Eric, thank you for your review and thoughts on the matter. You raised a few questions, please allow me to both answer and clarify the intention behind the proposed extension.
>> I represent an effort to extend Rack so that it allows server-side >> websocket upgrade implementation support and pure Rack websocket >> applications. >> >> This new Rack feature proposal is gaining support, with over 42 >> support votes in the [original Rack discussion >> thread](https://github.com/rack/rack/issues/1093). > > You mention performance several times, but I am not sure what > you mean. unicorn completely stops caring for a socket after > it's hijacked by the app. In other words: > > Your Rack app could take the socket and inject it into an > event loop running in a separate thread. That event loop > could be 100% C code running without GVL for all unicorn > cares. Running two (or more) event loops, each with it's own resources, is wasteful and promotes needless context switches. There is no reason to hijack a socket when the server can easily provide callbacks for IO related events using it's existing established event loop. This alone should provide a performance boost. There are other considerations as well, but I think they all derive from this core principle of having the web server retain control over all network IO concerns. > Also, Ruby IO.select also supports arbitrary number of > descriptors in some cases (Linux for sure, and probably most > server-oriented *BSDs). Of course, the malloc usage + O(n) > behavior still suck, but no, select(2) is not always limited to > <=1024 FDs. Although this isn't as relevant to the proposed specification, it is a good example for how intricate network programming details are unknown by most Ruby programmers and shows why it would be better for the web server to retain control over all network IO concerns. For example, the Linux man page expressly states that "To monitor file descriptors greater than 1023, use poll(2) instead" This is true even when using select for a single FD that has a value of more then 1023, since `select` is often implemented using a bit vector map of 1024 bits that are controlled using the FD_(*) macros. See, for example: http://linux-tips.org/t/is-it-possible-to-listen-file-descriptor-greater-than-1024-with-select/45/2 Ruby's IO.select uses this same system call and suffers the same issues that are present in the OS - each OS with it's own quirks. I don't think application developers should worry about these details when these issues were already resolved during the server's designed. By having the server provide callbacks - instead of hijacking - we eliminate a hoard of potential bugs and considerations. > unicorn would only parse the first HTTP request (with the > Upgrade header) before the Rack app hijacks it. Of course, not every server has to offer this feature - just like hijacking, it's optional. Unicorn was design for very specific use cases, so I definitely understand if this might not be as interesting for you. However, I do think your experience as developers could help enrich us all. If you have any comments or anything to add regarding the proposed `websocket.upgrade` specification, your voice is welcome: https://github.com/boazsegev/iodine/issues/6
