Daniel Becker Bighelini

SPEL API: BOP TRIGGERS

Blog Post created by Daniel Becker Bighelini on Jun 13, 2016

BOP TRIGGERS

 

Table of Contents

 

  1. I. Introduction......................................2
  2. II. MAJIC Overview...................................3
  3. III. Event Triggers Details..........................4

    A. NEW_INIT......................................4

    B. DB_INIT.......................................5

    C. PRE_VALIDATE..................................6

    D. POST_VALIDATE.................................7

    E. POST_CI.......................................8

    F. ON_PRE_VAL....................................9

    G. ON_POST_VAL_ASYNC.............................10

    H. ON_POST_VAL...................................11

 

 
 

 

 

                                               Page 2

  1. I. Introduction

 

Trigger happen at specific times in the life cycle of an object, such as,

creation or the changing of a value.  Theses specific times are called

event triggers.  There are eight defined event triggers.  These are:

 

       NEW_INIT               Chance to do complex initial default on a

                        new Dob

       DB_INIT                Last chance init after loading values from DB

 

       PRE_VALIDATE           Chance to modify values prior to a

                        validate/checkin

       POST_VALIDATE          Make sure the Dob is valid prior to a save

       POST_CI                Notify that some values have changed

 

       ON_PRE_VAL             Chance to trap and possibly abort a user change

                        of an attribute

       ON_POST_VAL            Serial notification of a change to an attribute

       ON_POST_VAL_ASYNC      Notify of a change being made to an attribute

 

Multiple triggers can be defined to execute at a specific moment.  The order

of execution of these multiple triggers is determined by an ordinal value

associated with each trigger.  A trigger with an ordinal value of 1 is

executed prior to a trigger with an ordinal value of 2 and so on.  The order

of execution of triggers with the same ordinal value is not guaranteed to

occur in any specific order such as first defined is first executed.  If you

need to guarantee order than use different ordinal values.

 

Since there can be multiple triggers defined to execute at a particular

moment each trigger can define whether execution of the triggers will continue

or abort.  There are two points at which the determination to continue or

to abort are made.  One is the trigger fails for some reason.  The other is

the trigger failed to complete within a specified time, that is, a timeout

  • occurs.

 

The arguments passed to a trigger are sometimes confusing.  We have

attempted to use the same pattern of arguments for all of the dob triggers,

and another pattern for the attribute triggers. If you get confused as to

what arguments are being passed, do a bop_logging and examine the

  1. arguments.  If you do this you will note three additional arguments at the

beginning of the trigger message.  These are internal arguments which

provide context to the interpretor and they should be disreguarded.

 

The first three arguments (which should be ignored) are:

    string template_name

    string trigger_name

    Object_Ref obj_ref  // The 'this' pointer

 

 

One thing to watch out for.  You need to be careful reguarding

unanticipated recursion.  For example if you had an object with two

attributes, fred and wilma.  If fred has an 'ON_PRE_VAL" that does a

set_val on wilma, and wilma has an 'ON_PRE_VAL' that does a set_val on

fred, you will be hosed.

 

 
 

 

 

                                               Page 3

  1. II. MAJIC Overview

 

