From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 7CD8D7EEF6 for ; Tue, 16 Jun 2015 19:50:32 +0200 (CEST) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of kennethadammiller@gmail.com) identity=pra; client-ip=209.85.214.173; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="kennethadammiller@gmail.com"; x-sender="kennethadammiller@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of kennethadammiller@gmail.com designates 209.85.214.173 as permitted sender) identity=mailfrom; client-ip=209.85.214.173; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="kennethadammiller@gmail.com"; x-sender="kennethadammiller@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-ob0-f173.google.com) identity=helo; client-ip=209.85.214.173; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="kennethadammiller@gmail.com"; x-sender="postmaster@mail-ob0-f173.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0DXAQBtYYBVm63WVdFbgkWBfgaDGMJkAiiBFAdMAQEBAQEBEgEBAQEBBgsLCSEuhBoIAQEBAwESEQQZARsdAQMBCwYDAgsNIAEJAgIhAQERAQUBHBkihVGCJgEDCgiZeJBrPjGLP4FrgnmLewoZJw1XhGIBAQEBAQEEAQEBAQEBFgEFDos2gk2BbksHgmgPgTYFk1+JZIFhgTOHEYg+gzuCERIjgQwJgi4fgW4iMYEDJIEgAQEF X-IPAS-Result: A0DXAQBtYYBVm63WVdFbgkWBfgaDGMJkAiiBFAdMAQEBAQEBEgEBAQEBBgsLCSEuhBoIAQEBAwESEQQZARsdAQMBCwYDAgsNIAEJAgIhAQERAQUBHBkihVGCJgEDCgiZeJBrPjGLP4FrgnmLewoZJw1XhGIBAQEBAQEEAQEBAQEBFgEFDos2gk2BbksHgmgPgTYFk1+JZIFhgTOHEYg+gzuCERIjgQwJgi4fgW4iMYEDJIEgAQEF X-IronPort-AV: E=Sophos;i="5.13,627,1427752800"; d="scan'208";a="136527967" Received: from mail-ob0-f173.google.com ([209.85.214.173]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 16 Jun 2015 19:50:30 +0200 Received: by obcej4 with SMTP id ej4so16792600obc.0 for ; Tue, 16 Jun 2015 10:50:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=uv2E0THGVz9xRc6e0gx0TSP+tm6bkpAIHKZXGftaECs=; b=xzcdS76JT3uRZ6tdfE/VKCbBrD8u3dr22izo3Ykb+7S8+iIgh/8RBi08GxOU8tQd6L PixIxIWQHBPea0LJ+b7CSW4caBhSZ8RgkWmUZdZfT5E/8VOopfWS3uxlAfwOgo7P4dix SNlmPdy2SNE8pF6liUtxdYD36kcH5mAMibRqdyxgzVmrLFUN3DWkYhvgCFFn5op93bQy llcRgu9kutaUpR5QZKh0YhNPvDm27tEiEOJ3VOM5ZrQZ4y1sJ7ReAGBcCTfKF6dOmUNO dmZOErZi1eICUL97AiFPQOMEcHRqdfbWGww15boO/+pMZDo+i36QbE+qQvm4SlYpwFPP 7wxA== MIME-Version: 1.0 X-Received: by 10.202.63.212 with SMTP id m203mr1147553oia.35.1434477029362; Tue, 16 Jun 2015 10:50:29 -0700 (PDT) Received: by 10.202.191.8 with HTTP; Tue, 16 Jun 2015 10:50:29 -0700 (PDT) In-Reply-To: References: Date: Tue, 16 Jun 2015 13:50:29 -0400 Message-ID: From: Kenneth Adam Miller Cc: caml users Content-Type: multipart/alternative; boundary=001a113d6cb8c614230518a63586 Subject: Re: [Caml-list] Async Server not executing --001a113d6cb8c614230518a63586 Content-Type: text/plain; charset=UTF-8 Ok, I have one last question - I've gotten my unit tests to succeed properly, but I'm concerned. At one point in the Pipe documentation, it talked about how writes a recvs would guarantee progress by returning early if they had something at all. I just need some kind of guarantee of the semantics of a send and recv, so that if I send a string of length 4, I don't receive multiple fragments. On Tue, Jun 16, 2015 at 11:48 AM, Kenneth Adam Miller < kennethadammiller@gmail.com> wrote: > Ah. Well I think I can incorporate from that what I can, but my unit tests > need to be reflective of the use case I have. I'm sending protobuf encoded > messages between two processes on one machine-whatever the size of the > message, that's the size that should be received on the other end (I've > read about the returning partial bytes, I can't decode a part of a proto > message, it has to be the right size). > > I can't use write_line, I'll have to find a way to delimit the messages > based on size. I think I'll just prepend every message with the size that > it should expect, and then read a integer off the stream and then that many > bytes. > > On Tue, Jun 16, 2015 at 11:41 AM, David House > wrote: > >> Ah, now I read your code in more detail I think I see why. >> >> Reader.contents on the server side will block until eof. The client side >> sends some stuff, but does not close the writer, so the server never sees >> eof. (Recall that sockets are not like files: it's possible to read all of >> the available data right now, but not reach eof.) >> >> Network protocols normally have some explicit "this is the end of one >> message" marker, like a newline or something similar. Then the server just >> reads chunks until it sees that marker, at which point it can put the >> message together and to something with it. >> >> For example, you could use Writer.write_line on the client side and >> Reader.read_line on the server side. >> >> On 16 June 2015 at 16:36, Kenneth Adam Miller < >> kennethadammiller@gmail.com> wrote: >> >>> So, now I can get server received if I add that into the callback, but >>> at "writing shutdown to server" I don't see response received or even >>> something for Eof. >>> >>> On Tue, Jun 16, 2015 at 11:09 AM, David House >>> wrote: >>> >>>> The first thing to try is to make sure that everything is getting >>>> flushed. For temporary debugging messages I strongly recommend just using >>>> [Core.Std.eprintf "\n%!"]. >>>> >>>> On 16 June 2015 at 16:03, Kenneth Adam Miller < >>>> kennethadammiller@gmail.com> wrote: >>>> >>>>> I'm having trouble with OCaml Async. I wrote a small server with it, >>>>> and right now I'm trying to unit test that server. Here's my code for the >>>>> server: >>>>> >>>>> >>>>> let _main ()= >>>>> print_endline "Server running"; >>>>> let handler = print_endline in >>>>> let socket = Tcp.on_port 5554 in >>>>> let server = Tcp.Server.create socket (fun addr r w -> >>>>> (Reader.contents r) >>| handler; (Writer.write w "got it")) in >>>>> server >>>>> >>>>> >>>>> >>>>> In my unit test code I have: >>>>> >>>>> let test_shutdown test_ctxt = Thread_safe.block_on_async_exn (fun () >>>>> -> ( >>>>> print_endline "test_shutdown"; >>>>> let server = Server._main () in >>>>> server >>= fun server -> >>>>> let where = Tcp.to_host_and_port "127.0.0.1" 5554 in >>>>> Tcp.connect where >>= fun s -> >>>>> let socket, r, w = s in >>>>> ignore (Writer.write w "kill"); >>>>> ignore (Writer.flushed w); >>>>> (Reader.recv r >>> function >>>>> | `Ok result -> print_endline ("writing shutdown to >>>>> server" ^ result) >>>>> | `Eof -> ()); >>>>> return () >>>>> )); () >>>>> >>>>> >>>>> >>>>> I see test_shutdown and Server running, but not sign of "writing >>>>> shutdown to server" or even "got it"; why isn't my server or even any of >>>>> the connection executing? >>>>> >>>> >>>> >>> >> > --001a113d6cb8c614230518a63586 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Ok, I have one last question - I've gotten my unit tes= ts to succeed properly, but I'm concerned.

