Many of you are probably already familiar with the unix cron program. For those that aren't, cron is a daemon process that allows users to execute commands or scripts automatically at user-configurable dates and times. The important part as far as OSCache is concerned is the cron expression syntax that allows users to dictate when commands should be executed - you can now use the same syntax to expire content in OSCache! A cron expression is a simple text string that specifies particular dates and/or times that are matched against.
OSCache uses cron expressions in a manner that might seem 'backwards' to what you might initially expect. When using a cron expression to test if a cache entry is stale, OSCache finds the date and time (prior to the current time) that most recently matches the supplied expression. This date/time is used as the expiry time - entries that were placed in the cache prior to this expiry time are considered stale and result in a NeedsRefreshException being thrown.
As an example, suppose you specify a cron expiry that matches every hour, on the hour ("0 * * * *"). If the current time is 10:42pm, then any content that was placed in the cache prior to 10:00pm would be considered stale.
The difference between the refresh period and a cron expression is that the refresh period specifies the maximum allowable age of a cache entry, whilst a cron expression specifies specific expiry times, regardless of how old an entry is. Eg imagine caching an object at 10:29am. With a refresh period of 30 minutes that entry would expire at 10:59am. With a cron expression of "0,30 * * * *" that entry would expire at 10:30am.
A cron expression consists of the following 5 fields:
If you don't want to specify a value for a particular field (ie you want the cron expression to match all values for that field), just use a * character for the field value.
As an example, an expression that expired content at 11:45pm each day during April would look like this: "45 23 * April *".
OSCache also allows you to optionally specify lists, ranges and intervals (or even a combination of all three) within each field:
"10/20 * * * *" is equivalent to "10,30,50 * * * *",
while "10-45/20 * * * *" would only match 10 and 30 minutes past the hour, since 50 is outside the specified range.
Supplying '*' as the left-hand value of an interval will match the same values as if you had specified a range over all possible values.
Eg "*/10 * * * *" matches minutes 0,10,20,30,40 and 50.
To have a look at further examples of both valid and invalid syntax, it is suggested you take a look at the JUnit test cases in the com.opensymphony.oscache.util.TestFastCronParser class. This class is located under the src/core/test directory. For examples of how to specify cron expiry times using the taglibs.