Jump to content

Module: LazyCron (for ProcessWire 2.1)


ryan
 Share

Recommended Posts

ProcessWire LazyCron Module


This core module provides hooks that are automatically executed at various intervals. It is called 'lazy' because it's triggered by a pageview, so the interval is guaranteed to be at least the time requested (and maybe more) rather than exactly the time requested. The more pageviews your site gets, the closer it is. This is fine for most cases, but if you need it to be fully accurate I'll describe how you can make it not-lazy a little further down.

How to download and install


This was built as a core module for ProcessWire 2.1 (development version), so you need to grab the latest commit of the development version and you will have the module. This module is not compatible with PW 2.0 (stable version). ProcessWire 2.1 is at: https://github.com/ryancramerdesign/P21

If you already have the latest commit of ProcessWire 2.1, go to your modules menu, click "check for new modules" at the bottom, and then click the "install" button for the LazyCron module. LazyCron is now installed and ready to be used by other modules or via the API.

Hookable time intervals


These are the function names you can hook from LazyCron. The function names describe the time intervals they provide. If you think I'm missing any important time intervals, please let me know and I can add more.

  • every30Seconds
  • everyMinute
  • every2Minutes
  • every3Minutes
  • every4Minutes
  • every5Minutes
  • every10Minutes
  • every15Minutes
  • every30Minutes
  • every45Minutes
  • everyHour
  • every2Hours
  • every4Hours
  • every6Hours
  • every12Hours
  • everyDay
  • every2Days
  • every4Days
  • everyWeek
  • every2Weeks
  • every4Weeks

How to use it


This module is mainly of use inside the API and to other modules. You hook one of the named intervals mentioned in the list above, and the function you provide will be executed at approximately that time interval. Here's how you do it, both from a class (module) and outside of one:

Usage in a class/module

<?php

// initialize the hook in your AutoLoad module
public function init() {
   $this->addHook('LazyCron::every30Minutes', $this, 'myFunc'); 
}

// the function you want executed every 30 minutes
public function myFunc(HookEvent $e) { 
   echo "30 Minutes have passed!"; 
}

Procedural usage (like in a template or elsewhere in the API):

<?php

// create your hook function
function myHook(HookEvent $e) { 
   echo "30 Minutes have passed!"; 
}

// add a hook to your function: 
wire()->addHook('LazyCron::every30Minutes', null, 'myFunc'); 

Arguments provided to the hooks

If desired, you can retrieve the number of seconds that have actually elapsed since your hooked function was last called:

<?php

function myHook(HookEvent $e) { 
   $seconds = $e->arguments[0];
   echo "30 Minutes have passed! (actual seconds were: $seconds)"; 
}

Note that in production usage, you probably wouldn't want to echo anything from these hooks because they are executed after the pageview was already delivered. So while you can directly echo output from these, it's probably not that useful (other than for demonstration purposes, like this).

How it works


When installed, LazyCron hooks into ProcessWire's ProcessPageView::finished() method. This ensures that the scheduled tasks are executed after the pageview has already been delivered rather than before or during it. This hopefully avoids any perceived slowdown if the scheduled tasks take time.

LazyCron provides a bunch of hooks that anything else can hook into. These functions are outlined in the section above titled "Hookable time intervals." These functions are called at the interval specified in their name. LazyCron simply uses ProcessWire's existing hook system. So when you hook into any one of these functions, your hook will also be executed at that same time interval.

LazyCron hooks are only executed during pageviews that are delivered by ProcessWire. They are not executed when using ProcessWire's API from other scripts.

How to make it not-lazy


In most cases, the way that LazyCron works out of the box is just fine. But if your need requires assurance that the module will always execute at exactly the interval you need (rather than possibly later), you need to setup a real cron job to trigger a pageview in your site. So if you needed accuracy to 1 minute, you'd setup a cron job to execute every one minute, and pull a page from the site. There are any number of ways you could pull a page from your site, but here is one using wget:

wget --quiet --no-cache -O - http://www.your-site.com > /dev/null

That command basically says to pull a page from the site, don't tell us anything, don't cache the request, and discard any output.

  • Like 5
Link to comment
Share on other sites

Thanks... I've been wanting to build it for awhile, as the need has come up a few times in some of my projects too. Our messages from the other thread motivated me to go ahead and build it. Let me know how it works for you if you use it at some point in the future. For anything that requires significant time to process, regular cron is still the way to go, but this LazyCron should be good for the majority of smaller automated tasks.

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

Well PW 2.1 is very close to becoming the current stable version. I have a few details to take care of, but think it's just about there (perhaps by the end of the month). I'll keep the 2.0 branch going for bug fixes but probably won't be adding new features to it... this is already the case.

Link to comment
Share on other sites

  • 3 years later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...