[Twisted-Python] reactor.callLater() or reactor.callFromThread() when sending msg just before quit

Hello everyone, I have to send a message just before my service quits, but sometimes the reactor quits before the msg is sent. I was wondering if I should user reactor.callLater like so : self.sendMessage(msg) reactor.callLater(1, self.stop) (which I don't really like), or use reactor.callFromThread like so : self.sendMessage(msg) reactor.callFromThread(self.stop) (self.stop calls reactor.stop at some point). I really need for that msg to be sent before the reactor shuts down. Thank you, Gabriel

On 12:50 pm, gabriel.rossetti@arimaz.com wrote:
You should stop the reactor only after you receive acknowledgement that the message arrived at its destination. Hopefully the protocol you're using supports this. There are several ways in which bytes on a TCP connection can get lost. When you call reactor.stop() immediately after trying to send some bytes, it's most likely that they get lost because they are still in Twisted's send buffer. However, even if they get out of Twisted's send buffer and into the kernel's, they still may get lost on the network. And even if they arrive in the destination's kernel receive buffer, the receiving process may still exit (perhaps unintentionally) without reading them. And even if it reads them, it may exit without processing them. And even if they are processed, the disk I/O which records the result of that processing may be interrupted by a power loss or similar event. You may not need to deal with all of these eventualities (it depends on the purpose and reliability requirements of your application, of course). It's very common to want to know that the application on the other side of the connection read and processed the bytes, though. This requires that the protocol allow messages to be acknowledged. Jean-Paul

On Tue, 2009-12-08 at 13:50 +0100, Gabriel Rossetti wrote:
Neither of these will necessarily work. Instead, you want to use a shutdown hook: reactor.addSystemEventTrigger("before", "shutdown", f) when you do reactor.stop(), f will be called... and shutdown will be delayed until the Deferred f returns is triggered. In your case, send message, tell connection to close, and then stop reactor. If you make sure the Deferred from f only gets callback()ed when connectionLost is called you'll get behavior you want.

On 12:50 pm, gabriel.rossetti@arimaz.com wrote:
You should stop the reactor only after you receive acknowledgement that the message arrived at its destination. Hopefully the protocol you're using supports this. There are several ways in which bytes on a TCP connection can get lost. When you call reactor.stop() immediately after trying to send some bytes, it's most likely that they get lost because they are still in Twisted's send buffer. However, even if they get out of Twisted's send buffer and into the kernel's, they still may get lost on the network. And even if they arrive in the destination's kernel receive buffer, the receiving process may still exit (perhaps unintentionally) without reading them. And even if it reads them, it may exit without processing them. And even if they are processed, the disk I/O which records the result of that processing may be interrupted by a power loss or similar event. You may not need to deal with all of these eventualities (it depends on the purpose and reliability requirements of your application, of course). It's very common to want to know that the application on the other side of the connection read and processed the bytes, though. This requires that the protocol allow messages to be acknowledged. Jean-Paul

On Tue, 2009-12-08 at 13:50 +0100, Gabriel Rossetti wrote:
Neither of these will necessarily work. Instead, you want to use a shutdown hook: reactor.addSystemEventTrigger("before", "shutdown", f) when you do reactor.stop(), f will be called... and shutdown will be delayed until the Deferred f returns is triggered. In your case, send message, tell connection to close, and then stop reactor. If you make sure the Deferred from f only gets callback()ed when connectionLost is called you'll get behavior you want.
participants (3)
-
exarkun@twistedmatrix.com
-
Gabriel Rossetti
-
Itamar Turner-Trauring (aka Shtull-Trauring)