def add_tracker(wfid, action, tracker_id, conditions, msg)

      tracker_id ||= [
        'tracker', wfid, action,
        Ruote.generate_subid(conditions.hash.to_s + msg.hash.to_s)
      ].collect(&:to_s).join('_')

      conditions =
        conditions && conditions.remap { |(k, v), h| h[k] = Array(v) }

      doc = @context.storage.get_trackers

      doc['trackers'][tracker_id] =
        { 'wfid' => wfid,
          'action' => action,
          'id' => tracker_id,
          'conditions' => conditions,
          'msg' => msg }

      r = @context.storage.put(doc)

      add_tracker(wfid, action, tracker_id, conditions, msg) if r
        # the put failed, have to redo the work

      tracker_id
    end
def add_tracker(wfid, action, tracker_id, conditions, msg)

      tracker_id ||= [
        'tracker', wfid, action,
        Ruote.generate_subid(conditions.hash.to_s + msg.hash.to_s)
      ].collect(&:to_s).join('_')

      conditions =
        conditions && conditions.remap { |(k, v), h| h[k] = Array(v) }

      doc = @context.storage.get_trackers

      doc['trackers'][tracker_id] =
        { 'wfid' => wfid,
          'action' => action,
          'id' => tracker_id,
          'conditions' => conditions,
          'msg' => msg }

      r = @context.storage.put(doc)

      add_tracker(wfid, action, tracker_id, conditions, msg) if r
        # the put failed, have to redo the work

      tracker_id
    end
Adds a tracker (usually when a 'listen' expression gets applied).

 The tracker_id may be nil (one will then get generated).

 Returns the tracker_id.