Uploaded image for project: 'Qpid Proton'
  1. Qpid Proton
  2. PROTON-668

Document Proton-c IO restrictions for 0.8 release

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Blocker
    • Resolution: Fixed
    • proton-0.8
    • proton-0.8
    • proton-c
    • None

    Description

      Proton is designed to provide an efficient IO layer that functions without imposing a threading model on the application. Applications may (1) roll their own IO and just use the Proton engine, (2) use all Proton primitives, (3) use some Proton primitives augmented by an external event loop.

      Case (1) is unrelated to this JIRA. The others may be restated:

      Scenario 2: Proton event loop: a proton selector manages socket events for all sockets placed in the selector, all associated sockets use pn_io_xxx() calls. Sockets outside the selector are "unmanaged" and passed through to the OS socket function unchanged.

      Scenario 3: Third party event loop (no proton selector involved), all sockets are treated as for "unmanaged" in scenario 2.

      Scenario 4, 5...: Others to support?

      The problem:

      The Proton Posix pattern for efficient IO is:

      "tell me when your (OS) buffer is ready for io transfer (in or out)"

      Whereas the normal Windows pattern is somewhat reversed (IO completion ports):

      "tell me when you are done transferring data (to or from) my (user space) buffer"

      The current Windows IOCP implementation (PROTON-640) tries to make the latter look like the former with some constraints. There should be documentation specifying reasonable limits on Proton usage that may be falsely implied by the API but do not translate efficiently to Windows. Assuming that future Windows implementations may adopt more aggressive performance strategies (especially on the read side), I would propose something along the lines of:

      a socket may only ever be used with a single pn_io_t in its lifetime
      exception: a socket from pn_accept() is not yet associated with any pn_io_t and its first use can be with any pn_io_t (or never with a pn_io_t at all)

      send/recv/close may not be intermixed with similar non-Proton OS calls (otherwise: out of order or lost data)

      a socket can move once from an external loop to a proton loop, but never the other way

      pn_pipe() values can only be used with pn_read and pn_write and pn_selector_select, they cannot participate in an external event loop.

      Furthermore, there is no thread safety except:

      threads may do concurrent pn_io_xxx() calls as long as no two are simultaneous on the same socket (where xxx is send/recv/read/write)

      pn_selector_select() is thread safe against pn_read/pn_write/pn_send/pn_recv, but the outcome of the select is indeterminate. pn_selector_select() must be interrupted and restarted at any time when other simultaneous IO may affect the outcome.

      calls on different pn_io_t objects do not interact and are thread safe.

      If it is desirable for a socket to be used in an external loop after being used in a Proton loop, we would need some sort of blocking calls along the lines of:

      pn_io_flush()
      pn_io_drain()

      which would be no-ops on Posix but would unwind outstanding completions on Windows.

      Early criticism of any of the above assumptions would be greatly appreciated. I will try to reword the above, or its evolution into the existing documentation for 0.8.

      Attachments

        Activity

          People

            cliffjansen Clifford Jansen
            cliffjansen Clifford Jansen
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: