Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let rulesets store information in established subscriptions #618

Open
b1conrad opened this issue Oct 20, 2022 · 3 comments
Open

Let rulesets store information in established subscriptions #618

b1conrad opened this issue Oct 20, 2022 · 3 comments
Assignees

Comments

@b1conrad
Copy link
Member

Proposing a rule that selects on a wrangler:new_key_value_pair event, with attributes: Id the established subscription identifier, key a key not reserved* for subscriptions, and value an optional value (a falsy value to mean remove the key).

The rule to raise a wrangler:key_value_updated event upon successful addition/deletion to/from the established subscription, with the original attributes.

The key-value pair is for the use of the pico that sets it.

For keys that begin either "Rx_" or "Tx_", it is considered good relationship practice to also send a similar event over the subscription to the other side, with the key prefix reversed. Care must be taken to avoid initiating an infinite loop.

*Reserved subscription keys are:

["Id","Rx_role","Tx_role","Rx","Tx","Tx_host"]
@b1conrad b1conrad self-assigned this Oct 20, 2022
@b1conrad
Copy link
Member Author

Playing with this candidate rule:

    select when wrangler new_key_value_pair
      Id re#(.+)#
      key re#(.+)#
      value re#(.*)#
      setting(Id,key,value)
    pre {
      buses = established()
      bad_key = ["Id","Rx_role","Tx_role","Rx","Tx","Tx_host"] >< key
      index = bad_key => -1 | indexOfId(buses, Id)
      ok = index >= 0
      add_kv = function(v,i){
        i==index => v.put(key,value || null) | v
      }
      new_established = ok => ent:established.map(add_kv)
                            | ent:established
    }
    if ok then noop()
    fired {
      ent:established := new_established
      raise wrangler event "key_value_pair_updated" attributes event:attrs
    }
  }

@b1conrad
Copy link
Member Author

Have had success with this rule, testing in localhost:3000:

  rule saveKeyValuePair {
    select when wrangler new_key_value_pair
      key re#(.+)# value re#(.*)# setting(key,value)
    pre {
      bus = findBus(established())
      invalid = bus.isnull() ||
        key.match(re#^(Id|Tx|Rx|Tx_role|Rx_role|wellKnown_Rx|Tx_host)$#)
      val = value.decode() || null
      already_seen = (bus.keys() >< key && bus{key} == value)
                  || (bus{key}.isnull() && val.isnull())
      ok = not invalid && not already_seen
      index   = ok => indexOfId(established(),bus{"Id"}) | -1
      new_bus = not ok =>        null
              | value =>         bus.put(key,value)
              |                  bus.delete(key)
      new_key = not ok =>              null
              | key.match(re#^Rx_#) => key.replace(re#^R#,"T")
              | key.match(re#^Tx_#) => key.replace(re#^T#,"R")
              |                        key
    }
    if ok && index >= 0 then
      event:send(
        {
          "eci":bus{"Tx"},"domain":"wrangler","type":"new_key_value_pair",
          "attrs":{
            "Id":bus{"Id"},
            "key":new_key,
            "value":new_bus{key}.defaultsTo("")
          }
        }
        , bus{"Tx_host"}
      )
    fired {
      ent:established := ent:established.splice(index,1,new_bus)
    }
  }

@b1conrad
Copy link
Member Author

Rather than modifying the io.picolabs.subscription ruleset, I think it is nearly as easy to have your ruleset "wrap" it and use the relationship Id to map to the desired auxiliary information. As an example of this, the initiating pico could select on the wrangler:outbound_pending_subscription_added event as in this wePropose rule, and the receiving pico could select on the wrangler:inbound_pending_subscription_added event, as in this theyPropose rule.

It would also be important to then clean up the layered-on map by selecting when these wrangler event types come in:

  • outbound_subscription_cancelled
  • outbound_pending_subscription_approved
  • inbound_subscription_cancelled
  • subscription_removed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant