Architecture: Asynchronous send requests ...

Posted on
  • When implementing a new network component for a new board (eg. ESP8266), we have to create a function that is mapped to the JsNetwork send function. This is a function with the following signature:

    int send(struct JsNetwork *net, int sckt, const void *buf, size_t len)

    What I feel I need to know are the semantics and contract for this function.

    What I sense is that, in its simplest mode, it is supposed to send len bytes of data starting at the memory pointer supplied by buf through the socket identified by sckt. It should return the number of bytes actually sent, 0 if no bytes were sent and -1 if there was an error.

    Unfortunately for some devices such as the ESP8266, this semantics needs further consideration. In the ESP8266 the correspond function to transmit data is called espconn_send. However, since nothing in ESP8266 is blocking, this call takes a buffer of data and then will eventually transmit it. When the transmission has completed, a registered call-back function is invoked to let us know that the data has been sent.

    Now ... let us try and map this to the apparent Espruino architecture. A naive implementation of the Espruino send() would be to simply call espconn_send() however what should we then return? If we return the length of data that send() was provided, then we are semantically declaring that all the data was transmitted which isn't the case. In fact, it appears that immediately following a successful send() using HTTP, we then close the socket.

    The next possible design thought is that when send() is called, we do invoke espconn_send() but return 0 ... indicating that NO data has been transmitted. The assumption here is that send() will continue to be invoked over and over. The ESP8266 layer could be watching for the previous send to complete and, when it does, we return that the data was sent. This may work, but makes a broad assumption. It assumes that when send() is called with some data and gets a return of 0 ... it will continually call with the SAME data to be sent over and over again ... it isn't clear in the semantics if this is correct or not.

    Another open question is the buffer passed into the send() call. Should the content be copied from the request or can we assume that the memory pointer is "good" and "stable" until the data has actually been transmitted at some time in the future. If we can't assume that, then we have the unfortunate circumstance of having to duplicate the memory buffer to hold a copy while we transmit.

    As we see ... we are starting to ask complex semantic questions which weren't immediately obvious from such an innocuous looking function such as send().

    Neil

  • It's exactly like the situation with connect. If it makes more sense, think of the description as:

    Start to send len bytes from buf on socket number sckt. Return the number of bytes that have been accepted, 0 if busy, or -1 if there was an error

    This is pretty much what happens on an OS anyway, it's not like the computer sends that packet over the network and then returns - it goes into a buffer (and it doesn't expect that the buffer you passed to send hangs around).

    And yes, the data is lost afterwards as the array is stored on the stack - if the ESP8266's send function needs the data to stay around, you'll have to allocate your own buffer for it.

    It's worth looking at socketserver.c though - it should be pretty obvious how net-> functions get used in there.

  • @Gordon
    As always ... awesome answers. Based on what you've said, I think I can make some tests tonight. The answers for connect() were perfect.

    In a lot of your answers, you have invited me to go look at code ... and being pointed to the correct code is GREAT ... however ... when you say something should be obvious, you are over assuming my skills. I have and can lay my hands on ESP8266 skills as needed but Espruino internals are a "grind". That is definitely NOT to say that they are poor in any way ... just a lot of stuff that I think is all locked in your head. Without your responses on the forum, this port would be dead or dramatically further back than where it is.

    Neil

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Architecture: Asynchronous send requests ...

Posted by Avatar for Kolban @Kolban

Actions