Opened 6 years ago

Last modified 4 years ago

#4700 enhancement new

make it easier to proxy things (specifically transports and protocols)

Reported by: Glyph Owned by:
Priority: normal Milestone:
Component: core Keywords:
Cc: acapnotic Branch:


As per #4699, without ClientFactory.clientConnectionLost, it's tricky to write a reconnecting client factory with endpoints because you have to write a factory which wraps its protocol to catch connectionLost, and doing that is tricky.

I think that the only really confusing issue is that the proxy needs to accurately relay whether or not its wrapped protocol provides IHalfCloseableProtocol or not, but whatever the confusion is, there should be one right way to write a dynamic proxy that just overrides a few methods, so that implementors don't need to be concerned with this sort of thing.

Specifically in the case of transports and protocols, it may also be helpful to dis-intermediate the proxy as much as possible, so that the implementor doesn't need to worry about using a proxy to catch one method slowing down every other possible method. But again, optimizing this is very confusing and hard to get really right, so there should be one central implementation of it.

Change History (7)

comment:1 Changed 6 years ago by <automation>

Owner: Glyph deleted

comment:2 Changed 4 years ago by acapnotic

Cc: acapnotic added

comment:3 Changed 4 years ago by acapnotic

One implementation is endpoints._WrappingProtocol, one is underway for #4735, what other implementations are there to draw from, consider use cases for, and ultimately replace with this common implementation?

  • t.protocols.policies (and various subclasses)
  • conch.ssh.session

comment:4 Changed 4 years ago by acapnotic

and, do direct me elsewhere if this isn't the right venue for this story, but the sort of use case we're handling here, i.e. "let me know when this type of event happens to this object so I can run this handler" is the sort of thing that things like gobject and the DOM use more of a publish/subscribe event model for, right? e.g.

signal_connect(protocol, CONNECTION_MADE, lambda protocol, event: self._onConnection.callback(protocol))

Is there a reason we don't see more of that in Twisted? Should we? Signal handler ordering, propagation, and debugging is its own stack of worms to be sure, but having boundless stacks of wrappers, one per subscriber, with no way to un-register, doesn't seem like a great deal.

comment:5 Changed 4 years ago by Jean-Paul Calderone

Is there a reason we don't see more of that in Twisted?

Probably not a good reason. Just that someone needs to do the work, and the first one is always the hardest. The desire for this sort of thing comes up a lot with makeConnection and connectionLost (though I'm sure other areas would benefit from it as well).

See a somewhat related ticket for an API/implementation idea (which may be interesting to consider, but I am not suggesting that is necessarily the resolution to this ticket).

comment:6 Changed 4 years ago by Jean-Paul Calderone

Also an older rejected idea for publishing the connectionLost event more widely.

comment:7 Changed 4 years ago by Glyph

The tubes ticket addresses this problem, in a way, by making something both protocol-like and transport-like that is explicitly designed to be used with composition rather than inheritance..

Note: See TracTickets for help on using tickets.