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