[Twisted-Python] composition VS. inheritance
meejah
meejah at meejah.ca
Tue Jun 30 13:26:05 MDT 2020
As others have pointed out, you're stuck with a certain amount of
inheritance to use Twisted. However, this can be fairly minimal. For new
code trying to follow a "sans-io" approach is good too. The go-to
example of this for Twisted is Hyper/H2 and its integration into Twisted
Web for HTTP2 support.
For nearly every protocol you have similar pieces: framing, parsing, a
state-machine and some way to send and receive bytes ("do I/O").
Keeping these separate has a lot of value. The only part of the above
where you "need to use inheritance" is the I/O part ("because
Twisted"). You don't even technically need to "subclass" because you
could just implement the right interfaces .. but in practice, you
subclass Protocol.
However, you can keep this looking like "just a shim":
class Shim(Protocol):
def connectionMade(self):
# self.transport is valid now
self._framing.startup()
def dataReceived(self, data):
self._framing.feed_data(data)
def connectionLost(self, reason):
self._framing.shutdown()
(This is just one sort of suggestion / psuedo-code here). So your
"framing" object collects bytes and when it has "a message" it can pass
it along to the parser which validates it and turns it into a thing that
it can pass along to the state-machine. All the state-machine needs is
some way to indicate "I have messages to send" (e.g. a callback?) which
is turned into bytes and you call "shim_instance.transport.write()" with
those bytes.
So all those "other" pieces can be written without inheritance. At least
the parser and serializer can probably just be functions.
I recently wrote a relatively simple protocol to try this "sans-io" style
and was happy to start with the state-machine (using Automat). This
forced some good decisions. Then I worked outwards to the "more boring"
bits (framing and serialization/parsing).
(Hmm, this should almost just be a blog-post maybe ;)
--
meejah
More information about the Twisted-Python
mailing list