<div dir="ltr">Re allocations: Thanks for the detailed explanation. The writes will be small (user code stores what to write in a fixed buffer < 1MTU) so everything looks good on that front.</div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Oct 3, 2016 at 9:56 PM, Andy Green <span dir="ltr"><<a href="mailto:andy@warmcat.com" target="_blank">andy@warmcat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Mon, 2016-10-03 at 19:33 -0700, Chris Evans wrote:<br>
> Thanks for the quick reply,<br>
><br>
> Re allocations: Heap allocations during the initial setup/handshake<br>
> are fine so long as there are no allocations per query. (The<br>
> connection will be long-running but serve 10,000K queries/sec)<br>
<br>
</span>Whether there are allocations handling what the connection is doing is<br>
mainly up to the user code.<br>
<br>
lws uses poll() type semantics by default, and waits to hear if it is<br>
able to send something more on the connection by waiting for POLLOUT.<br>
<br>
When that arrives, it's a sign we can send more on the connection, but<br>
actually it gives no clue about how much the kernel will accept, just<br>
that it will accept something.<br>
<br>
If what you send per POLLOUT is modest and is always accepted (it seems<br>
on Linux when I have studied it, < 1 MTU is always acceptable if<br>
POLLOUT has come, but it's not guaranteed anywhere AFAIK) then there<br>
won't be any malloc()s once the ws connection is established.<br>
<br>
However in theory it's open to the OS to signal POLLOUT and then accept<br>
one byte.  To handle that kind of fatal situation, lws will<br>
automatically malloc up a buffer for the remainder and drain it<br>
autonomously in an emergency.  That lets you always use transient stack<br>
buffers to create packets safely.<br>
<br>
However if you just throw megabytes at lws_write() in one go, which<br>
will certainly not be accepted by send(), it will be forced to always<br>
use this "emergency mechanism" and it'll be expensive mallocs and<br>
memcpys every time.<br>
<br>
So you must send in chunks sizes that the kernel will almost always<br>
accept in send() after a POLLOUT if you want to more or less eliminate<br>
mallocs.  If you expect to send packets < 1MTU, I guess nothing to do.<br>
 But if you will send larger things, you will have to break them up<br>
into frames and use ws FIN to manage the larger message.  Lws supports<br>
everything needed to do that.<br>
<span class=""><br>
> Re echo-server: `libwebsockets-test-echo` seems to behave how I would<br>
> expect an "echo server" to. i.e. if I connect to and query it with<br>
> iocat (<a href="https://www.npmjs.com/package/iocat" rel="noreferrer" target="_blank">https://www.npmjs.com/<wbr>package/iocat</a> -- tool like netcat but<br>
> speaking the websockets protocol), it echos back my query. (Though I<br>
> understand if it wasn't built for performance testing)<br>
<br>
</span>OK.<br>
<span class=""><br>
> I've attached the pcap output from `tcpdump -i lo0 -c 200 -w<br>
> output.pcap src port 6666 or dst port 6666` (running the same<br>
> client/server commands as before). I'm not too familiar with<br>
> networking/tcpdump/wireshark but it looks like the handshake goes<br>
> down, a few "Test Message"s are echoed, and then the server resets<br>
> the connection. <br>
><br>
> I also added print statements to print the `lws_callback_reason` in<br>
> the callback (First 250 lines of output attached as stdout.txt) which<br>
> seem to confirm the reset/reconnects from the server's point of view.<br>
<br>
</span>I can see the log, but I will have to study it tonight or tomorrow.<br>
<span class="HOEnZb"><font color="#888888"><br>
-Andy<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
> Thanks again for the help,<br>
>   Chris<br>
><br>
> On Mon, Oct 3, 2016 at 6:11 PM, Andy Green <<a href="mailto:andy@warmcat.com">andy@warmcat.com</a>> wrote:<br>
> > On Mon, 2016-10-03 at 14:22 -0700, Chris Evans wrote:<br>
> > > Howdy,<br>
> > ><br>
> > > I'm looking to set up a simple query/response websockets-protocol<br>
> > > server in a high-throughput environment: Serving a machine<br>
> > learning<br>
> > > model behind Amazon's new Application Load Balancer (which<br>
> > > necessitates speaking the WebSockets protocol) . `libwebsockets`<br>
> > > seems a good choice as 1) I'm not looking to build a full web<br>
> > app,<br>
> > > and 2) It doesn't allocate per query (is that correct?)<br>
> ><br>
> > Depends on what you do while processing the query... by default it<br>
> > allocates some space at the connection and ws protocol negotiation<br>
> > and<br>
> > doesn't need the heap otherwise.<br>
> ><br>
> > > But I've run into issues when stress testing with the `tcpkali`<br>
> > tool<br>
> > > (<a href="https://github.com/machinezone/tcpkali" rel="noreferrer" target="_blank">https://github.com/<wbr>machinezone/tcpkali</a>), even against the<br>
> > provided<br>
> > > test-echo server; `tcpkali` is unable to make a connection (I've<br>
> > had<br>
> > > success with tcpkali in other contexts):<br>
> ><br>
> > The echo server is just designed to talk to himself in client mode.<br>
> >  When I wrote it, I didn't realize "echo" has a bigger meaning for<br>
> > people looking to make performance measurements.  So it may not do<br>
> > what<br>
> > you want for that.<br>
> ><br>
> > I tried to install tcpkali but it's not packaged in Fedora.<br>
> ><br>
> > > ```<br>
> > > chrisevans@CHRIS-EVANS:bin ((detached from v2.0.0))$<br>
> > ./libwebsockets-<br>
> > > test-echo --port 6666<br>
> > > [2016/09/03 13:44:51:3543] NOTICE: Built to support client<br>
> > operations<br>
> > > [2016/09/03 13:44:51:3543] NOTICE: Built to support server<br>
> > operations<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>: libwebsockets<br>
> > test<br>
> > > server echo - license LGPL2.1+SLE<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>: (C) Copyright<br>
> > > 2010-2016 Andy Green <<a href="mailto:andy@warmcat.com">andy@warmcat.com</a>><br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>: Running in<br>
> > server<br>
> > > mode<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>: Initial<br>
> > logging<br>
> > > level 7<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>: Libwebsockets<br>
> > > version: 2.0.0 chrisevans@CHRIS-EVANS-v2.0.0<br>
> ><br>
> > You should use v2.0-stable branch or master, there are many fixes<br>
> > since<br>
> > v2.0, although I don't think that's the problem.<br>
> ><br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>: IPV6 not<br>
> > compiled<br>
> > > in<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>: libev support<br>
> > not<br>
> > > compiled in<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>: libuv support<br>
> > not<br>
> > > compiled in<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>:  Threads: 1<br>
> > each<br>
> > > 10240 fds<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>:  mem: platform<br>
> > fd<br>
> > > map: 81920 bytes<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>:  Compiled with<br>
> > > OpenSSL support<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>:  SSL disabled:<br>
> > no<br>
> > > LWS_SERVER_OPTION_DO_SSL_<wbr>GLOBAL_INIT<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>: Creating Vhost<br>
> > > 'default' port 6666, 1 protocols<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>:  Listening on<br>
> > port<br>
> > > 6666<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>:  mem: per-<br>
> > conn:   <br>
> > >       488 bytes + protocol rx buf<br>
> > > Oct  3 13:44:51 CHRIS-EVANS lwsts[14575] <Notice>: <br>
> > > canonical_hostname = CHRIS-EVANS<br>
> > > ```<br>
> > ><br>
> > > ```<br>
> > > chrisevans@CHRIS-EVANS:Clients (test_suite)$ tcpkali -m "Test<br>
> > > Message" -c 1 --ws  <a href="http://127.0.0.1:6666" rel="noreferrer" target="_blank">127.0.0.1:6666</a><br>
> > > Destination: [127.0.0.1]:6666<br>
> > > Interface lo0 address [127.0.0.1]:0<br>
> > > Interface lo0 address [169.254.169.254]:0<br>
> > > Using interface lo0 to connect to [127.0.0.1]:6666<br>
> > > Could not create 1 connection in allotted time (10s)<br>
> > > ```<br>
> > > Any help would be greatly appreciated!<br>
> ><br>
> > This doesn't give me anything to go on... if you can tcpdump what's<br>
> > happening on the port, and / or increase the logging (eg -d 65535)<br>
> > at<br>
> > the echo server, we might get a clue.<br>
> ><br>
> > -Andy<br>
> ><br>
> ><br>
> > >  <br>
> > > -Chris<br>
> > > ______________________________<wbr>_________________<br>
> > > Libwebsockets mailing list<br>
> > > <a href="mailto:Libwebsockets@ml.libwebsockets.org">Libwebsockets@ml.<wbr>libwebsockets.org</a><br>
> > > <a href="http://libwebsockets.org/mailman/listinfo/libwebsockets" rel="noreferrer" target="_blank">http://libwebsockets.org/<wbr>mailman/listinfo/libwebsockets</a><br>
> ><br>
><br>
</div></div></blockquote></div><br></div>