The overview of the MAJIC syntax for an event trigger is:

    event name                NEW_INIT, DB_INIT, PRE_VALIDATE, POST_VALIDATE,

                        POST_CI, ON_PRE_VAL, ON_POST_VAL_ASYNC, or

                        ON_POST_VAL

 

    location information      This is either a remote trigger which requires:

                            trigger's node name

                            trigger's process name

                            trigger's object name

                            trigger's name

                        in the format:

                            method@node|process|object[ refcount ]

                        where refcount is either

                            0

                            1

                        or it is an local trigger which is specified by

                        the spell method name alone.

 

    trigger arguments         This is a list of the names of attributes to

                        be passed to the trigger.  A keyword value of

                        CHANGED_ONLY can be inserted into the attribute

                        list to indicate that attributes following

                        CHANGED_ONLY should be passed to the trigger

                        only if their old and new values are different.

 

    ordinal             This is a numeric value specifying the trigger's

                        execution order.

 

    timeout information       This specifies if triggers are to continue

                        processing or to abort and how long to wait

                        for a trigger to complete.

 

    condition                 This is a filter on whether to execute a

                        trigger.  If it evaluates to TRUE the trigger

                        is executed.  This only applies to trigger on

                        a dob not on an attribute.

 

 

 
 

 

 

 

                                               Page 4

  1. III. Event Triggers Details

 

  1. A. NEW_INIT

    This is executed prior to the creation (as opposed to instantiation) of

    an object. It is here that one can do complex initial default

    calculations for a new object.  This is a serial trigger.  Execution

    will not proceed until the trigger returns.

 

    The function you define for the trigger is called with an array of

    triplets which correspond to the attributes you defined in majic.  Each

    element of the triplet consists of the attribute name, the 'old' value,

    and the 'new' value.  Old is the 'original' and new is the 'changed'. 

 

    For the reply, you provide the attributes you want to set, and what the

    value to set should be.  An error return is not supported.  Do not attempt

    to change the attributes using a 'this' pointer;

 

    Arguments:

      (string attr_name, value old_val, value new_val) []

 

    Reply:

      (string attr_name, value change_val)[]

 

    Note:

      There is NO context here.  Do not attempt to access the dob.  It does

      not exist.

      Ignore the 'new_val' in the input arguments.

 

 
 

 

 

                                               Page 5

  1. B. DB_INIT

    This is executed prior to instantiation.  At this point the backstore

    has been asked for data, and you have a chance to add any attribute

    values you wish.  This is the last chance for initialization after

    reading values from the database.  This is a serial trigger.  Execution

    will not proceed until the trigger returns.

 

    The function you define for the trigger is called with an array of

    triplets which correspond to the attributes you defined in majic.  Each

    element of the triplet consists of the attribute name, the 'old' value,

    and the 'new' value.  Old is the 'original' and new is the 'changed'. 

 

      For the reply, use set_return_data() to indicate the number of name-value pairs

      you are returning, followed by the name-value pairs themselves.  The name is the

      attribute name to modify.  For example, a DB_INIT trigger that modifies a Request's

      summary and description attributes:

            set_return_data(2);                // Expect two name-value pairs

            set_return_data("summary");  

            set_return_data("My new summary");

            set_return_data("description");

            set_return_data("My new desc");

 

      Be sure the data type for the value is set or cast correctly,

      i.e. "set_return_data( (int) some_local_variable)".

 

      If your trigger doesn't set any attributes, be sure "set_return_data(0)" is executed,

      presumably to indicate no data is expected.

 

      An error return is not supported.  Do not attempt to change the attributes using a

       'this' pointer.

 

 

    Arguments:

      (string attr_name, value old_val, value new_val) []

 

    Reply:

      (string attr_name, value change_val)[]

 

    Note:

      There is NO context here.  Do not attempt to access the dob.  It does

      not exist.

      Ignore the 'new_val' in the input arguments.

 

      (An aside: it seems DB_INIT triggers are fired twice when the object is fetched

      for viewing.  They are fired again when the object is checked out modified - perhaps

      because it is a new object, albeit a copy --RKM)

 
 

 

 

                                               Page 6

  1. C. PRE_VALIDATE

    This is executed prior to a validate/checkin.  It is here that one can

    modify the values prior to a checkin.  This is a serial trigger. Execution

    will not proceed until the trigger returns.

 

    The function you define for the trigger is called with an array of

    triplets which correspond to the attributes you defined in majic.  Each

    element of the triplet consists of the attribute name, the 'old' value,

    and the 'new' value.  Old is the 'original' and new is the 'changed'.

 

    From your function you can typically do two things.  Either simply

    return an error code saying that the validation check has failed, or

    you can modify attributes using the 'this' pointer.

 

    Arguments:

      (string attr_name, value old_val, value new_val) []

 

    Error Reply:

      Set error_code != 0, put a string error_text in msg[0]

 

    Success Reply:

      Set error_code == 0

 

 

    Notes/Side Effects:

      You are in the exclusive session of the group leader doing the

      checkin (CI) when you get this call.  We make a Dob just for your use

      on this function.  Do not attempt to save the 'this' pointer.

 

 
 

 

 

                                               Page 7

  1. D. POST_VALIDATE

    This is executed after the validate pass, and prior to the saving of

    the changes.  It is here that one can do additional modifications of

    attributes before it is written to the database.  This is a serial

    trigger. Execution will not proceed until the trigger returns.

 

    The function you define for the trigger is called with an array of

    triplets which correspond to the attributes you defined in majic.  Each

    element of the triplet consists of the attribute name, the 'old' value,

    and the 'new' value.  Old is the 'original' and new is the 'changed'.

 

    From your function you can typically do two things.  Either simply

    return an error code saying that the validation check has failed, or

    you can modify attributes using the 'this' pointer.

 

    Arguments:

      (string attr_name, value old_val, value new_val) []

 

    Error Reply:

      Set error_code != 0, put a string error_text in msg[0]

 

    Success Reply:

      Set error_code == 0

 

    Notes/Side Effects:

      You are in the exclusive session of the group leader doing the

      checkin (CI) when you get this call.  We make a Dob just for your use

      on this function.  Do not attempt to save the 'this' pointer.

 
 

 

 

                                               Page 8

  1. E. POST_CI

    This is executed to notify a change of value.  This is an asynchronous

