{"action":"created","issue":{"url":"https://api.github.com/repos/crystal-lang/crystal/issues/4019","repository_url":"https://api.github.com/repos/crystal-lang/crystal","labels_url":"https://api.github.com/repos/crystal-lang/crystal/issues/4019/labels{/name}","comments_url":"https://api.github.com/repos/crystal-lang/crystal/issues/4019/comments","events_url":"https://api.github.com/repos/crystal-lang/crystal/issues/4019/events","html_url":"https://github.com/crystal-lang/crystal/issues/4019","id":206991982,"number":4019,"title":"Binding TCPServer to the same port from different processes","user":{"login":"straight-shoota","id":466378,"avatar_url":"https://avatars.githubusercontent.com/u/466378?v=3","gravatar_id":"","url":"https://api.github.com/users/straight-shoota","html_url":"https://github.com/straight-shoota","followers_url":"https://api.github.com/users/straight-shoota/followers","following_url":"https://api.github.com/users/straight-shoota/following{/other_user}","gists_url":"https://api.github.com/users/straight-shoota/gists{/gist_id}","starred_url":"https://api.github.com/users/straight-shoota/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/straight-shoota/subscriptions","organizations_url":"https://api.github.com/users/straight-shoota/orgs","repos_url":"https://api.github.com/users/straight-shoota/repos","events_url":"https://api.github.com/users/straight-shoota/events{/privacy}","received_events_url":"https://api.github.com/users/straight-shoota/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":12,"created_at":"2017-02-11T16:44:30Z","updated_at":"2017-02-14T15:24:56Z","closed_at":null,"body":"After I had a server process lingering around and running the exact same program again, I noticed that different crystal processes *can* bind to the same port (without any special setup as suggested in #3586). I used [this simple test server](https://github.com/straight-shoota/nginx-cache-test/blob/master/backend.cr) which returns an incrementing counter. With two process listening on the same port, every incoming connection is randomly assigned to one of them:\r\n\r\n```\r\n> for i in `seq 1 10`; do curl localhost:8022/; echo -e \"\" ; done\r\n2\r\n2\r\n3\r\n4\r\n3\r\n4\r\n5\r\n5\r\n6\r\n7\r\n```\r\n\r\nI find this behaviour quite odd. By default a second binding should fail with a port already in use exception. I believe, most people would expect this.\r\nIt is almost never desired to have different processes  listening on the same port (unless it is intentionally set up), and the user possibly being unaware of this.\r\n\r\nThen I tested things further and investigated how other languages implementations work. Pythons oneliner `python -m SimpleHTTPServer 8022` threw an error `[Errno 98] Address already in use` when the crystal server was already bound to the same port. The crystal server also failed when the python server was run first (`Address already in use (Errno)`).\r\nReally interesting is Ruby's WebRick (`ruby -run -e httpd . -p8022`): It seems to hijack the socket and no request is let through to the crystal server and every connection goes to WebRick. Once the ruby process is stopped, the crystal server receives again. The other way around, crystal also fails with `Address already in use (Errno)` when WebRrick was started first. That is, unless another crystal server was started before WebRick. Then the second one also succeeds but does not receive any connection as long as WebRick is running.\r\n\r\nBesides the odd WebRick behaviour, it seems like the crystal implementation succeeds to bind to an already occupied port as long as at least one other crystal process is also bound to this port. Why this happens, I have no idea... but I would argue that it shouldn't and instead fail with an port already in use exception.\r\n\r\n>  crystal --version\r\n>  Crystal 0.20.5 [ccf46c0] (2017-01-20)"},"comment":{"url":"https://api.github.com/repos/crystal-lang/crystal/issues/comments/279737912","html_url":"https://github.com/crystal-lang/crystal/issues/4019#issuecomment-279737912","issue_url":"https://api.github.com/repos/crystal-lang/crystal/issues/4019","id":279737912,"user":{"login":"RX14","id":2788811,"avatar_url":"https://avatars.githubusercontent.com/u/2788811?v=3","gravatar_id":"","url":"https://api.github.com/users/RX14","html_url":"https://github.com/RX14","followers_url":"https://api.github.com/users/RX14/followers","following_url":"https://api.github.com/users/RX14/following{/other_user}","gists_url":"https://api.github.com/users/RX14/gists{/gist_id}","starred_url":"https://api.github.com/users/RX14/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RX14/subscriptions","organizations_url":"https://api.github.com/users/RX14/orgs","repos_url":"https://api.github.com/users/RX14/repos","events_url":"https://api.github.com/users/RX14/events{/privacy}","received_events_url":"https://api.github.com/users/RX14/received_events","type":"User","site_admin":false},"created_at":"2017-02-14T15:24:56Z","updated_at":"2017-02-14T15:24:56Z","body":"Isn't `reuse_address` a sensible default?"}}
{"actor":{"display_login":"RX14"}}