I had to change it to make not weird, because I found that because writer.write wasn't sending the Eof like you said, and it wasn't causally correct so my code was hanging. I found that out when I got it working yesterday. My tests all run normally now! Thank you so so much. On Wed, Jun 17, 2015 at 4:09 AM, David House wrote: > Right, length-prefixing is another common trick. > > In fact, this is exactly what Writer.send does. Your code at the moment is > a little weird because it uses Reader.recv, whose documentation says "[recv > t] returns a string that was written with Writer.send", but you're not > using Writer.send. I think if you use those pairs of things then you get > the semantics you want. > > More generally, async has good support for reading chunks of data, which > might contain partial messages, and then putting those chunks together to > form full messages. See Unpack_sequence in async_extra, which works with > Unpack_buffer in core_kernel. > > On 16 June 2015 at 18:50, Kenneth Adam Miller > wrote: > >> 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? >>>>>>> >>>>>> >>>>>> >>>>> >>>> >>> >> >