Prev: socket limitations question
Next: file tempfile
From: tom.rmadilo on 16 Oct 2009 16:25 On Oct 16, 1:11 am, Adrian Davis <adr...(a)satisoft.com> wrote: > > Unplug your network cable, extend your timeout to over three minutes > > (or maybe five) and see what the error message is for dns timeout. If > > it doesn't differ from the original, you may not be able to rely on > > the error message. But 60 seconds is less than required to test DNS > > timeout. > > The main problem I have is that the geturl timeout is not doing > anything. The geturl hangs - never returns - no error message. I'd be > very happy indeed if setting the timeout to one minute actaully caused > the geturl to timeout. > > Are there any other ways that I can force the geturl to quit after a > specified time? Ahh! That does sound like the described bug. It isn't a network hang. geturl is actually not working with the -timeout option. I recommend looking at AOLserver's nstclsh until this bug is fixed. An example http module (part of AOLserver) is here: http://junom.com/gitweb/gitweb.perl?p=aolserver.git;a=blob;f=aolserver/tcl/http.tcl;h=04c90 Even if blocking simplifies your http client (obviously it does), you risk serious permanent malfunction of your overall application if your API does not support an independent timeout other sock status features. AOLserver's API, also available in nstclsh includes a few additional features above those available in Tcl. One is ns_socknread which returns the number of bytes available to be read without blocking. If this number turns out to be zero, you can wait and check again (even on a blocking socket), using ns_sockselect. With nonblocking sockets, you can use ns_sockcheck to make sure a readable socket is actually connected to the foreign server. You should only use blocking mode if nothing else can be done before you get a full response from the foreign server. It is a very simple rule.
From: tom.rmadilo on 16 Oct 2009 22:41 On Oct 15, 11:44 pm, Alexandre Ferrieux <alexandre.ferri...(a)gmail.com> wrote: > On Oct 16, 6:32 am, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote: > > Strange, what is the purpose of using blocking mode in that situation? > > If I were to guess, I'd say "to simplify the state machine" ;-) > Now you're welcome to step in and rewrite that part, unless Jeff > objects. After looking at the code in question I am even more baffled. The http code is obviously designed to handle multiple connections at the same time, so "code simplification" could not possibly be the reason to use blocking. But I don't see any real attempt in this code to manage the complexity of client/server. All I know is that the easiest way to simplify code, and the data structures necessary is to use threads. Otherwise you have to get really anal over your event model. If I were to rewrite this code, I would start by separating the channel code from the protocol code (build your request/response, then talk to your channel code). Almost every fconfigure line is a brain fart of one sort or another. Every puts line is a total disaster. Basically a request/response looks like this: proc ::<ws>::invokeOperation { tclNamespace request } { set host [<ws>namespace set $tclNamespace host] set port [<ws>namespace set $tclNamespace port] set sock [socket $host $port] fconfigure $sock -translation binary puts $sock $request flush $sock set result [read $sock] close $sock return $result } That is how simple code looks with threads and when you remove all the request/response header-body building to some other place. But when the geturl proc is 450 lines long, who exactly cares to fix it? There are more uses of [catch] in that one procedure than I have in all the code I have ever published.
From: Alexandre Ferrieux on 17 Oct 2009 04:26
On Oct 17, 4:41 am, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote: > > > Now you're welcome to step in and rewrite that part, unless Jeff > > objects. > > After looking at the code in question I am even more baffled. The http > code is obviously designed to handle multiple connections at the same > time, so "code simplification" could not possibly be the reason to use > blocking. You don't understand. Let's clarify. (1) "code simplification" here means, do local single-blocking- connection style in the middle of an otherwise large, fully event- driven, multi-connection state machine. Of course this simplifies locally. But it is a bug, nobody denies that. (2) I didn't write a single line of this code, in case you wonder. 'cvs annotate' is your friend. > But I don't see any real attempt in this code to manage the > complexity of client/server. All I know is that the easiest way to > simplify code, and the data structures necessary is to use threads. > Otherwise you have to get really anal over your event model. Yeah, bringing back the thread-vs-event debate is the best idea at this spot... Are you aware that the http package works in unthreaded Tcl, and has been doing so from the beginning ? A more constructive suggestion would be to switch to coro style (again you're welcome to contribute). However, a direct fix of the bug posted by Eric would rather please 8.5.x users I think. -Alex |