Yaws 1.85 Released
Steve Vinoski - steve - October 20, 2009Today Klacke announced Yaws 1.85, mainly a bugfix release. You can find the list of changes and fixes at that link, but one addition in this release I wanted to point out was our new streamcontent_from_pid feature, which allows your server application code to temporarily take over the client connection socket from Yaws, thus allowing you to feed data directly to the socket without first passing it back through Yaws. Could be just the ticket for long-polling (Comet) applications, for example.
Prior to this release, the closest feature Yaws provided for this sort of operation was the streamcontent capability, which is still very useful in that it allows you to have an Erlang process deliver data back into Yaws, which in turn sends it in HTTP chunked transfer mode back to the client. For large file resources like video files or install tarballs, or for data sources where content arrives at your server in batches from a separate back-end source, or generally for resources whose sizes are not known up front, streamcontent is perfect because it lets you transfer the data back into Yaws in chunks, at your leisure and without having to copy all the data at once. Still, though, the data has to be sent back through Yaws, which converts it to HTTP chunks and writes it to the socket, plus in this case your only choice is chunked transfer.
With streamcontent_from_pid, you reply to the out/1 upcall from Yaws with the HTTP reply headers and with the following special return tuple:
{streamcontent_from_pid, MimeType, StreamPid}
This tells Yaws that you wish to have process StreamPid take over the client socket in order to send data of media type MimeType directly back to the client. Yaws uses MimeType to set the HTTP Content-Type header, and then after sending that and all the other HTTP headers back to the client, it turns control of the client socket over to StreamPid. The code running within StreamPid must handle the following messages from Yaws:
{ok, YawsPid}tellsStreamPidthat it can proceed with using the socket. The socket is present in the originalArgvariable passed to yourout/1function and can be retrieved viaArg#arg.clisock.{discard, YawsPid}tellsStreamPidthat it shouldn’t send any data on the socket, for example because the client request was an HTTPHEADrequest and so there is no response body.
To send data, your code can choose to send chunked data or non-chunked data. To send the latter, first make sure you set the HTTP Content-Length header in your initial reply to Yaws, and then once Yaws calls back to your StreamPid process, just call:
yaws_api:stream_process_deliver(Socket, IoList)
or for chunked data:
yaws_api:stream_process_deliver_chunk(Socket, IoList)
where for both cases Socket is the client socket from the Arg and IoList is an iolist containing the data to be sent. The first case just calls gen_tcp:send and is there primarily so we can maybe someday add SSL socket support for this feature. For the second case Yaws will format the data for you for chunked transfer. Unless a Content-Length header is set, Yaws will assume you want chunked transfer and will set the Transfer-Encoding header appropriately. If you’re sending chunked data, make sure you send your final chunk using the following function:
yaws_api:stream_process_deliver_final_chunk(Socket, IoList)
so that Yaws knows to send the termination chunk to inform the client of the end of the transfer.
You can continue to call these functions from your StreamPid as frequently as you need to in order to deliver your data to the client. Meanwhile, the Yaws process that handed you the socket will just sit back and wait for you (non-blocking, of course). When you’re completely finished sending, just call:
yaws_api:stream_process_end(Socket, YawsPid)
to end the transmission and give control of the socket back to Yaws. At that point, your StreamPid can exit if it wishes.
If you try out this feature, be sure to send feedback either to me or to the Yaws mailing list.
Categories: Blogs Steve Vinoski
Erlang on Twitter
» kirikaza (Kirikaza): RT @LogaRhythm: “If you don’t perform experiments before designing a new system, your entire new system will be an experiment” Mike William…
» digitalBush (Josh Bush): Lost a couple of hours figuring this one out “erl -pa ebin” needs to be “erl -pa ../{app}/ebin” if you want code:priv_dir/1 to work. #erlang
» buzzamzn (アマゾンに関する情報を発信中♪): 楽天市場:Learn You Some Erlang for Great Good!-【電子ブック版】 http://t.co/Ot4LPkbgw7 #amazon #アマゾン #相互フォロー
» rvalyi (Raphaël Valyi): @matrixise j’avais bidouillé un peu de Erlang récemment, pas trop mon truc, mais là avec la Syntaxe de Ruby/team Plataformatec, ça motive…
» imarshut (MarsHut): #Calling #Ruby #Functions http://t.co/79x1tBhoc9 ErlPort (library to connect Erlang to Ruby) 1.0.0alpha released
» fogelmania (Raphael Fogel): Alexander Fok, System Architect @ooVoo will have a talk at the #Erlang track of #DevconTLV http://t.co/GRA0Q2zny7 Welcone to TLV, Alexander!
» robertoaloi (Roberto Aloi): @mariofusco Wouldn’t it be simpler switching to #erlang? ;-)
» guillaumepotier (Guillaume POTIER): @francois2metz du coup tu vas recruter une armée de full stack ? Tu ne veux pas qques spécialistes Erlang ?
» oker1 (Zsolt Takács): Mochi Labs - statebox, an eventually consistent data model for Erlang (and Riak) http://t.co/tWhlCDGtBz
» HumphreyStamper (Humphrey Stamper): Wage reduction the trim erlang only http://t.co/6qTcEyl3Sk tactician in contemplation of organism leap http://t.co/1CWvIAjBNU
Statistics
Number of aggregated posts: 10657
Most recent article: June 11, 2013
Latest comments
» Moraru on This is Why You Spent All that Time Learning to Program: It is true that computer science was a pain in the back at time that i’ve had to learn it…
» Commercial hand dryers on Couchbase Meetup at new HQ: Buy online from here where you will get so much of variety in Commercial hand dryers for people. If you…
» Fort McMurray Homes on Motivated Reasoning and Erlang vs Python vs Node: I don’t really understand why this post is motivational? I don’t even see a post, just a title. Fort McMurray…