afb-apiset: Fix start of apis
[src/app-framework-binder.git] / old-docs / afb-events-guide.md
1 Guide for developing with events
2 ================================
3
4 Signaling agents are services that send events to any clients that
5 subscribed for receiving it. The sent events carry any data.
6
7 To have a good understanding of how to write a signaling agent, the
8 actions of subscribing, unsubscribing, producing, sending and receiving
9 events must be described and explained.
10
11 Overview of events
12 ------------------
13
14 The basis of a signaling agent is shown in the following figure:
15
16 ![scenario of using events](pictures/signaling-basis.svg)
17
18 This figure shows the main role of the signaling framework for the events
19 propagation.
20
21 For people not familiar with the framework, a signaling agent and
22 a “binding” are similar.
23
24 ### Subscribing and unsubscribing
25
26 Subscribing is the action that makes a client able to receive data from a
27 signaling agent. Subscription must create resources for generating the data, and
28 for delivering the data to the client. These two aspects are not handled by the
29 same piece of software. Generating the data is the responsibility of the
30 developer of the signaling agent while delivering the data is handled by the
31 framework.
32
33 When a client subscribes for data, the agent must:
34
35 1.  check that the subscription request is correct;
36 2.  establish the computation chain of the required data, if not already
37     done;
38 3.  create a named event for the computed data, if not already done;
39 4.  ask the framework to establish the subscription to the event for the
40     request;
41 5.  optionally give indications about the event in the reply to
42     the client.
43
44 The first two steps are not involving the framework. They are linked to
45 the business logic of the binding. The request can be any description of
46 the requested data and the computing stream can be of any nature, this
47 is specific to the binding.
48
49 As said before, the framework uses and integrates **libsystemd** and its event
50 loop. Within the framework, **libsystemd** is the standard API/library for
51 bindings expecting to setup and handle I/O, timer or signal events.
52
53 Steps 3 and 4 are bound to the framework.
54
55 The agent must create an object for handling the propagation of produced
56 data to its clients. That object is called “event” in the framework. An
57 event has a name that allows clients to distinguish it from other
58 events.
59
60 Events are created using the ***afb\_daemon\_make\_event*** function
61 that takes the name of the event. Example:
62
63 ```C
64         event = afb_daemon_make_event(afb_daemon, name);
65 ```
66
67 Once created, the event can be used either to push data to its
68 subscribers or to broadcast data to any listener.
69
70 The event must be used to establish the subscription for the requesting
71 client. This is done using the ***afb\_req\_subscribe*** function
72 that takes the current request object and event and associates them
73 together. Example:
74
75 ```C
76         rc = afb_req_subscribe(afb_req, event);
77 ```
78
79 When successful, this function make the connection between the event and
80 the client that emitted the request. The client becomes a subscriber of
81 the event until it unsubscribes or disconnects. The
82 ***afb\_req\_subscribe*** function will fail if the client
83 connection is weak: if the request comes from a HTTP link. To receive
84 signals, the client must be connected. The AGL framework allows connections
85 using WebSocket.
86
87 The name of the event is either a well known name or an ad hoc name
88 forged for the use case.
89
90 Let's see a basic example: client A expects to receive the speed in km/h
91 every second while client B expects the speed in mph twice a second. In
92 that case, there are two different events because it is not the same
93 unit and it is not the same frequency. Having two different events
94 allows to associate clients to the correct event. But this doesn't tell
95 any word about the name of these events. The designer of the signaling
96 agent has two options for naming:
97
98 1.  names can be the same (“speed” for example) with sent data
99     self describing itself or having a specific tag (requiring from
100     clients awareness about requesting both kinds of speed isn't safe).
101 2.  names of the event include the variations (by example:
102     “speed-km/h-1Hz” and “speed-mph-2Hz”) and, in that case, sent data
103     can self describe itself or not.
104
105 In both cases, the signaling agent might have to send the name of the
106 event and/or an associated tag to its client in the reply of the
107 subscription. This is part of the step 5 above.
108
109 The framework only uses the event (not its name) for subscription,
110 unsubscription and pushing.
111
112 When the requested data is already generated and the event used for
113 pushing it already exists, the signaling agent must not instantiate a
114 new processing chain and must not create a new event object for pushing
115 data. The signaling agent must reuse the existing chain and event.
116
117 Unsubscribing is made by the signaling agent on a request of its client.
118 The ***afb\_req\_unsubscribe*** function tells the framework to
119 remove the requesting client from the event's list of subscribers.
120 Example:
121
122 ```C
123         afb_req_unsubscribe(afb_req, event);
124 ```
125
126 Subscription count does not matter to the framework: subscribing the
127 same client several times has the same effect that subscribing only one
128 time. Thus, when unsubscribing is invoked, it becomes immediately
129 effective.
130
131 #### More on naming events
132
133 Within the AGL framework, a signaling agent is a binding that has an API
134 prefix. This prefix is meant to be unique and to identify the binding
135 API. The names of the events that this signaling agent creates are
136 automatically prefixed by the framework, using the API prefix of the
137 binding.
138
139 Thus, if a signaling agent of API prefix ***api*** creates an event
140 of name ***event*** and pushes data to that event, the subscribers
141 will receive an event of name ***api/event***.
142
143 ### Generating and pushing signals and data
144
145 This of the responsibility of the designer of the signaling agent to
146 establish the processing chain for generating events. In many cases,
147 this can be achieved using I/O or timer or signal events inserted in the
148 main loop. For this case, the AGL framework uses **libsystemd** and
149 provide a way to integrates to the main loop of this library using
150 afb\_daemon\_get\_event\_loop. Example:
151
152 ```C
153         sdev = afb_daemon_get_event_loop(af_daemon);
154         rc = sd_event_add_io(sdev, &source, fd, EPOLLIN, myfunction, NULL);
155 ```
156
157 In some other cases, the events are coming from D-Bus. In that case, the
158 framework also uses **libsystemd** internally to access D-Bus. It provides
159 two methods to get the available D-Bus objects, already existing and
160 bound to the main**libsystemd**event loop. Use either
161 ***afb\_daemon\_get\_system\_bus*** or
162 ***afb\_daemon\_get\_user\_bus*** to get the required instance. Then
163 use functions of **libsystemd** to handle D-Bus.
164
165 In some rare cases, the generation of the data requires to start a new
166 thread.
167
168 When a data is generated and ready to be pushed, the signaling agent
169 should call the function ***afb\_event\_push***. Example:
170
171 ```C
172         rc = afb_event_push(event, JSON);
173         if (rc == 0) {
174                 stop_generating(event);
175                 afb_event_drop(event);
176         }
177 ```
178
179 The function ***afb\_event\_push*** pushes json data to all the
180 subscribers. It then returns the count of subscribers. When the count is
181 zero, there is no subscriber listening for the event. The example above
182 shows that in that case, the signaling agent stops to generate data for
183 the event and delete the event using afb\_event\_drop. This is one
184 possible option. Other valuable options are: do nothing and continue to
185 generate and push the event or just stop to generate and push the data
186 but keep the event existing.
187
188 ### Receiving the signals
189
190 Understanding what a client expects when it receives signals, events or
191 data shall be the most important topic of the designer of a signaling
192 agent. The good point here is that because JSON[^1] is the exchange
193 format, structured data can be sent in a flexible way.
194
195 The good design is to allow as much as possible the client to describe
196 what is needed with the goal to optimize the processing to the
197 requirements only.
198
199 ### The exceptional case of wide broadcast
200
201 Some data or events have so much importance that they can be widely
202 broadcasted to alert any listening client. Examples of such an alert
203 are:
204
205 -   system is entering/leaving “power safe” mode
206 -   system is shutting down
207 -   the car starts/stops moving
208 -   ...
209
210 An event can be broadcasted using one of the two following methods:
211 ***afb\_daemon\_broadcast\_event*** or
212 ***afb\_event\_broadcast***.
213
214 Example 1:
215
216 ```C
217         afb_daemon_broadcast_event(afb_daemon, name, json);
218 ```
219
220 Example 2:
221
222 ```C
223         event = afb_daemon_make_event(afb_daemon, name);
224         . . . .
225         afb_event_broadcast(event, json);
226 ```
227
228 As for other events, the name of events broadcasted using
229 ***afb\_daemon\_broadcast\_event*** are automatically prefixed by
230 the framework with API prefix of the binding (signaling agent).
231
232 Reference of functions
233 ----------------------
234
235 ### Function afb\_event afb\_daemon\_make\_event
236
237 The function ***afb\_daemon\_make\_event*** that is defined as below:
238
239 ```C
240 /*
241  * Creates an event of 'name' and returns it.
242  * 'daemon' MUST be the daemon given in interface when activating the binding.
243  */
244 struct afb_event afb_daemon_make_event(struct afb_daemon daemon, const char *name);
245 ```
246
247 The daemon is the handler to the application framework binder daemon
248 received during initialisation steps of the binding.
249
250 Calling the function ***afb\_daemon\_make\_event*** within the initialisation
251 function ***afbBindingV1Register*** will _fail_ because the binding
252 name is not known at this time.
253
254 The correct way to create the event at initialisation is to call the function
255 ***afb\_daemon\_make\_event*** within the initialisation
256 function ***afbBindingV1ServiceInit***.
257
258 ### Function afb\_event\_push
259
260 The function ***afb\_event\_push*** is defined as below:
261
262 ```C
263 /*
264  * Pushes the 'event' with the data 'object' to its observers.
265  * 'object' can be NULL.
266  *
267  * For convenience, the function calls 'json_object_put' for object'.
268  * Thus, in the case where 'object' should remain available after
269  * the function returns, the function 'json_object_get' shall be used.
270  *
271  * Returns the count of clients that received the event.
272  */
273 int afb_event_push(struct afb_event event, struct json_object *object);
274 ```
275
276 As the function ***afb\_event\_push*** returns 0 when there is no
277 more subscriber, a binding can remove such unexpected event using the
278 function ***afb\_event\_drop***.
279
280 ### Function afb\_event\_drop
281
282 The function ***afb\_event\_drop*** is defined as below:
283
284 ```C
285 /*
286  * Drops the data associated to the event
287  * After calling this function, the event
288  * MUST NOT BE USED ANYMORE.
289  */
290 void afb_event_drop(struct afb_event event);
291 ```
292
293 ### Function afb\_req\_subscribe
294
295 The function ***afb\_req\_subscribe*** is defined as below:
296
297 ```C
298 /*
299  * Establishes for the client link identified by 'req' a subscription
300  * to the 'event'.
301  * Returns 0 in case of successful subscription or -1 in case of error.
302  */
303 int afb_req_subscribe(struct afb_req req, struct afb_event event);
304 ```
305
306 The subscription adds the client of the request to the list of subscribers
307 to the event.
308
309 ### Function afb\_req\_unsubscribe
310
311 The function ***afb\_req\_unsubscribe*** is defined as
312 below:
313
314 ```C
315 /*
316  * Revokes the subscription established to the 'event' for the client
317  * link identified by 'req'.
318  * Returns 0 in case of successful unsubscription or -1 in case of error.
319  */
320 int afb_req_unsubscribe(struct afb_req req, struct afb_event event);
321 ```
322
323 The unsubscription removes the client of the request of the list of subscribers
324 to the event.
325 When the list of subscribers to the event becomes empty,
326 the function ***afb\_event\_push*** will return zero.
327
328 ### Function afb\_event\_broadcast
329
330 The function ***afb\_event\_broadcast*** is defined as below:
331
332 ```C
333 /*
334  * Broadcasts widely the 'event' with the data 'object'.
335  * 'object' can be NULL.
336  *
337  * For convenience, the function calls 'json_object_put' for 'object'.
338  * Thus, in the case where 'object' should remain available after
339  * the function returns, the function 'json_object_get' shall be used.
340  *
341  * Returns the count of clients that received the event.
342  */
343 int afb_event_broadcast(struct afb_event event, struct json_object *object);
344 ```
345
346 This uses an existing event (created with ***afb\_daemon\_make\_event***)
347 for broadcasting an event having its name.
348
349
350 ### Function afb\_daemon\_broadcast\_event
351
352 The function ***afb\_daemon\_broadcast\_event*** is defined as below:
353
354 ```C
355 /*
356  * Broadcasts widely the event of 'name' with the data 'object'.
357  * 'object' can be NULL.
358  * 'daemon' MUST be the daemon given in interface when activating the binding.
359  *
360  * For convenience, the function calls 'json_object_put' for 'object'.
361  * Thus, in the case where 'object' should remain available after
362  * the function returns, the function 'json_object_get' shall be used.
363  *
364  * Returns the count of clients that received the event.
365  */
366 int afb_daemon_broadcast_event(struct afb_daemon daemon, const char *name, struct json_object *object);
367 ```
368
369 The name is given here explicitly. The name is automatically prefixed
370 with the name of the binding. For example, a binding of prefix "xxx"
371 would broadcat the event "xxx/name".
372
373 ### Function afbBindingV1ServiceEvent
374
375 Binding can implement function **afbBindingV1ServiceEvent** which will
376 be called when an event is broadcasted or if service subscribed to an event.
377 That allow a service to react to an event and do what it is to do if this is
378 relevant for it (ie: car back camera detects imminent collision and broadcast
379 it, then appropriate service enable parking brake.). Here is the
380 **afbBindingV1ServiceEvent** definition:
381
382 ```C
383 /*
384  * When a binding have an implementation of the function 'afbBindingV1ServiceEvent',
385  * defined below, the framework calls that function for any broadcasted event or for
386  * events that the service subscribed to in its name.
387  *
388  * It receive the 'event' name and its related data in 'object' (be aware that 'object'
389  * might be NULL).
390  */
391 extern void afbBindingV1ServiceEvent(const char *event, struct json_object *object);
392
393 The binding *tic-tac-toe* broadcasts events when the board changes.
394 This is done in the function **changed**:
395 ```
396
397 Architectural digressions
398 -------------------------
399
400 Based on their dependencies to hardware, signaling agents can be split
401 into 2 categories: low-level signaling agents and high-level signaling
402 agents.
403
404 Low-level signaling agents are bound to the hardware and focused on
405 interfacing and driving.
406
407 High-level signaling agent are independent of the hardware and focused on
408 providing service.
409
410 This separation (that may in the corner look artificial) aim to help in
411 the systems design. The main idea here is that high-level signaling
412 agents are providing “business logic”, also known as “application
413 logic”, that is proper to the car industry and that can be reused and
414 that can evolve as a foundation for the future of the industry.
415
416 The implementation of this decomposition may follow 2 paths: strict
417 separation or soft composition.
418
419 ### Strict separation
420
421 The strict separation implements the modularity composition of signaling
422 agent through the framework. The high-level signaling agent subscribes
423 to the low level signaling agent using the standard client API.
424
425 Advantages:
426
427 -   Modularity
428 -   Separation of responsibilities
429 -   Possible aggregation of multiple sources
430 -   Soft binding of agent good for maintenance
431
432 Drawbacks:
433
434 -   Cost of propagation of data (might serialize)
435 -   Difficulties to abstract low-level signaling agent or to find a
436     trade-off between abstracting and specializing
437
438 The key is modularity versus cost of propagation. It can be partly
439 solved when logical group of signaling agent are launched together in
440 the same binder process. In that particular case, the cost of
441 propagation of data between agents is reduced[^2] because there is no
442 serialization.
443
444 This reduction of the propagation cost (and of the resources used)
445 precludes implementation of strong security between the agents because
446 they share the same memory.
447
448 ### Soft composition
449
450 The soft composition implements the business logic of high-level
451 signaling agents as libraries that can then be used directly by the low
452 level signaling agents.
453
454 Advantages:
455
456 -   No propagation: same memory, sharing of native structures
457
458 Drawbacks:
459
460 -   Cannot be used for aggregation of several sources
461 -   Difficulties to abstract low-level signaling agent or to find a
462     trade-off between abstracting and specializing
463 -   Source code binding not good for maintenance
464
465 [^1]: There are two aspect in using JSON: the first is the flexible data
466     structure that mixes common types (booleans, numbers, strings,
467     arrays, dictionaries, nulls), the second, is the streaming
468     specification. Streaming is often seen as the bottleneck of using
469     JSON (see http://bjson.org). When the agent share the same process,
470     there is no streaming at all.
471
472 [^2]: Within the same process, there is not serialization, the
473     propagation has the cost of wrapping a json data and calling
474     callbacks with the benefit of having a powerful callback manager:
475     the event mechanism of the framework.