On 03.10.2006, at 01:01, Stephen Deasey wrote:
It's not just the cleanup-up after error. Why does the Tcl programmer need to get and return resources? It's kind of awkward.
Not necessarily... Think of a handle as a "reservation". I take the handle and I "own" the resource for some time. In case of nsproxy, I can run two or more "things" one after another, possibly sharing the common state in the proxy slave.
For example: ns_serialize { # whatever } is better than the mutex example above because you also don't have to mess around with the mutex handle and nsv arrays. The Tcl code in the code block serves as a key into a hash table of locks, created on demand. We can let the code block shimmer to an object which contains both a byte code script and a mutex pointer. It will run as fast as possible the second time round. More complicated syntax for a more complicated operation: ns_serialize -lock mylock { # whatever } Now you could run two different code blocks using the same lock. But you still don't have to allocate mutex objects, pass around their names in nsv arrays, and so on. I don't think the above is dumbed-down. It's a much nicer way to work with Tcl, and you just wouldn't do this kind of thing from C.
Guess what... exactly this I have done in the Tcl threading extension for the thread::eval command: thread::eval ?-lock mutex? arg ?arg ...? (this is perhaps a misnomer as script is evaluated in the _current_ and not in some other thread) Which means: I completely understand what you say. Just in some cases it is feasible (like in example for the mutex) to avoid fiddling with handles and in some cases (nsproxy) it opens new posibilities.
Anyway, back to nsproxy. Thinking about it further, it looks like the explicit handles are actually there to allow a particular kind of Tcl programming, not necessarily because explicit handle management is needed. i.e.: set x [create ... $x method ... Which is perhaps not a bad way to manage the handles if you absolutely need them. But if you can instead do: ns_proxy eval { # whatever } which in the case of a default pool and a single evaluation, you can, it's got to be better than the explicit handle management, right?
As said, in this special case: yes. But otherwise: no. What I CAN do with explicit handle managment is: set proxy [ns_proxy get thepool] $proxy "set a 1" $proxy "puts $a" This is not possible w/o explicit handle. It is also the reservation aspect that is important when using the handle. This aspect is of course nil for mutex, condvar or other "things".
This is basically identical to the db module. People hate manging db handles, which is why the ACS style db_* API is so popular.
It is all the matter of the programming case. In some cases it is absolutely stupid to use handles, I agree. In some cases it opens new possibilities.
I was also wondering about the ns_proxy send/wait/receive. Why are wait and receive separate commands?
Because you can wait, get the timeout, do something and then go repeat waiting. It makes sense. You can't achieve this with a longer wait timeout OR with a timed [ns_proxy eval]. Allright, you can argue: one can [ns_proxy receive proxy ?timeout?] in which case you have the same behaviour. Correct. But what difference would it make, really?
Also, does there need to be so many timeouts? The waittimeout is 100 msec. That means if all else goes well, but the wait time takes 101 msec, the evaluation will not be successful. But looking at the other defaults, the script evaluator was prepared to wait (gettimeout 5000 + evaltimeout infinite + sendtimeout 1000 + recvtimeout 1000), or between six seconds and forever... Wouldn't a single timeout do?
There are lots of "places" something can go "wrong" at the communication path. Hence so many timeouts. At every place you send something or receive something, there is a timeout. Timeout to send chunk of data to proxy isn't the same as the timeout to wait for the proxy to respond after feeding it some command to execute. Basically, one can hardwire "sane" values for those communication timeouts (and there are sane values set there as defaults) but somebody may come into the need of adjusting them during runtime. You however do not need to do that, as sane defaults are provided everywhere.
It would also be great if the timeout error code began with the NS_TIMEOUT symbol, which if not caught will automatically trigger a Server Busy error page.
This is not a problem.