On Tue, Mar 3, 2015 at 2:39 PM, Nicolas Di Pietro <pote...@gmail.com> wrote:
> Hi Guido, > > Thank you for taking some time to answer this. > > 2015-03-03 6:05 GMT+01:00 Guido van Rossum <gu...@python.org>: > >> I'll try to give some hints on Nicolas's original question. I agree with >> Luciano that posting your source code would be helpful. >> > > I know, I will try to push something soon. > > >> I assume the serial port is a file descriptor. The big question is, does >> it support select()? If it doesn't, you'd be in a world of pain (you'd have >> to create a helper thread to read from the serial port). Assuming it does, >> I think that the device itself should be treated as a stream, not a >> datagram. And you should read up on the selectors module before trying >> this. Using this and some examples it should be possible to create a >> Transport that reads bytes from the serial port whenever the selector calls >> its handler, and sends them to a (stream style) Protocol. >> > > It sounds like it support it, I'm using the pyserial package, and, on the > posix implementation (at least), the port is read with select. The idea I > had was indeed to threat it as a stream of bytes, the datagram thing should > come later (that why I was talking of chaining the (transport, protocol) > pair, I don't know if this is doable, or/and a good idea, but I thought of > a generic transport/protocol to read/write the serial port in a generic and > reusable way, and then putting that into a another transport/protocol that > is specific, in my case is this pair is for zigbee/xbee, but if another > protocol over serial is to be implemented, this part only must be changed ) > Yes, that's a totally reasonable approach. > > I also assume you are speaking of "datagrams" because the semantics of the >> device connected to the serial port are that it sends packets of data >> consisting of multiple bytes and having a well-defined format. Your >> Transport will have to parse these, and beware that a single read may not >> get you all the bytes you want, *or* may return more bytes than you need -- >> you may end up needing a simple state machine for the parsing. Then once >> you have parsed a full packet you can call another callback function with >> the complete packet. That may be a different method on the same Protocol >> object, so you could have a single Protocol that in a sense processes both >> the stream aspect and the packet aspect of the data. (Incidentally this is >> how Twisted protocols tend to work.) >> > > You are right with my choice of word for "datagrams", that, and the fact > the protocol (network one, not in asyncio terms) is not connection > oriented, but your description fit well (in fact, I've already done that > for another protocol, with gevent, but I based my code on how twisted works > to do that), I wanted to stay close to the asyncio way about datagram to > have something that as the same "interface" to the user (sendto et all) > Sure. > My bet is that your code got too messy when you were trying to parse the >> data. The state machine idea may help here. >> > > My code was to messy because I tried to subclass things already in asyncio > but I guess I do not master the thing well enough to get somewhere since I > ended subclassing lots lots lots of things (when I stopped, I was > subclassing selector_events._SelectorDatagramTransport, > _UnixSelectorEventLoop, _UnixReadPipeTransport) and then realised I must be > completely wrong. That's why I was asking if someone had already managed to > implement a new transport that was not based on socket, I did not yet tried > to parse the data, the messier code is coming ;-) > Yeah, basically the code in asyncio is not meant to be subclassed. The leading underscores should have provided a warning. :-) > Good luck! >> > > Thanks ! > > >> --Guido >> >> > Have a nice day, > > Nicolas > You too! -- --Guido van Rossum (python.org/~guido)