On 10/4/06, Zoran Vasiljevic <[EMAIL PROTECTED]> wrote:
To summarize. What you object is:
a. handle management (should work without handles)
b. name of the module (should not be proxy)
c. invent default pool
d. ?
For a:
I understand the syntactical need, but this is how I see that from
the practical side. By having a handle, I can run "things" in the
proxy (lets call it slave process from now on) one after another with
a possible "state" between the runs. This might sometimes be needed.
If I hide the handle, how could I force my two or three consecutive
operations to be executed in the same slave?
That's a good point.
The same problem arises in the higher level db APIs. If handle
management is transparent, how do you send multiple statement to a
single db back end, such as to implement transactions or "select for
update" and so on?
dbi_withhandle {
dbi_dml "update foo ..."
dbi_dml "update bar ..."
}
But what I'm wondering is, why you need to do this with proxy slaves?
It seems like they don't have the same state problem that a series of
database statements do.
It's possible to send multiple Tcl commands to a single proxy slave at
the same time:
ns_proxy eval {
set f [do_foo ...]
set b [do_bar ...]
return [list $f $b]
}
(You can't do that with databases because they often forbid using a
statement separating semicolon when using prepared statements and/or
bind variables. But Tcl doesn't have that restriction.)
I can imagine some kind of if-then between the two statements. When
does it become impossible to do this in the proxy slave? When do you
have to do this instead?:
ns_proxy withhandle {
set f [ns_proxy eval {do_foo ...}]
...
if {$f ...} {
set b [ns_proxy eval {do bar ...}]
}
}
If it's not possible to send all the code to the proxy slave at once,
then you can use something like the withhandle command to batch
multiple calls to eval on the same handle.
This does have some disadvantages to running both statements in a
single call to 'eval'.
For example, any time budget you have for the statements as a whole
must be split between each. So, if you decide each call should take
only 30 secs, and the first call takes 1 sec but the second takes 31
secs, you will get a timeout error with almost half your total time
budget still to spend. But you would have been perfectly happy to wait
58 seconds in total, spread evenly between the two calls.
Another problem might be the code you run in between the two eval
calls. In the case of explicit handle management or the withhandle
command, the handle is kept open even when it is not being used. If
the code that runs between the two eval calls takes some time --
perhaps because it blocks on IO, which may not be apparent to the
caller -- then other threads may be prevented from using a proxy slave
because the pool is empty. Handles which could have been returned to
the pool and used by other callers are sitting idle in threads busy
doing other things. This is a (temporary, mostly) resource leak.
So, apart from state (if this is needed), the withhandle command is a
speed optimisation. If you know for a fact that you're going to have
to make sequential calls to the proxy system, you can take the pool
lock just once. Otherwise, with implicit handle management, you take
and release the pool lock for each evaluation.
Regardless, the withhandle command allows implicit handle management
in the common case, and a nice, clear syntax for when you explicitly
want to manage the handle for performance or state reasons.
For b.
I do not care how we call it. We can call it ns_cocacola if you like.
The name contest is open...
It's an annoying thing to have to even bother about... But it is
important. If it's not clear, people will be confused, we've seen a
lot of that. Confused people take longer to get up to speed. People
like new hires, which costs real money.
For c.
I'd rather stick to explicit pool naming. I'd leave this "default"
to the programmer. The programmer might do something like
(not 100% right but serves the illustration purpose):
ns_proxy config default
rename ::exec tcl::exec
proc ::exec args {
ns_proxy eval default $args
}
This covers overloading of Tcl exec command. If you can convince me
that there are other benefits of having the default pool I can
think about them. I just do not see any at this point.
A default only makes sense if it's built in. If it isn't, no on can
rely on it and all code that uses proxy pools will have to create
their own.
Even with a built-in default, user code can certainly still create
it's own proxy pool(s). Nothing is being taken away.
If it was unlikely that the default would work for much/most code,
then it would be wrong to have one. That would be hiding something
from programmers that they should be paying attention to. It looks to
me though like a default pool would work for most code. But this is
just a convenience.
To manage resources efficiently you need the default pool. I can
imagine 'exec' using the default pool, and 3rd party modules doing
something like:
ns_proxy eval -pool [ns_configvalue ... pool default] {
....
}
Which will just work. The site administrator can then allocate
resources in a more fine grained way, if needed, according to the
local situation.