Wrangler's io.picolabs.ds
ruleset provides a simple key-value datastore that multiple rulesets can use at once. It can be used as a data transfer layer between different rulesets.
Installing the Datastore
To install Wrangler's datastore simply install the io.picolabs.ds
ruleset in your pico. You can programmatically react to its installation by listening for wrangler:ds_ready events.
/* An example of a rule taken from io.picolabs.wrangler.profile that selects on the initialization of the datastore */ rule set_up_ds_entry { select when wrangler ds_ready or pre { givenInitialProfile = event:attr("initialProfile") initialProfile = givenInitialProfile && givenInitialProfile.typeof() == "Map" => givenInitialProfile | initialProfile() } always { raise wrangler event "ds_assign_map_to_domain" attributes { // wrangler:ds_assign_map_to_domain assigns the whole key-value mapping under a certain domain "domain":meta:rid, "map":initialProfile, "co_id":meta:rid } } }
Updating Data
Data in a data store can be updated through two different paths. The first is by giving a key-value pair for a domain by raising wrangler:ds_update and then responding to wrangler:ds_updated. The second is by changing all the key-value mappings under a domain raising wrangler:ds_assign_map_to_domain with a new key-value map and reacting to wrangler:ds_domain_updated. It is recommended to use the latter way of updating sparingly, such as for data migration purposes.
It is convention to use a ruleset ID as the domain to silo your data to your rulesets.
/* An example of a rule that increments a counter value in the datastore */ rule incrementDS { select when test incrementDS pre { currentCounter = datastore:getItem(meta:rid, "counter")o.picolabs.wrangler.profile that selects on the initialization of the datastore newValue = currentCounter.isnull() => 0 | currentCounter + 1 } always { raise wrangler event "ds_update" attributes { "domain":meta:rid, // The domain of the key-value pairings you want to manipulate "key":"counter", // The key of the value you want to change "value":newValue // The new value for the store } } } /* This rule reacts to wrangler:ds_updated to ensure that the counter we are incrementing above is always even by checking if the new value in the store is divisible by 2 */ rule makeCounterEven { select when wrangler ds_updated pre { domain = event:attr("domain") key = event:attr("key") value = event:attr("value") } if domain == meta:rid && key == "counter" && value % 2 == 1 then noop() fired { raise wrangler event "ds_update" attributes event:attrs.put("value", value + 1) } }