[OPEN-ILS-DEV] From the archives: more on passive hooks

Mike Rylander mrylander at gmail.com
Wed Mar 24 20:52:12 EDT 2010


What follows is from circa Jan 2009 (lightly edited to reflect current
reality), and is an attempt to explain the difference between active
and passive hooks.  Let me know if it helps or confuses, eh?

---------------------------------------------------

There are two scheduling points for events: actively before (or at) the
triggering time; and passively after the triggering time.  The first is
exemplified by a checkout, where the xact_start field records the time of the
triggering event, and is accompanied by an action -- the creation of the circ
record at item circulation time.  The second is something who's time is
recorded, but the event that occurs at that recorded time may or may not
actually come to pass, for instance a circ becoming overdue.  This is
recorded in the due_date field, but for 90% or more circs, this event
(overdue-ness) won't come to pass.

This distinction is generally described by the passive field on
action_trigger.hook.  To put the above another way, if an event is known to
have happened (or be happening now) and an event entry should be set up for
its passing (circ is created, hold captured, etc) then the hook should have a
false passive flag.  If an event might happen in the future, but either not
for some time or probably not at all, but the event's future potential time
is known (circ due date) or will be known (stop fines time), then the hook
should have a true passive flag.

So, what does that really mean, in practical terms?  Well, using the
circ-begin and circ-overdue as the canonical examples, it means that we can
treat the delay and delay_field columns of event_definition differently for
passive=true and passive=false hooks, and that we can create a generic event
generator for both active-hook (passive=false) and passive-hook event
definitions.

For the active-hook case, the code creating or updating the object will call a
method in the trigger app, passing the hook it uses, the core object
involved, and the triggering location (org id):

# request open-ils.trigger open-ils.trigger.inject_event_at_hook 'checkout',
1234 /* the target (in this case circ) id */, 10 /* the org id */

We discussed this today ... the event injection code will find the correct
event definitions based on the context org and the hook key and create one or
more events targeting the id passed.  Each event definition has the option of
offsetting the run_time for the specific event based on the amount of time
specified in its delay field into the future based on the field on the core
object named in its delay_field (or now(), if the definition supplies no
delay_field).  Then the processor comes along and does its thing.

However, passive events are different.  The delay and delay_field can be seen
as an event entry creation delay, instead of a run_time delay.  There could
be a generic passive event generator that does the following:

1) collect all passive hooks
2) collect all active (the active flag on event_definition, not non-passive
hook) event definitions for those hooks
3) look for objects of type hook.core_type where the column named in
delay_field is /at least/ older than the age (interval) specified in the
delay column (def.hook.core_type = circ, def.delay_field = due_date,
def.delay = 7 days) but not older than max_delay_age, and meet other
specified criteria (supplied the filter JSON file) and create events for them

Later, possible much later if the granularity (in trunk, and I don't
recall the label) field is in use for this definition, the events are
grouped (if group_field is used) and fired.

One other major difference is that, for passive hooks, only one event
per definition+target will ever be run, regardless of the final state
of the event.  For active hooks, if the target, for whatever reason,
is found for a definition, the event will be created -- even if that
same definition was used for that target in the past.

When might that happen?  Consider an active hook called hold.captured
which is asynchronously triggered whenever a hold is captured.  If a
hold is captured, an event created (possibly delayed, but that's
immaterial), but then the item is found to be damaged so the hold gets
retargeted, we're going to need to create events for the the
hold.captured hooked definitions when the next item is captured.

----------------------------------------------------------------------

I hope that helps!

-- 
Mike Rylander
 | VP, Research and Design
 | Equinox Software, Inc. / The Evergreen Experts
 | phone:  1-877-OPEN-ILS (673-6457)
 | email:  miker at esilibrary.com
 | web:  http://www.esilibrary.com


More information about the Open-ils-dev mailing list