<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Jul 27, 2011, at 5:41 PM, <a href="mailto:exarkun@twistedmatrix.com">exarkun@twistedmatrix.com</a> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; font-family: Menlo; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; "><div><blockquote type="cite">My main thought here is that protocol reentrancy is bad, and nobody<span class="Apple-converted-space">&nbsp;</span><br></blockquote><blockquote type="cite">really expects it even if they think it should be fine.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">However, I do believe it would be best (easier to test, in particular)<span class="Apple-converted-space">&nbsp;</span><br></blockquote><blockquote type="cite">to immediately call connectionLost within doRead (or doWrite) after<span class="Apple-converted-space">&nbsp;</span><br></blockquote><blockquote type="cite">dataReceived exits, rather than callLater(0)-ing it or otherwise<span class="Apple-converted-space">&nbsp;</span><br></blockquote><blockquote type="cite">placing it into a global call queue.<br></blockquote><br>Probably not easier to test, nor easier to get right. &nbsp;A single<span class="Apple-converted-space">&nbsp;</span><br>generalized solution to avoid re-entrancy is probably the only way to<span class="Apple-converted-space">&nbsp;</span><br>avoid a perpetual sequence of accidental re-entrant calls in obscure<span class="Apple-converted-space">&nbsp;</span><br>untested cases in each different reactor implementation.<br></div></span></blockquote><div><br></div><div>Fair point; upon reflection of all the previous ad-hoc non-reentrancy stuff I've seen in the reactor, I retract my suggestion. &nbsp;For testing, it's easy enough to plug a Clock() in there and iterate it once.</div><br><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; font-family: Menlo; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; "><div>Perhaps the solution doesn't need to be `reactor.callLater(0, ...)`, but<span class="Apple-converted-space">&nbsp;</span><br>I think various implementations will be better if they put tasks into<span class="Apple-converted-space">&nbsp;</span><br>some kind of queue, perhaps checked at the end of the iteration instead<span class="Apple-converted-space">&nbsp;</span><br>of in the next iteration, rather than special casing each possible re-<span class="Apple-converted-space">&nbsp;</span><br>entrant event in each possible event dispatcher.<br></div></span></blockquote></div><br><div>What would be the point of adding another task queue to the reactor? &nbsp;This sounds like a solution to a non-problem. &nbsp;(Although I might have suggested the same thing myself if I hadn't thought about it too much first.)</div><div><br></div><div>The answer that comes to mind when I think about this question is that an end-of-iteration queue would avoid unnecessary additional invocations of whatever multiplexing system call the reactor needs to make. &nbsp;But there are several points on the down side:</div><div><br></div><div><ol class="MailOutline"><li>it's more code to maintain</li><li>it's more interfaces for users, or at least maintainers, to learn</li><li>it's an optimization, and so we should produce a benchmark indicating that the optimization makes sense and is effective before doing it</li><li>the optimization could be applied to callLater as it stands; any callLater(0) calls could be executed before the next reactor tick</li></ol><div><br></div></div><div>Mostly though, an additional queue for non-reentrancy would be an ad-hoc special-case solution to one tiny part of the more general problem that reactor event ordering is a complete accident with unforseen consequences. &nbsp;If there were a more general scheduling mechanism, we could schedule events in a better order overall.</div><div><br></div><div>-glyph</div><div><br></div></body></html>