I'd like to propose some changes/improvements to the cron system.What is cronCron
is a utility that periodically runs pre-defined tasks at pre-defined intervals.Status quo
phpBB 3.0 has a cron-like system to run maintenance tasks such as garbage collection for sessions, db cache, search index, permissions. There is also message queue (email) processing, pruning of warnings and topics.
The way it is implemented is by outputting a transparent 1x1 pixel gif in the board footer, while doing the work in the background. If possible it uses register_shutdown_function to handle the tasks after the image was rendered. This allows any board user to trigger the execution of the script.
The way it is implemented is not very extensible. The possible tasks are hard-coded into the cron.php file and the page_footer() function from includes/functions.php. This makes it hard to add new tasks or to run those tasks by other means.Proposal
There are several use-cases for a modular cron system. First of all, the ability to add new tasks. If a MOD author (or other person) wants to extend phpBB, there are cases which require running tasks periodically. For example a feed aggregator that posts an RSS/Atom feed to a specified forum.
Also from a task caller perspective this has benefits. A large board may want to switch to a real server-side cron instead of the current client-side pseudo cron implementation. Currently this is not easily possible, because phpBB's files are not particularly CLI-friendly.
Speaking of which, many frameworks provide cli tools to aid development. ameeck has been working
on such a tool for phpBB. It might be useful for a developer (mod author) to be able to run cron tasks explicitly from the command line. CLI and cron tasks could use a common or easily combinable interface, to make this a breeze.Implementation suggestions
Most of cron.php and the cron parts of page_footer need to be factored out into a separate class. There needs to be an interface for tasks and implementations of the current existing tasks. There needs to be a naming convention for tasks to allow automatically loading them.
Because checking whether a cron task needs to be run may result in some overhead (loading all the task classes, running the checks) it may be worthwhile to only do it every n pageloads or so.
Ideally a task would get its dependencies injected, decoupling it completely from any global state. Possible dependencies include cache, db, paths, config. Doing so would allow a reduced bootstrapping, which is good for performance and non-web environments such as CLI. Not sure what's the best way to implement this, though. The task could have a method returning a list of its dependencies, the caller would have a mapping for those strings and inject the instance. Or perhaps some kind of annotations (reading docblocks with reflection
) would be plausible.
Here's an (attempted) UML diagram of how this could look, using the command pattern.
Of course it would need to be adjusted to phpBB3 naming conventions. Note that the shouldRun() method is static.