Bundles or helper programs

Commenting on my previous posting my friend Peter asked me why I suggested using helper programs instead of bundles.

I've come to think that bundles (dynamically loaded modules in Mac OS X) should be used with care. I'm not saying you shouldn't ever use bundles. You should, but only if you have a good reason to do so.

Using external programs instead of loading bundles or modules dynamically gives a few advantages:

  • Separate namespace.
  • Easy testing.
  • A bug in the plug-in won't crash the invoker.
  • Plug-in need not worry about thread safety in the invoker.
  • Not worrying about thread safety means less and easier code.
  • Automatic true multi threading as the plug-in runs in a separate process. The OS will handle it they way it seems fit. The invoker can call the plug-in from a separate thread if it doesn't want to wait for it (in a Cocoa application for example, where the main thread handles the UI). The plug-in doesn't care.

Some things cannot be externalized this way. In these case dynamically loadable bundles are a great thing. But if you don't need'em, consider using helper programs instead.

iCal program interface

It would be really cool if iCal was to provide a configurable program invocation interface. What I'm looking for is a way for the user to specify programs to be run by iCal when its about to display a new range of dates (day, week or month view). It's a very dynamic and safe plug-in architecture.

iCal would dictate a command line API that the programs would have to follow in order to work as a plug-in. For example:

  • iCal will start program with command line parameters as specified by the user (in preferences).
  • iCal will write (in an unambiguous and easy to parse format) the time period to be displayed to program's file descriptor 3.
  • iCal expects program to write iCalendar data to its standard output.
  • iCal expects program to exit 0 if program did not encounter any problems.
  • iCal expects program to exit <some other code> for temporary errors and <yet another code> for permanent errors.

What would the benefits be with such an architecture?

Many types of calendar information could easily be calculated by a small program. This includes for example:

  • Data that is dynamic to its nature, for example easter and the holidays based on it.
  • Data that is repetitive, for example annual holidays, birthdays etc.
  • Data stored in a legacy database.
  • Combinations of the above and more variants that I haven't thought of.

These small programs could of course be invoked manually and its output redirected to files, files which could then be opened in iCal. But, letting iCal invoke these programs itself, in a clearly documented and standardized manner, would save a lot of disk space. I always want to know about easter, but I don't want a huge file containing all easters from now to eternity.

One argument against using such programs would be the overhead of invoking the program, wait for it to finish and then parse its output. This could be solved by introducing simple caching algorithms, perhaps announced by the program itself, perhaps configurable by the user.

Some programs will generate output that for a given period of time won't change once its been calculated. Such a program need only be executed once for each period of time that the user wants to look at during a session; Some programs generate more dynamic data and might need to be consulted more often.

I think this is a cool idea! I'll submit it as an iCal Enhancement Request.