ipc-high.txt 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. The IPC protocol
  2. ================
  3. While the cc-protocol.txt describes the low-level primitives, here we
  4. describe how the whole IPC should work and how to use it.
  5. Assumptions
  6. -----------
  7. We assume the low-level protocol keeps ordering of messages. That is,
  8. if A sends messages 1 and 2 to B, they get delivered in the same order
  9. as they were sent. However, if A sends message 1 to B and 2 to C, the
  10. order in which get them or the order in which they answer is not
  11. defined.
  12. We also assume that the delivery is reliable. If B gets a message from
  13. A, it can be sure that all previous messages were delivered too. If A
  14. sends a message to B, B either gets the message or either A or B is
  15. disconnected during the attempt.
  16. Also, we expect the messages don't get damaged or modified on their
  17. way.
  18. Addressing
  19. ----------
  20. We can specify the recipient in two different ways:
  21. * Directly. Each connected client has an unique address. A message
  22. addressed to that addressed is sent only to the one client.
  23. * By a group. A client might subscribe to any number of groups.
  24. When a message is sent to the group, all clients subscribed to the
  25. group receive it. It is legal to send to an empty group.
  26. Feedback from the IPC system
  27. ----------------------------
  28. The IPC system generates some additional information to aid the
  29. communicating clients.
  30. Undeliverable notification::
  31. If the client requests it (by a per-message flag) and the set of
  32. recipients specified is empty (either because the connection
  33. ID/lname is not connected or because the addressed group is empty),
  34. an answer message is sent from the MSGQ daemon to notify it about
  35. the situation.
  36. Notifications about connections and disconnections::
  37. The system generates notification about following events:
  38. * Client with given lname connected
  39. * Client with given lname disconnected
  40. * Client with given lname subscribed to given group
  41. * Client with given lname unsubscribed from given group
  42. List of group members:
  43. The MSGQ provides a command to list members of given group and list
  44. of all connections.
  45. Communication paradigms
  46. -----------------------
  47. Event notifications
  48. ~~~~~~~~~~~~~~~~~~~
  49. Sometimes, an event that may be interesting to other parts of the
  50. system happens. The originating module may not know what other modules
  51. are interested in that kind of event, nor it may know if any at all
  52. wants to know that. With such event, the originating module does not
  53. need any feedback.
  54. For each kind or family of notifications, there's a group. Everybody
  55. interested in that family of notifications subscribes to the group.
  56. When the event happens, it is sent (broadcasted) to the group, without
  57. requiring an answer.
  58. [[NOTE]]
  59. To avoid race conditions on start up, it is important to first
  60. subscribe to the group and then load the initial state (for which
  61. change the notification would be), not the other way around. The other
  62. way, the state could be loaded, and then, before subscribing, an event
  63. could happen and be unnoticed. On the other hand, we may still receive
  64. event for change to the state we already loaded (which should be
  65. generally safe), but not lose an update.
  66. Examples of these kinds could be change to a zone data (so it would
  67. get reloaded by every process that has the data),
  68. connection/disconnection notification from msgq, or change to
  69. configuration data.
  70. It would be the recipients responsibility to handle the notification,
  71. or at least, produce an error log message. In these situations, the
  72. originator can not reasonably handle error cases anyway (the zone data
  73. has been written), so if something does not work, log is everything we
  74. can do.
  75. One-to-one RPC call
  76. ~~~~~~~~~~~~~~~~~~~
  77. Sometimes, a process needs to call remote function (or command) in
  78. other process. An example could be asking the configuration manager
  79. for the current configuration or asking it to change it, asking single
  80. process to terminate, etc.
  81. It may be that the group is a singleton group (eg. the command
  82. manager, there must be exactly one in a running system, and is used
  83. just as a stable name for the process) or an lname received by means
  84. of other communication (like a previous subscribe notification).
  85. A command message (containing the parameters, name of the command,
  86. etc) is sent, with the want-answer flag set. The other side processes
  87. the command and sends a result or error back.
  88. If the recipient does not exist, the msgq sends an error right away.
  89. There are still two ways this may fail to provide an answer:
  90. * The receiving module reads the command, but does not provide an
  91. answer. Clearly, such module is broken. There should be some (long)
  92. timeout for this situation, and loud logging to get it fixed.
  93. * The receiving module terminated at the exact time when msgq tried
  94. to send to it, or crashed handling the command. Therefore the
  95. sender listens for disconnect or unsubscription notifications
  96. (depending on if it was sent by lname or group name) and if the
  97. recipient disconnects, the sender knows it should not expect the
  98. answer any more.
  99. An asynchronous waiting for the answer is preferred.
  100. One-to-many RPC call
  101. ~~~~~~~~~~~~~~~~~~~~
  102. Sometimes it is needed to send a command to bunch of modules at once,
  103. usually all members of a group that can contain any number of clients.
  104. This would be done by requesting the members of the group from msgq
  105. and then sending a one-to-one RPC call to each of them, tracking them
  106. separately.
  107. [NOTE]
  108. It might happen the list of group members changes between the time it
  109. was requested and the time the commands are sent. If a client gets
  110. disconnected, the sender gets an undeliverable error back from msgq.
  111. If anything else happens (the client unsubscribes, connects,
  112. subscribes), it must explicitly synchronise to the state anyway,
  113. because we could have sent the commands before the change actually
  114. happened and it would look the same to the client.
  115. [WARNING]
  116. It would look better to first request the list of group members and
  117. then send the command to the group, and use the list to track the
  118. answers only. But that is prone to race conditions ‒ if there's any
  119. change between the request for the member list and sending the
  120. command, the actual recipients don't match the list and the server
  121. could get more answers than expected or could wait for answer of a
  122. module that no longer exists.
  123. Known limitations
  124. -----------------
  125. It is meant mostly as signalling protocol. Sending millions of
  126. messages or messages of several tens of megabytes is probably a bad
  127. idea. While there's no architectural limitation with regards of the
  128. number of transferred messages or their sizes, the code is not
  129. optimised and it would probably be very slow.