From: Fredderic U. <mag...@gm...> - 2010-02-05 05:09:48
|
On 5 February 2010 11:04, Alexandre Ferrieux <ale...@gm...> wrote: > On 2/4/10, Wayne Cuddy <wc...@us...> wrote: >> TIP #361: RELEASING CHANNEL BUFFERS > > Uh, is it just me, or is the problem very different in 8.6 HEAD ? > (in another terminal: mkfifo /tmp/fifo;sleep 9999 < /tmp/fifo) > set ff [open /tmp/fifo w] > fconfigure $ff -blocking 0 > puts -nonewline $ff [string repeat A 999999] > flush $ff > close $ff > exit > => exits immediately > > Comment out the 'close' above, and the [exit] blocks again.... > Note that this *might* be the effect of one of the shortcuts done in > the 'exit reform' [Bug 2001201]. I'd be inclined to think that the TIP is the right thing, and this is a bug. If I explicitly say [flush], I kind of assume TCL would understand that I really really would like the data to be written to the underlyng connection, even if that means waiting a while before carrying through with a [close] or [exit]. In a proper production system, the application should have both internal and external limits set on how long it's allowed to just sit there, and this TIP would allow those internal limits to be enforced on any remaining outgoign data, while leaving the default action to Do The Right Thing. With respect to the example, TCP socket connections should eventualy time out, the consumer should time out (again, due to internal and external limits - most Unix's provide mechanisms to do that and they're almost mandatory on at least a few mainframe type systems I've seen) which in fact does happen in the example above, and if those timeouts could possibly be too long, steps should have been taken to enforce more appropriate limits. I'm more interested now, in how much effort needs to be applied to ensure TCL *won't* dump unwritten data in this case, and how obvious that is to someone who might think of doing what you've just done in that example; imagine a small application that builds one specific component of a webpage, in a string of such components, doesn't want to have a whole pile of extra work to do just to make sure its data gets written at the appropriate time - that is, in many cases, the calling applications job in this instance. ALL it wants to have to worry about, is preparing its chunk of output, writing it, cleaning up (updating databases, etc.), and finishing. My personal preference would be that [flush]d data WILL be written, even if it has to wait indefinitely (unless the other end of the socket gets closed first), sort of like setting a madatory low-water mark on the output buffer. [close] will do its best to close as much of the connection now as possible, and the rest as soon as possible (ie. after unwritten data has been sent), with [flush] being a means to indicate that we really do want this data written. [exit] and falling off the end of the script should be equivelant, and should try to finish cleanly (including [close]ing any open channels, with everything that goes along with [close]). And there should be some mechanism to prevent waiting if so desired (normally, I'd hazard to guess that if you've written something to a channel, regardless of what mode that channel's in, it's probably for a pretty good reason unless you explicitly say otherwise). In the case where there wasn't just a flush, but the channel has been closed, I'd be willing to accept TCL would try its best to write it, but just close it and give up when it hits the [exit], and perhaps also if it finds it's run out of files. (The latter should help resolve the issue mentioned with denial of services, if at all possible.) Other options could also be no-flush and/or max-wait options to any/all of [close] and [exit], and even the channel itself through [fconfigure]. But a quick loop over all open channels, using this TIP to explicitly close them without flush, just before an [exit], would do the trick. Fredderic |