service-communication.tm 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. <TeXmacs|2.1>
  2. <project|scheme-gnunet.tm>
  3. <style|tmmanual>
  4. <\body>
  5. To connect with a GNUnet service<index|services> \V this applies to both
  6. the C and Scheme implementation, the GNUnet service must bind a local
  7. domain socket<\footnote>
  8. The C implementation supports Internet sockets as well.
  9. </footnote> somewhere on the file system and the client (possibly another
  10. service) must connect to it.<space|1em>Connections to a service can be made
  11. with the <scm|connect/fibers><index|connect/fibers> procedure from
  12. <scm|(gnu gnunet mq-impl stream)><index|(gnu gnunet mq-impl stream)>, like
  13. this:
  14. <\scm-code>
  15. (define mq (connect/fibers config "nse" handlers error-handler))
  16. </scm-code>
  17. <section|Asynchronuously connecting><index|connecting to services>
  18. This is an asynchronuous operation: it will \<#2018\>complete\<#2019\>
  19. immediately and the connection will actually be formed in the
  20. background.<space|1em>When the connection has actually be formed, the
  21. <scm|error-handler><index|error-handler> is called with the symbol
  22. <scm|connection:connected><index|connection:connected>.<space|1em>To
  23. demonstrate, the following code asynchronuously connects to the NSE
  24. service, and prints the text <scm|"connected!"> when the connection has
  25. actually been formed.
  26. <\scm-code>
  27. ;; XXX test this, explain 'config' ...
  28. (define (error-handler error . args)
  29. \ \ (case error
  30. \ \ \ \ ((connection:connected)
  31. \ \ \ \ \ (format #t "connected!~%"))
  32. \ \ \ \ (else (format #t "unknown error: ~a ~a~%" error args))))
  33. \;
  34. (define mq
  35. \ \ (connect/fibers config "nse" (message-handlers) error-handler))
  36. </scm-code>
  37. <section|Message handler>
  38. <index|message handler>When a message is received by the message queue, the
  39. corresponding message handler is invoked.<space|1em>Message handlers can be
  40. constructed with the <scm|message-handler><index|message-handler> macro and
  41. the <scm|make-message-handler><index|make-message-handler> procedure from
  42. <scm|(gnu gnunet mq handler)>, as follows:
  43. <\scm-code>
  44. (import (gnu gnunet mq handler)
  45. \ \ \ \ \ \ \ \ (gnu extractor enum)
  46. \ \ \ \ \ \ \ \ (gnu gnunet message protocols)
  47. \ \ \ \ \ \ \ \ (gnu gnunet util struct)
  48. \ \ \ \ \ \ \ \ (gnu gnunet utils bv-slice)
  49. \ \ \ \ \ \ \ \ (gnu gnunet netstruct syntactic))
  50. \;
  51. (define handler/syntactic
  52. \ \ (message-handler
  53. \ \ \ (type (symbol-value message-type msg:util:dummy))
  54. \ \ \ ((interpose code) code)
  55. \ \ \ ((well-formed? slice)
  56. \ \ \ \ (= (slice-length slice)
  57. \ \ \ \ \ \ \ (sizeof /:message-header '())))
  58. \ \ \ ((handle! slice)
  59. \ \ \ \ (pk 'message: slice))))
  60. \;
  61. (define handler/procedural
  62. \ \ (make-message-handler
  63. \ \ \ (symbol-value message-type msg:util:dummy)
  64. \ \ \ (lambda (thunk) (thunk))
  65. \ \ \ (lambda (slice)
  66. \ \ \ \ \ (= (slice-length slice)
  67. \ \ \ \ \ \ \ \ (sizeof /:message-header '())))
  68. \ \ \ (lambda (slice)
  69. \ \ \ \ \ (pk 'message: slice))))
  70. </scm-code>
  71. As illustrated in the example code above, a message handler has four
  72. components: the <with|font-shape|italic|type> of message<subindex|message
  73. type|of handler> it handles, an <with|font-shape|italic|interposer><index|interposer>
  74. which will be explained later, the <with|font-shape|italic|verifier><index|verifier>
  75. deciding if a message is well-formed and the
  76. <with|font-shape|italic|handler procedure><index|handler procedure>.
  77. The verifier is passed a bytevector slice with the message and should
  78. return <scm|#true> if the message is well-formed and <scm|#false> if it
  79. isn't.<space|1em>It may assume that the length of the slice corresponds to
  80. the length <em|in> the message header and is at least the length <em|of>
  81. the message header and that the type in the message header corresponds to
  82. the type of the message handler.<space|1em>Messages will only be passed to
  83. the handler procedue if the verifiers returns <scm|#true>.
  84. The handler procedure is passed a bytevector slice with the message, but
  85. only if the verifier considers it well-formed.<space|1em>The handler
  86. procedure and verifier are run from the
  87. <with|font-shape|italic|interposer>.<space|1em>The interposer is passed a
  88. thunk to execute and may e.g. install exception handlers and parameterise
  89. parameters.<space|1em>It can change the current input, output and error
  90. ports for example.
  91. <todo|document the message type database, various procedures>
  92. <section|Message type database><label|sec:message type><subindex|message
  93. type|database>
  94. The module <scm|(gnu gnunet message protocols)><index|(gnu gnunet message
  95. protocols)> has a mapping of symbolic names of every message type known to
  96. scheme-GNUnet to their numeric value.<space|1em>To use it, the macro
  97. <scm|symbol-value><index|symbol-value> from <scm|(gnu extractor
  98. enum)><index|(gnu extractor enum)> is required and possibly
  99. <scm|value-\<gtr\>index><index|value-\<gtr\>index> as well.<space|1em>To
  100. determine the numeric value of the message type <scm|msg:nse:estimate>, one
  101. would write:
  102. <\scm-code>
  103. (define numeric-type
  104. \ \ (value-\<gtr\>index (symbol-value message-type msg:nse:estimate)))
  105. </scm-code>
  106. <todo|other various enum procedures for introspection, documentation,
  107. <text-dots>?>
  108. <todo|how to define new message types>
  109. <section|Sending messages>
  110. Messages can be sent with the <scm|send-message!><index|send-message!>
  111. procedure, which can be called as <scm|(send-message! <var|mq>
  112. <var|message> #:priority <var|priority>)>, where <var|mq> is the message
  113. queue and <var|message> is the message to send as a readable bytevector
  114. slice. This is an asynchronuous operation, so this procedure can return
  115. before the service has processed the message.
  116. <label|mq-prio-prefs>Depending on the transport, it might be possible for
  117. messages to be lost or received out-of-order. Some transports allow to
  118. explicitely allow messages to be lost or received out-of-order and would by
  119. default retransmit lost messages and reorder out-of-order messages; this
  120. behaviour can to a degree be controlled by setting the
  121. <dfn|priority-preference> flags.
  122. These flags are not absolute, e.g. even if reliable transmission is
  123. requested, it is possible that the transport fail to transmit the message.
  124. The exact behaviour is transport-dependent!
  125. <\description>
  126. <item*|<scm|pref:unreliable>>Unreliable delivery is acceptable.
  127. <item*|<scm|pref:low-latency>>Low latency is desired, this cannot be
  128. meaningfully combined with <scm|pref:cork-allowed>.
  129. <item*|<scm|pref:cork-allowed>>The transmission of a message can be
  130. delayed to combine this message with other messages into a larger
  131. transmission with less per-message overhead.
  132. <item*|<scm|pref:good-throughput>>High bandwith is desired; the method
  133. chosen for transmission should focus on overall throughput.
  134. <item*|<scm|pref:out-of-order>>Out-of-order delivery is acceptable.
  135. </description>
  136. These flags can be combined into a numeric value with the macro
  137. <scm|prio-prefs> from <scm|(gnu gnunet mq prio-prefs)>; the following code
  138. defines <var|x> as the numeric value of the flags <scm|pref:unreliable> and
  139. <scm|pref:out-of-order>:
  140. <\scm>
  141. (import (gnu gnunet mq prio-prefs))
  142. (define x (prio-prefs pref:unreliable pref:out-of-order))
  143. </scm>
  144. This numeric priority-preference can be passsed to <scm|send-message!> as
  145. the optional <var|priority> keyword argument of <scm|send-message!>. The
  146. transport of <scm|connect/fibers> is always reliable and in-order.
  147. <todo|notify-sent! callbacks><todo|cancellation><todo|queue size limits,
  148. <scm|%suspicious-length>>
  149. <section|Error handler><index|error handler>
  150. The message queue implementation usually just sends and receives messages,
  151. but some exceptional situations cannot be communicated with
  152. <scm|send-message!> or <scm|inject-message!>.<space|1em>For those, there is
  153. the <scm|inject-error!><index|inject-error!> procedure.<space|1em>This
  154. variadic procedure accepts a message queue to inject the error into, a
  155. <with|font-shape|italic|key><index|key> (usually a symbol) describing the
  156. exceptional situation and rest arguments.<space|1em>It calls the
  157. <with|font-shape|italic|error handler> of the message queue with the key
  158. and rest arguments.<space|1em>The following errors can currently be
  159. reported by the built-in message queue implementations:
  160. <\explain>
  161. <scm|connection:connected><index|connection:connected>
  162. <|explain>
  163. The connection to the server has been established.
  164. </explain>
  165. <\explain>
  166. <scm|connection:interrupted><index|connection:interrupted>
  167. </explain|The message queue has been closed before the connection to the
  168. server could be established.>
  169. <\explain>
  170. <scm|input:regular-end-of-file><index|input:regular-end-of-file>
  171. <|explain>
  172. The connection has been closed by the server.
  173. For people wondering about what happens if a connection becomes
  174. half-duplex: GNUnet does not have a notion of half-duplex message
  175. streams.<space|1em>If it is detected the underlying stream became
  176. half-duplex anyways, it will be treated as closed by scheme-GNUnet,
  177. resulting in this error.<space|1em>However, note that currently broken
  178. pipes cannot be reliably detected.
  179. </explain>
  180. <\explain>
  181. <scm|input:premature-end-of-file><index|input:premature-end-of-file>
  182. </explain|The connection was closed by the server while a message was still
  183. being read.<space|1em>This can happen if the server was stopped while it
  184. was still sending the rest of the message.>
  185. <\explain>
  186. <scm|input:overly-small> <var|type> <var|size><index|input:overly-small>
  187. </explain|The message size in the header was smaller than the minimal
  188. message size.<space|1em>Sometimes, but not always, the message type
  189. <var|type> and message size <var|size> are available (as exact
  190. naturals).<space|1em>When they are not available, <var|type> and <var|size>
  191. are <scm|#false> instead.<space|1em>This can only happen if the server or
  192. connection to the server is buggy.>
  193. <\explain>
  194. <scm|logic:no-handler> <var|type> . <var|rest><index|logic:no-handler>
  195. <|explain>
  196. The received message of type <var|type> (as an integer) does not have a
  197. corresponding message handler.<space|1em><var|rest> is currently
  198. unspecified.
  199. </explain>
  200. <\explain>
  201. <scm|logic:ill-formed> <var|type> . <var|rest><index|logic:ill-formed>
  202. </explain|The received message of type (as an integer) is ill-formed
  203. according to the message handler.<space|1em><var|rest> is currently
  204. unspecified.>
  205. Consider automatically reconnecting after
  206. <scm|<scm|input:regular-end-of-file>> and
  207. <scm|<scm|input:premature-end-of-file>>, to allow the server to restart
  208. without having to manually restart every individual
  209. application.<space|1em>To report errors, see the section
  210. <reference|sec:error reporting> Error reporting.
  211. <section|Ordering of injected errors and messages and sent messages>
  212. This section describes how injected errors and messages and sent messages
  213. are ordered with respect to each other in the default message queue
  214. implementation.<space|1em>Messages are handled or corresponding
  215. <scm|logic:no-handler> or <scm|logic:ill-formed> errors are injected in the
  216. order that the messages are received.<space|1em>Before messages are read,
  217. <scm|connection:connected> is injected.<space|1em>This error is injected at
  218. most once.
  219. <em|Soon> after all messages are read (and therefore
  220. <with|font-shape|italic|soon> after all handled messages or corresponding
  221. errors), the error <scm|input:regular-end-of-file>,
  222. <scm|input:overly-small> or <scm|input:premature-end-of-file> is
  223. injected.<space|1em>Only one of those errors can be injected for the entire
  224. lifetime of the message queue.
  225. Be aware that <em|soon> is not <em|immediate> here!<space|1em>For example,
  226. it is possible for a message to be received, the port closed, a message
  227. queued for sending, the closing of the port being detected by the write
  228. fiber, <scm|input:regular-end-of-file> being injected from the write fiber
  229. and the read fiber handling the received message, and the read fiber
  230. exiting because the port is closed, in that order.
  231. Messages are sent (and received on the other side) in the order they were
  232. enqueued for sending.<space|1em>Likewise, the notify-sent callback of
  233. enqueued messages are called in order.<space|1em>If the notify-sent
  234. callback is called, it is before the message is received by the other
  235. side.<space|1em>The message and its notify-sent callback are only received
  236. by the other side and called after the message has been injected and
  237. <scm|connection:connected> has been injected.<space|1em>It is possible for
  238. the notify-sent callback to be called without the message being received by
  239. the other side, e.g. if the port was closed during the notify-sent
  240. callback.
  241. If a message is received by the other side, all previously-sent messages
  242. have be received before.<space|1em>If a notify-sent callback is invoked,
  243. all notify-sent callbacks of previous messages have been invoked before,
  244. except the messages that are eventually cancelled.
  245. The errors <scm|logic:no-handler> and <scm|logic:ill-formed> are not fatal:
  246. later messages can still be read and handled.<space|1em>If
  247. <scm|connection:interrupted> is injected, no other errors are ever
  248. injected, whether in the past or in the future.<space|1em>This error can
  249. only be injected once.
  250. <todo|I/O errors>
  251. <todo|envelopes>
  252. <section|Disconnecting><index|disconnecting>
  253. A message queue can be closed with the <scm|close-queue!><index|close-queue!>
  254. procedure from <scm|(gnu gnunet mq)>.<space|1em>In the default message
  255. queue implementation, this asynchronuously closes the port and stops
  256. associated fibers.<space|1em>Closing ports when they won't be used anymore
  257. is important for limiting resource consumption, especially for servers that
  258. can have many connections.<space|1em>Closing message queues is an
  259. idempotent operation: closing a message queue twice is the same as closing
  260. it once.<space|1em> If a message queue is closed before a connection could
  261. be formed, <scm|connection:interrupted><index|connection:interrupted> is
  262. injected instead of <scm|connection:connected> and
  263. <scm|connection:regular-end-of-file>.
  264. <section|Error reporting><label|sec:error reporting>
  265. <index|error reporting>Errors can be reported with the procedure
  266. <scm|report-error> from the module <scm|(gnu gnunet mq
  267. error-reporting)><index|(gnu gnunet mq error-reporting)>.<space|1em>It can
  268. be called as <scm|(report-error key argument ...)>, e.g. <scm|(report-error
  269. 'logic:no-handler 3)><index|report-error>.<space|1em>By default, it reports
  270. the error to the current error port.<space|1em>If this is not desired, the
  271. output can be sent to another port by setting the parameter
  272. <scm|textual-error-reporting-port><index|textual-error-reporting-port>.<space|1em>If
  273. textual error reporting is not desired, the parameter
  274. <scm|error-reporter><index|error-reporter> can be set to a procedure with
  275. the same interface as <scm|report-error>.<space|1em>Such a procedure could
  276. e.g. open a GUI dialog, sent the message to the system logger or ignore the
  277. error.
  278. Error messages are translated for the current locale.<todo|TODO actually
  279. call bindtextdomain>
  280. </body>
  281. <\initial>
  282. <\collection>
  283. <associate|page-medium|paper>
  284. <associate|save-aux|false>
  285. </collection>
  286. </initial>