It doesn't help if HT does it's part right. Imagine, for the sake of argument that your code inside a handler writes to the log file. The handle of the log file is shared between all threads (or else there would be a log file per thread? Not something you want to do, right?). So, imagine you have two long-living requests, which you serve in server-events fashion: first starts writing to the file stream while at the same time the second handles data. Just as the first one is about to finish to write to the log, the second one finished writing data and wants to write to the log as well: boom, you have a race: two threads fighting over the ownership of the log file handle! Sockets don't particularly help in this scenario, but IMO they make the programmer more aware of what happens to the program (I'm not a big fun of implicit parallelism...)
On Sat, Mar 1, 2014 at 11:46 PM, Ron Garret ron@flownet.com wrote:
you may easily run yourself into a situation where two functions try to write to the same output stream
I don't think so. The default HT taskmaster on a multi-threaded Lisp spawns a thread per connection and rebinds all the globals. If it didn't, then *any* simultaneous connections would have problems, not just SSE connections. And even on a single-threaded Lisp, subsequent requests would just be blocked until the SSE handler was done. That would certainly be a problem, but not the one you describe.
rg
On Mar 1, 2014, at 12:58 PM, Left Right olegsivokon@gmail.com wrote:
Don't forget that sockets are concurrent by design: in a simplest scenario, you'd allocate a thread per connection. Not a very efficient way of dealing with it, but at least it is easy to implement in a way that you don't run into deadlocks or other errors caused by multiple threads accessing shared state. But if you choose to use server events, you would have to be very careful to write re-entrant functions to serve the request, which is particularly difficult because Hunchentoot relies on a handful of global variables to function... you may easily run yourself into a situation where two functions try to write to the same output stream, even at the level that Unicode byte sequences become interleaved and the receiving side would fail with arcane low-level decoding errors (happened to me before).
On Sat, Mar 1, 2014 at 10:04 PM, Ron Garret ron@flownet.com wrote:
Personally I much prefer server-side events (SSE). It's a lot simpler than websockets. On the client side all you do is:
var source=new EventSource(URL); source.onmessage=function(event) { do_something_with(event.data); }
and on the server arrange for URL to have a content-type header of text/event-stream, and send lines of the form:
data: [your data] <newline><newline>
to the stream you obtain from calling (ht:send-headers). (Note: this stream is a binary stream so you have to encode strings to bytes and use write-sequence, or wrap it in a flexi-stream, but that's the only complication.)
rg
On Feb 28, 2014, at 1:40 PM, Left Right olegsivokon@gmail.com wrote:
Not exactly answering your question, but if you are looking for push functionality in browser, then WebSockets might be a better option. The reason server-sent events exist is by and large due to the handicapped nature of most popular web-development stack in use today, such as PHP interpreter that has to be started on every connection by an HTTP server, such as Apache httpd or ngnx. This means that traditional setup works in a stateless manner. This is unlike, say, most Java HTTP servers (Tomcat, JBoss etc) or Python (Twisted, Tornado), where the setup is normally stateful, meaning that you wouldn't need to restart the interpreter upon each request, instead, your server would persist the state until it is shut down. Hunchentoot belongs to the later category.
Now, because it's not really possible to persist a PHP session across multiple requests, a technique first known as long polling appeared. The operating principle was that the server, in response to an HTTP request would not close the connection immediately, instead it would keep sending the information, whenever the application state at the server would demand it. The receiving side (the browser) would listen to updates on this connection and interpret them as "pushes". Event stream is a refinement of this scheme.
WebSockets, on the other hand, are plain TCP sockets, which means that they don't require HTTP wrapping to function. I haven't had much experience with JavaScript WebSockets, but I used their analogy in Flash quite a bit. It was a relief not to depend on the bizarre rules of HTTP protocol and its encodings, headers and so on. So I would expect the same to hold for WebSockets.
Best,
Oleg
On Fri, Feb 28, 2014 at 11:09 PM, Faruk S. Can farukscan@gmail.com wrote:
I have read in w3schools about usage of server sent events in html5. it says:
Set the "Content-Type" header to "text/event-stream" Specify that the page should not cache Output the data to send (Always start with "data: ")
that is in echo line in php code as echo "data: The server time is: {$time}\n\n";
Flush the output data back to the web page
http://www.w3schools.com/html/html5_serversentevents.asp examples here are in php for server side. i am using hunchentoot on common lisp.
On Fri, Feb 28, 2014 at 10:27 PM, Faruk S. Can farukscan@gmail.com wrote:
I have another question about hunchentoot. Is it possible to use server sent events with hunchentoot, like other html5 improvements mentioned in w3schools-html5 such as app cache, local storage, session storage? as that one related to and depend on the server side support.