{"action":"created","issue":{"url":"https://api.github.com/repos/mirage/mirage/issues/550","repository_url":"https://api.github.com/repos/mirage/mirage","labels_url":"https://api.github.com/repos/mirage/mirage/issues/550/labels{/name}","comments_url":"https://api.github.com/repos/mirage/mirage/issues/550/comments","events_url":"https://api.github.com/repos/mirage/mirage/issues/550/events","html_url":"https://github.com/mirage/mirage/pull/550","id":162642986,"number":550,"title":"[RFC] Add `disconnect` to `FLOW`","user":{"login":"djs55","id":198586,"avatar_url":"https://avatars.githubusercontent.com/u/198586?v=3","gravatar_id":"","url":"https://api.github.com/users/djs55","html_url":"https://github.com/djs55","followers_url":"https://api.github.com/users/djs55/followers","following_url":"https://api.github.com/users/djs55/following{/other_user}","gists_url":"https://api.github.com/users/djs55/gists{/gist_id}","starred_url":"https://api.github.com/users/djs55/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/djs55/subscriptions","organizations_url":"https://api.github.com/users/djs55/orgs","repos_url":"https://api.github.com/users/djs55/repos","events_url":"https://api.github.com/users/djs55/events{/privacy}","received_events_url":"https://api.github.com/users/djs55/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2016-06-28T09:36:35Z","updated_at":"2016-06-28T09:40:36Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/mirage/mirage/pulls/550","html_url":"https://github.com/mirage/mirage/pull/550","diff_url":"https://github.com/mirage/mirage/pull/550.diff","patch_url":"https://github.com/mirage/mirage/pull/550.patch"},"body":"`FLOW` already includes `close` which performs a graceful shutdown\r\nof one half of a bidirectional connection (also known as a half-close\r\nand written in Unix as `Unix.(shutdown fd Unix.SHUTDOWN_SEND)`).\r\nFor example in the Mirage tcpip stack, [close](https://github.com/mirage/mirage-tcpip/blob/29a5e068f6175207bb42965edd228d334157f56f/lib/tcp/flow.ml#L74) will send a FIN\r\nand wait for the FIN ACK and then continue accepting data in the\r\nother direction. This is important for protocols like HTTP where a\r\ncommon pattern is to `connect`, `write` a request and then `close`\r\n(a.k.a. `Unix.(shutdown fd SHUTDOWN_SEND)`), and then `read` the\r\nresponse.\r\n\r\nThis patch requires a `disconnect` function which performs an\r\nungraceful shutdown of both halves of a bidirectional connection.\r\n`disconnect` waits until all local resources have been cleaned up\r\n(within limits imposed by the platform). Users who are happy to\r\nlet resources be freed in the background are welcome to call\r\n`disconnect` asychronously.\r\n\r\nNotes regarding implementations:\r\n\r\n- in the Mirage tcpip stack, connection state is freed in the\r\n  background as connections close and are timed-out. This extra\r\n  function allows us to (i) request the state be cleaned up sooner;\r\n  and (ii) optionally wait for the cleanup to be complete.\r\n- in a Unix shim, `disconnect` should call `Unix.close` (or its\r\n  equivalent) which will drop any buffered data rather than try to\r\n  resend it, perform a FIN/ACK handshake and return. Unfortunately\r\n  the Unix socket API is limited and it's not possible for us to\r\n  wait while the kernel manages the connection in the \"TIME-WAIT\"\r\n  state. This means it's possible even for careful applications\r\n  to run out of kernel resources.\r\n\r\nCurrently it's not possible to write a TCP proxy with FLOWs\r\nbecause of the confusion between half-close and full-close.\r\n\r\nAlthough the terminology is different to Unix, I quite like the use of\r\n`disconnect` here since it mirrors what we already do with `DEVICE`s\r\nand is the opposite of `connect`.\r\n\r\nAn alternative would be:\r\n- redefine `FLOW.close` to mean the same as `Unix.close` i.e.\r\n  full close, drop incoming date (so one would `disconnect` a `BLOCK`\r\n  but `close` a `FLOW`?)\r\n- add a `FLOW.shutdown` to mean the same as `Unix.shutdown`\r\n  to half-close the connection\r\n- change `mirage-tcpip` to use both of these.\r\n"},"comment":{"url":"https://api.github.com/repos/mirage/mirage/issues/comments/229001403","html_url":"https://github.com/mirage/mirage/pull/550#issuecomment-229001403","issue_url":"https://api.github.com/repos/mirage/mirage/issues/550","id":229001403,"user":{"login":"avsm","id":53164,"avatar_url":"https://avatars.githubusercontent.com/u/53164?v=3","gravatar_id":"","url":"https://api.github.com/users/avsm","html_url":"https://github.com/avsm","followers_url":"https://api.github.com/users/avsm/followers","following_url":"https://api.github.com/users/avsm/following{/other_user}","gists_url":"https://api.github.com/users/avsm/gists{/gist_id}","starred_url":"https://api.github.com/users/avsm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/avsm/subscriptions","organizations_url":"https://api.github.com/users/avsm/orgs","repos_url":"https://api.github.com/users/avsm/repos","events_url":"https://api.github.com/users/avsm/events{/privacy}","received_events_url":"https://api.github.com/users/avsm/received_events","type":"User","site_admin":false},"created_at":"2016-06-28T09:40:36Z","updated_at":"2016-06-28T09:40:36Z","body":"I'm in favour of remaining consistent with our use of `connect`/`disconnect` wrt state management"}}
{"actor":{"display_login":"avsm"}}