Once upon a time, while examining log files and watching updatedb and makewhatis run, I came to the conclusion that I needed a better scheduling system than is provided by cron. My primary need was for a utility/daemon that scheduled system administration procedures as often as necessary and not, for example, once a week at a specific time. I don't change my software often enough to justify frequent execution of makewhatis. Then again, maybe I do or maybe I will. I wanted something flexible enough to meet the changing needs of my system.

Identifying the need, I then began work on a solution. It quickly became obvious that I could and should create a program that not only scheduled execution of other programs as often as necessary, but could be easily extended to other criteria (even replacing cron and at). That was the real birth of AgentD. I decided to do the program in Objective-C, which I had just started learning at the time.



When started, AgentD begins by parsing its command line messages. The command line message parser is a work in progress that allows Objective-C program objects to receive messages that are given by the user at execution. Think of it as a language-supported getopt(). What it does is save me the effort of having to associate external options with internal ones. For example, a likely way to execute AgentD is agentd configFile: /etc/agents. Look in AgentD.h for some of the valid messages AgentD responds to. Multiple messages can be given at the same time.

The main startup activity is reading in and parsing the config file. There is no default config file, so one must be given on the command line for AgentD to do anything useful. As a system-level daemon, the main config file would probably be /etc/agents; as a user-level daemon, ~/.agents is a reasonable choice. The entries are verified as much as possible and the valid Agent entries are created and scheduled for execution. It sleeps until the first Agent is scheduled to run, executes it, and then re-schedules it when it's finished. Currently, this continues until the Agent queue is empty, possibly forever.

Config File

The config file is very simple, mostly because its parsing is primarily handled externally by the given Agent type. It goes:

[<Agent type> <options>] <Agent>

echo AgentD is up and ready for testing.
every 60       atrun
AOAN	/usr/local/bin/ftp-agent /var/spool/ftp/get.list
Cron 0 * * * *       cat /usr/local/lib/sounds/hourly.chime > /dev/audio

Blank lines and lines beginning with a # are ignored. Giving just an agent runs it once (after initial parse). The default is to attempt to create an Agent from an entry. If that fails, the entry is assumed to be an agent.

Agent Types/Modules

AgentD is powerful because it doesn't need to know the details of the Agent types it is scheduling and executing. What happens in parsing the config file is that the Agent type is read, and the rest of the line is passed on to that module (assuming it exists). It is then up to the module to parse its particular options, after which it returns the rest of the line (the raw Agent or, with type chaining, further Agent entries). The created Agent object (which encapsulates all those things) is used to schedule execution. For information on programming modules, look here.

The following modules already exist:

Cron crontime
A horribly simplified version written for testing purposes only. It only handles * and single integer entries. I hope someone (perhaps the author of a normal cron daemon) will make a proper cron module. Being a drop-in replacement for cron is the beta goal.
Adjusts scheduling to run only As Often As Necessary. Currently, this is handled with a simple halving/doubling of a sleep interval based on failed/successful executions (Note that not all raw Agents report success for the activity they were run for. For example, find will return success so long as it had no errors, even if it didn't find any of the files specified. If you use programs like that, you will need to use a wrapper to give better than Level 0 status). It's a far cry from intelligent, but it works for now. Improvemnts on the algorithm are underway, and comments are appreciated.

About the Author

AgentD was written by some geek named Darrin "Doc" O'Leary. Credit is due to the giants upon which shoulders he stands, nameless here forever more. I, uh, the author has attempted to make his software as clean and portable as possible, conforming to ANSI C before POSIX (before anything else) in C and the GnuStep Foundation classes in ObjC. In fact, he would be very interested in knowing if his software works under NeXTSTEP or with any non-GNU Foundation library. Suggestions and bug reports are also welcome via email

To Do