At one po= int in the Pipe documentation, it talked about how writes a recvs would gua= rantee progress by returning early if they had something at all. I just nee= d some kind of guarantee of the semantics of a send and recv, so that if I = send a string of length 4, I don't receive multiple fragments.

On Tue, Jun 16= , 2015 at 11:48 AM, Kenneth Adam Miller <kennethadammiller@gmail= .com> wrote:
Ah. Well I think I can incorporate from that what I can, but my unit tes= ts need to be reflective of the use case I have. I'm sending protobuf e= ncoded messages between two processes on one machine-whatever the size of t= he message, that's the size that should be received on the other end (I= 've read about the returning partial bytes, I can't decode a part o= f a proto message, it has to be the right size).=C2=A0

I= can't use write_line, I'll have to find a way to delimit the messa= ges based on size. I think I'll just prepend every message with the siz= e that it should expect, and then read a integer off the stream and then th= at many bytes.

On Tue, Jun 16, 2015 at 11= :41 AM, David House <dhouse@janestreet.com> wrote:
Ah, now I read your code in m= ore detail I think I see why.

Reader.contents on the ser= ver side will block until eof. The client side sends some stuff, but does n= ot close the writer, so the server never sees eof. (Recall that sockets are= not like files: it's possible to read all of the available data right = now, but not reach eof.)

Network protocols normall= y have some explicit "this is the end of one message" marker, lik= e a newline or something similar. Then the server just reads chunks until i= t sees that marker, at which point it can put the message together and to s= omething with it.

For example, you could use Write= r.write_line on the client side and Reader.read_line on the server side.

On 16 June 2015 at 16:36, Kenneth Adam Miller <kennethadammill= er@gmail.com> wrote:
So, now I can get server received if I add that into the callbac= k, but at "writing shutdown to server" I don't see response r= eceived or even something for Eof.

On Tue, Jun 16, 2015 at 11:09 AM, David Ho= use <dhouse@janestreet.com> wrote:
The first thing to try is to make sure that= everything is getting flushed. For temporary debugging messages I strongly= recommend just using [Core.Std.eprintf "<message>\n%!"].

On = 16 June 2015 at 16:03, Kenneth Adam Miller <kennethadammiller@gm= ail.com> wrote:
I'm having trouble with OCaml Async. I wrote a small server with it, a= nd right now I'm trying to unit test that server. Here's my code fo= r the server:

let _main=C2=A0()=3D
=C2=A0 print_endline=C2=A0
"Server runnin= g";
=C2=A0 let ha= ndler=C2=A0
=3D=C2=A0print= _endline=C2=A0in
=C2=A0 = let socket=C2=A0
=3D=C2=A0= Tcp.on_port=C2=A05554= =C2=A0in
=C2=A0 let serv= er=C2=A0
=3D=C2=A0<= span style=3D"margin:0px;padding:0px;border:0px;vertical-align:baseline;col= or:rgb(102,0,102)">Tcp..create socket=C2= =A0(fun addr r w=C2=A0->
=C2=A0 =C2=A0 =C2= =A0=C2=A0
(Reader.contents r)=C2=A0>>|= =C2=A0handler;=C2=A0(Wr= iter.write w=C2=A0= "got it"))=C2=A0
in
= =C2=A0 server



In my unit test code I have:

= let test_shutdown test_ctxt=C2=A0=3D=C2=A0Thread_safe.block_on_async_exn=C2=A0(fun=C2=A0()=C2=A0->=C2=A0(&quo= t;test_shutdown";=C2=A0 =C2=A0 =C2=A0 let server=C2=A0=3D= =C2=A0Server._main=C2=A0()=C2=A0in>>= =3D=C2=A0fun server=C2=A0= ->
=C2=A0 =C2=A0 =C2=A0 let=C2=A0
where=C2=A0= =3D=C2=A0Tcp.to_host_and_port=C2=A0"127.0.0.1"=C2=A05554=C2=A0in
=C2=A0 =C2=A0 =C2=A0=C2=A0
.connect=C2=A0where=C2=A0>>=3D=C2=A0fun s=C2=A0->=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = let socket
,=C2=A0r= ,=C2=A0w=C2=A0=3D=C2=A0s=C2=A0in=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ignore=C2=A0
<= span style=3D"margin:0px;padding:0px;border:0px;vertical-align:baseline;col= or:rgb(102,102,0)">(
Writer.write w=C2=A0"ki= ll");
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 ignore=C2=A0
(Writer.flushed = w);
=C2=A0 =C2=A0 =C2= =A0 =C2=A0=C2=A0
(Read= er.recv r=C2=A0>>>
=C2=A0function
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0=C2=A0
|=C2=A0`Ok result -> =C2=A0print_endline ("writing shutdow= n to server" ^ result)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | `Eof=C2=A0->=C2=A0());
=C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0
return=C2=A0()
=C2=A0 =C2=A0=C2=A0
));
=C2=A0()
=


I see test_shutdown and Serve= r running, but not sign of "writing shutdown to server" or even &= quot;got it"; why isn't my server or even any of the connection ex= ecuting?





--001a113d6cb8c614230518a63586--