From: Tobias O. <tob...@gm...> - 2007-02-11 20:22:24
Attachments:
yaws_server.erl.patch
|
I'm experimenting with Yaws and the "Comet Pattern", which is about sending real asynchronous stuff to the browser. A browser portable way is i.e. having a hidden IFRAME which receives MIME type text/html with content pieces of JS script tags which in turn manipulate the main HTML DOM. Browsers will eval JS tags "as they arrive" (incremental rendering). see for example: http://ajaxian.com/archives/iframe-script-tags-portable-comet http://ajaxify.com/run/streaming/xmlHttpRequest/iframe/scriptTags/ and description of what I did below. It's whats called "forever frame" in the following http://alex.dojotoolkit.org/wp-content/LowLatencyData.pdf versus the "long poll" technique. -- Unfortunately, there seems to be a hard-coded timeout of 30s in yaws_server.erl for streaming content. I've attached a patch (for yaws_server.erl as it comes with Yaws 1.68) which allows out/1 in Yaws to produce 2 new return values {streamcontent_with_timeout, MimeType, FirstChunk, TimeOut} {streamcontent_with_size_and_timeout, Sz, MimeType, FirstChunk, TimeOut} which enables the user to set the timeout for streaming content, including setting the TimeOut = infinity. -- The patch seems to work, but I'm a total Erlang newbie .. so if someone likes to use it, please QA it .. (in particular, I've not used/tested the streamcontent_with_size_and_timeout stuff .. just extended it for symmetry reasons). Tobias ============ Details. The content I produce in Yaws for the IFRAME contains only one <erl></erl> piece which subscribes the Yaws worker process to a registered (named) process P, and returns {streamcontent, "text/html", "<html><body>"}. Then, P will send JS script tags to all subscriber Yaws streaming processes using yaws_api:stream_chunk_deliver(..., "<script type="text/javascript">window.parent.onData(5);</script>"). -- Problem is, when P does not send anything for some time, the Yaws streaming worker dies with =ERROR REPORT==== 11-Feb-2007::15:59:45 === Yaws process died: {stream_timeout,[{yaws_server,stream_loop_send,3}, {yaws_server,aloop,3}, {yaws_server,acceptor0,2}, {proc_lib,init_p,5}]} -- I've looked for "stream_timeout", seems to be produced in fun stream_loop_send(Priv, CliSock, FlushStatus) -> TimeOut = case FlushStatus of flushed -> 30000; unflushed -> 300 end, receive ... of yaws_server.erl, which seems to hit the hardcoded timeout of 30s. -- I've verified, that after hacking above line "flushed -> 30000" for "flushed -> 120000" and recompiling yaws_server.erl, both Firefox 2 and IE 7 will not timeout by themselfes, but still receive asynchronous JS tags via the IFRAME even after 110s inactivity. -- With the attached patch, one is able to set the timeout {streamcontent_with_timeout, "text/html", "<html><body>", infinity}. from the .yaws page and both Firefox/IE will receive tags "forever". I've tested IE7 for a waiting time of 15min between tags sent. No problem, IE itself does not timeout. -- |
From: Roberto S. <rs...@gm...> - 2007-02-12 02:38:32
|
I also experimented with comet pattern, and for iframe transport type, If I remember propperly, I sent after each 25 seconds a keep alive message to the browser, to prevent the 30 second timeout and to detect a disconnected browser, so I can kill that yaws worker process. On 2/11/07, Tobias Oberstein <tob...@gm...> wrote: > > I'm experimenting with Yaws and the "Comet Pattern", which is about > sending real asynchronous stuff to the browser. > > A browser portable way is i.e. having a hidden IFRAME which receives > MIME type text/html with content pieces of JS script tags which in > turn manipulate the main HTML DOM. Browsers will eval JS tags "as they > arrive" (incremental rendering). > > see for example: > > http://ajaxian.com/archives/iframe-script-tags-portable-comet > http://ajaxify.com/run/streaming/xmlHttpRequest/iframe/scriptTags/ > > and description of what I did below. > > It's whats called "forever frame" in the following > > http://alex.dojotoolkit.org/wp-content/LowLatencyData.pdf > > versus the "long poll" technique. > > -- > > Unfortunately, there seems to be a hard-coded timeout of 30s in > yaws_server.erl for streaming content. > > I've attached a patch (for yaws_server.erl as it comes with Yaws 1.68) > which allows > > out/1 > > in Yaws to produce 2 new return values > > {streamcontent_with_timeout, MimeType, FirstChunk, TimeOut} > {streamcontent_with_size_and_timeout, Sz, MimeType, FirstChunk, TimeOut} > > which enables the user to set the timeout for streaming content, > including setting the TimeOut = infinity. > > -- > > The patch seems to work, but I'm a total Erlang newbie .. so if someone > likes to use it, please QA it .. (in particular, I've not used/tested > the streamcontent_with_size_and_timeout stuff .. just extended it for > symmetry reasons). > > Tobias > > > > ============ > > Details. > > The content I produce in Yaws for the IFRAME contains only one > <erl></erl> piece which subscribes the Yaws worker process to a > registered (named) process P, and returns > > {streamcontent, "text/html", "<html><body>"}. > > Then, P will send JS script tags to all subscriber Yaws streaming > processes using > > yaws_api:stream_chunk_deliver(..., "<script > type="text/javascript">window.parent.onData(5);</script>"). > > -- > > Problem is, when P does not send anything for some time, the Yaws > streaming worker dies with > > =ERROR REPORT==== 11-Feb-2007::15:59:45 === > Yaws process died: {stream_timeout,[{yaws_server,stream_loop_send,3}, > {yaws_server,aloop,3}, > {yaws_server,acceptor0,2}, > {proc_lib,init_p,5}]} > > -- > > I've looked for "stream_timeout", seems to be produced in fun > > stream_loop_send(Priv, CliSock, FlushStatus) -> > TimeOut = case FlushStatus of > flushed -> 30000; > unflushed -> 300 > end, > receive > ... > of yaws_server.erl, which seems to hit the hardcoded timeout of 30s. > > -- > > I've verified, that after hacking above line > > "flushed -> 30000" > > for > > "flushed -> 120000" > > and recompiling yaws_server.erl, both Firefox 2 and IE 7 will > not timeout by themselfes, but still receive asynchronous JS tags > via the IFRAME even after 110s inactivity. > > -- > > With the attached patch, one is able to set the timeout > > {streamcontent_with_timeout, "text/html", "<html><body>", infinity}. > > from the .yaws page and both Firefox/IE will receive tags "forever". > > I've tested IE7 for a waiting time of 15min between tags sent. No > problem, IE itself does not timeout. > > -- > > > > --- yaws_server.erl.original Sun Feb 11 16:28:03 2007 > +++ yaws_server.erl Sun Feb 11 18:02:33 2007 > @@ -1906,13 +1906,25 @@ > accumulate_content(FirstChunk), > Priv = deliver_accumulated(Arg, CliSock, > decide, undefined, stream), > - stream_loop_send(Priv, CliSock); > + stream_loop_send(Priv, CliSock, 30000); > + {streamcontent_with_timeout, MimeType, FirstChunk, TimeOut} -> > + yaws:outh_set_content_type(MimeType), > + accumulate_content(FirstChunk), > + Priv = deliver_accumulated(Arg, CliSock, > + decide, undefined, stream), > + stream_loop_send(Priv, CliSock, TimeOut); > {streamcontent_with_size, Sz, MimeType, FirstChunk} -> > yaws:outh_set_content_type(MimeType), > accumulate_content(FirstChunk), > Priv = deliver_accumulated(Arg, CliSock, > decide, Sz, stream), > - stream_loop_send(Priv, CliSock); > + stream_loop_send(Priv, CliSock, 30000); > + {streamcontent_with_size_and_timeout, Sz, MimeType, FirstChunk, > TimeOut} -> > + yaws:outh_set_content_type(MimeType), > + accumulate_content(FirstChunk), > + Priv = deliver_accumulated(Arg, CliSock, > + decide, Sz, stream), > + stream_loop_send(Priv, CliSock, TimeOut); > _ -> > DeliverCont(Arg) > end. > @@ -1981,31 +1993,31 @@ > finish_up_dyn_file(ARG, CliSock). > > > -stream_loop_send(Priv, CliSock) -> > - stream_loop_send(Priv, CliSock, unflushed). > +stream_loop_send(Priv, CliSock, TimeOut) -> > + stream_loop_send(Priv, CliSock, TimeOut, unflushed). > > -stream_loop_send(Priv, CliSock, FlushStatus) -> > - TimeOut = case FlushStatus of > - flushed -> 30000; > +stream_loop_send(Priv, CliSock, TimeOut, FlushStatus) -> > + ThisTimeOut = case FlushStatus of > + flushed -> TimeOut; > unflushed -> 300 > end, > receive > {streamcontent, Cont} -> > P = send_streamcontent_chunk(Priv, CliSock, Cont), > - stream_loop_send(P, CliSock, unflushed) ; > + stream_loop_send(P, CliSock, TimeOut, unflushed) ; > {streamcontent_with_ack, From, Cont} -> % acknowledge after send > P = send_streamcontent_chunk(Priv, CliSock, Cont), > From ! {self(), streamcontent_ack}, > - stream_loop_send(P, CliSock, unflushed) ; > + stream_loop_send(P, CliSock, TimeOut, unflushed) ; > endofstreamcontent -> > end_streaming(Priv, CliSock) > - after TimeOut -> > + after ThisTimeOut -> > case FlushStatus of > flushed -> > erlang:fault(stream_timeout); > unflushed -> > P = sync_streamcontent(Priv, CliSock), > - stream_loop_send(P, CliSock, flushed) > + stream_loop_send(P, CliSock, TimeOut, flushed) > end > end. > > @@ -2237,6 +2249,11 @@ > yaws:outh_set_content_type(MimeType), > {streamcontent, MimeType, First}; > > +handle_out_reply({streamcontent_with_timeout, MimeType, First, TimeOut}, > + _LineNo,_YawsFile, _UT, _A) -> > + yaws:outh_set_content_type(MimeType), > + {streamcontent_with_timeout, MimeType, First, TimeOut}; > + > handle_out_reply(Res = {page, _Page}, > _LineNo,_YawsFile, _UT, _A) -> > Res; > @@ -2246,6 +2263,11 @@ > yaws:outh_set_content_type(MimeType), > {streamcontent_with_size, Sz, MimeType, First}; > > +handle_out_reply({streamcontent_with_size_and_timeout, Sz, MimeType, > First, TimeOut}, > + _LineNo,_YawsFile, _UT, _A) -> > + yaws:outh_set_content_type(MimeType), > + {streamcontent_with_size_and_timeout, Sz, MimeType, First, TimeOut}; > + > handle_out_reply({header, H}, _LineNo, _YawsFile, _UT, _A) -> > yaws:accumulate_header(H); > > > ------------------------------------------------------------------------- > Using Tomcat but need to do more? Need to support web services, security? > Get stuff done quickly with pre-integrated technology to make your job > easier. > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 > _______________________________________________ > Erlyaws-list mailing list > Erl...@li... > https://lists.sourceforge.net/lists/listinfo/erlyaws-list > > -- Roberto Saccon |
From: Christian S <ch...@gm...> - 2007-02-12 09:28:12
|
Is the thirty second timeout documented? I recall finding out by reading source code when my connections mysteriously died. On 2/12/07, Tobias Oberstein <tob...@gm...> wrote: > > I set a timer to go off before thirty sec of inactivity. Then send a > > 'noop' message. > > Well, ok. Thats a workaround. > > > > > In my case that noop updated the ui to reflect chat inactivity rather > > than silent failure. So it was not really a noop. > > > > I can see that it might be useful to sent some heartbeat at least every > 30-120s anyway in many scenarios. > > Also, I just checked Opera 9 .. and that beast _does_ timeout < 5min > on IFRAMEs in contrast to IE 7 and Firefox 2 at least. > > Tobias > |
From: Tobias O. <tob...@gm...> - 2007-02-13 21:17:57
|
> Is the thirty second timeout documented? I recall finding out by > reading source code when my connections mysteriously died. I saw the "stream_timeout" from the console when running Yaws in interactive mode and grepped the sources .. The yaws.pdf does not seem to mention it .. Tobias |