/
stream.yaws
65 lines (37 loc) · 2.34 KB
/
stream.yaws
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<erl>
box(Str) ->
{'div',[{class,"box"}],
{pre,[],yaws_api:htmlize(Str)}}.
tbox(T) ->
box(lists:flatten(io_lib:format("~p",[T]))).
ssi(File) ->
{'div',[{class,"box"}],
{pre,[],
{ssi, File,[],[]}}}.
out(A) ->
[{ssi, "TAB.inc", "%%",[{"stream", "choosen"}]},
{ehtml,
{'div',[{id, "entry"}],
[{h1, [], "Streaming data to the client"},
{p, [],
"Sometimes we want to stream data to the client. Maybe we don't know or cannot compute the size of the data. Regardless of what, we do not want to keep all data in memory until it's shipped to the client. We want to use chunked encodings, and simply send data in chunks to the client. This is performed in steps. First the out/1 return value:"},
box(" {streamcontent, MimeType, FirstChunk}"),
{p,[], ["Is returned from the out/1 function"
" This make the erlang process processing that particular page go into a receive loop, waiting for more data. Somehow, another process in the erlang system, must then deliver data to the waiting/receiving erlang processs. There are two asyncronous API functions that can be used to deliver that data."]},
box("yaws_api:stream_chunk_deliver(YawsPid, Data)"),
{p, [], "and"},
box("yaws_api:stream_chunk_end(YawsPid)"),
{p, [], "The YawsPid argument is the process identifier of the original yaws process processing the page, i.e. self(), in the .yaws file."},
{p, [],"Maybe this gets clear with a programing example, let's use a process reading a random number of bytes from /dev/urandom as the source of the data"},
ssi("urandom.yaws"),
{p, [],
["The above slightly bizzare code can be executed ",
{a, [{href, "urandom.yaws"}], "Here"},
" The code creates a process which reads a random amount of bytes from /dev/urandom and sends them to the client, piece by piece. "]},
{p,[], "There is also a version of the API code which delivers the data in a blocking fashion. Whenever the producer of the stream is faster than the consumer, that is the WWW client, we must use a syncronous version of the code. The api function is called:"},
box("yaws_api:stream_chunk_deliver_blocking(YawsPid, Data)")
]}},
{ssi, "END2",[],[]}
].
</erl>
</html>