trigger.  You do not reply.

 

    The function you define for the trigger is called with an array of

    triplets which correspond to the attributes you defined in majic.  Each

    element of the triplet consists of the attribute name, the 'old' value,

    and the 'new' value.  Old is the 'original' and new is the 'changed'.

 

    You can do virtually nothing from this function except fire off

    notifications, set events, etc.

 

    Arguments:

      (string attr_name, value old_val, value new_val) []

 

    No Reply's:

 

    Notes/Side Effects:

        This is an asynchronous only call.  There is NO 'this' pointer, and

        you do not get a change to respond in any way.

 

 
 

 

 

                                               Page 9

  1. F. ON_PRE_VAL

    This is executed during a set on an attribute.  This function is

    intended to allow you to check that what is entered is valid.  It also

    gives you a way to coerce the value being set to some other value

    without calling the validate triggers.

 

    The function you define for the trigger is called with a bunch of stuff

    for the attribute, then the standard array of attribute triblets you

    passed in as part of the majic definition.

 

    You will typically either fail the change, causing an error, or you can

    coerce the value to some other value and continue.  If we did not

    coerce the value, we would do another ON_PRE_VAL and things get nasty

    quickly.

 

    Arguments:

      attr_name         attribute name for attribute being set

      attr_val.orig       original attribute value (could be in the db)

      attr_val.last       attribute value prior to set

      attr_val.new        value passed with set_attr message

      set_val_smag        smag value from the set_attr message

      group_leader        object reference for a group leader or NIL

      (string attr_name, value old_val, value new_val) []

 

 

    Error Reply:

      Set error_code != 0, put a string error_text in msg[0]

 

    Success Reply:

      Set error_code == 0

 

    Success Reply - and coerce the set_val to a new value:

      Set error_code == 0;

      set msg[0] to the new value

 

 
 

 

 

                                                Page 10

  1. H. ON_POST_VAL

    This is executed to notify of a change to an attribute, IE it has

    passed all validation steps.  This is a serial trigger.  Execution will

    not proceed until the trigger returns.

 

    The function you define for the trigger is called with a bunch of stuff

    for the attribute, then the standard array of attribute triblets you

    passed in as part of the majic definition.

 

    What you do here is to perhaps set other attributes based on the value

    just set, etc using the 'this' pointer..

 

    Arguments:

      attr_name         attribute name for attribute being set

      attr_val.orig       original attribute value (could be in the db)

      attr_val.last       attribute value prior to set

      attr_val.new        value passed with set_attr message

      set_val_smag        smag value from the set_attr message

      group_leader        object reference for a group leader or NIL

      (string attr_name, value old_val, value new_val) []

 

 

    Error Reply:

      No error reply is possible.

 

    Success Reply:

      Set error_code == 0

 

    Notes/Side Effects:

      A Dob reference is passed in the synchronous case.  No return errors

      possible.

 

 
 

 

                                               Page 11

  1. G. ON_POST_VAL_ASYNC

    This is executed to notify of a change to an attribute, IE it has

    passed all validation steps.  This is an async trigger.  Execution will

    proceed immediately and will not wait for a reply.

 

    The function you define for the trigger is called with a bunch of stuff

    for the attribute, then the standard array of attribute triblets you

    passed in as part of the majic definition.

 

    What you do here is to perhaps set other attributes based on the value

    just set, etc using the 'this' pointer..

 

    Arguments:

      attr_name         attribute name for attribute being set

      attr_val.orig       original attribute value (could be in the db)

      attr_val.last       attribute value prior to set

      attr_val.new        value passed with set_attr message

      set_val_smag        smag value from the set_attr message

      group_leader        object reference for a group leader or NIL

      (string attr_name, value old_val, value new_val) []

 

 

    Reply:

      None supported.

 

    Notes/Side Effects:

      There is no Dob reference passed.

 

 

Outcomes