Managing Subscriptions
- 1 Introduction to Subscriptions
- 1.1 Well Known Rx
- 1.1.1 Another pico
- 1.1.2 Same pico
- 1.1 Well Known Rx
- 2 Creating a Subscription
- 3 Deleting a Subscription
- 4 Sending Messages Between Subscribers
- 4.1 Manually Sending Messages
- 4.2 Using an API Call
- 4.2.1 not yet tested
- 5 Subscription Attributes
- 6 Types of Subscriptions
- 7 Understanding the Protocol
- 7.1 Subscription Event Flow
- 7.1.1 Internal API
- 7.1.2 Subscription Creation
- 7.1.3 Subscription Deletion
- 7.1 Subscription Event Flow
Introduction to Subscriptions
To understand how subscriptions between picos work, it is important to understand what a pico channel is and what channel policies are. Inter-pico Subscriptions use pico channels to implement the subscription protocol itself (which is independent of picos).
Subscriptions allow two picos to communicate with each other, enabling the creation of peer-to-peer structures. From each pico's perspective there is a receiving channel, Rx
, and a transmitting channel, Tx
. Each pico receives events and queries from the other pico through the Rx channel and makes queries and sends events to the other pico using the Tx channel. However, it is important to note that there are only two pico channels, just a different perspective. For example, Pico A records a Tx channel and an Rx channel, but the Tx channel that pico A has recorded is actually Pico B's Rx channel and vice versa.
Subscriptions can occur between any two picos as long as the picos have a way to communicate (over HTTP or on the same engine). For example, in the Forever application, the picos belonged to different people and represented their personal contact information. The io.picolabs.subscription
ruleset is what implements subscriptions, so both picos need to have it installed.
Subscriptions are established by pico A sending a request to establish a subscription to pico B, and pico B then accepting that request.
Well Known Rx
When the io.picolabs.subscription
ruleset is installed on a pico (it is preinstalled on every pico created by Wrangler), it creates a pico channel known as the "wellKnown_Rx" channel. This channel is what receives requests to create subscriptions. The channel has a policy that only allows events related to accepting a subscription. This allows the ECI of this "wellKnown" channel to be shared publicly with anyone without fear that someone will send events that mess with the pico or send queries for information they are not allowed to have.
Although any channel which does not block the subscription events will work when creating subscriptions, it is considered good practice to use the wellKnown_Rx channel unless the subscription is between a parent and child pico. Even then, you should use the family channel to obtain the other pico’s wellKnown channel and then use its ECI to create your subscription.
A wellKnown_Rx can be accessed by querying the wellKnown_Rx()
function, shared by the io.picolabs.subscription
ruleset. It returns the channel, a Map (with keys: “id”, “tags”, “eventPolicy”, and “queryPolicy”). Of these, you will be interested only in the value of the "id"
key, the ECI.
How to obtain a pico's wellKnown channel and its ECI? Once you have a channel, say chan
, you get its ECI with chan{"id"}
. How you get the channel itself depends on whether you are looking for the well known channel of the same pico, or a different pico.
Another pico
When you are sure that it is a different pico (i.e., not the one running your ruleset), you would use the wrangler:picoQuery()
function (documented on the "Accessing a Function Shared by Another Pico" page). For example, code like this will get the ECI of the well known channel of your parent pico:
wellKnown_ECI = wrangler:picoQuery(wrangler:parent_eci(),"io.picolabs.subscription","wellKnown_Rx"){"id"}
Notice that the picoQuery
returns the channel as a Map, so you must extract its ECI using the "id"
key. Reminder that wrangler:parent_eci()
function gives you the family channel ECI for your parent.
And this is how you might get an Array of well known ECIs for all of your child picos:
wrangler:children() // an Array of Maps, each with keys: "eci", "name", and "parent_eci"
.map(function(c){
wellKnown_Rx = wrangler:picoQuery(c{"eci"},"io.picolabs.subscription","wellKnown_Rx") // the channel
c.put("wellKnown_ECI",wellKnown_Rx{"id"}) // adding a key "wellKnown_ECI" to the map for each child pico
}) // an Array of Maps, each with keys: "eci", "name", "parent_eci", and "wellKnown_ECI"
Reminder that the wrangler:children()
function gives you the family channel ECI for each of your child picos.
Same pico
Since you can’t use the wrangler:picoQuery()
function to call a function in another ruleset of the same pico, you’ll need to use a different technique. The easiest way it to look up the channel by its tags, and then extract the ECI (using the key "id"
):
wrangler:channels(["wellKnown_Rx","Tx_Rx"]) // an Array of all your channels with those tags
.head() // the first channel with those tags (and usually the only one)
{"id"} // this pico's well known ECI for subscription requests
or, without the comments:
As a reminder, a channel contains three pieces of information: the Event Channel Identifier (ECI), tags, and policies. The well known channel tags are wellKnown_Rx with Tx_Rx. This channel is used to establish new subscriptions between picos, and is meant to be publicly shared with potential subscribers.