Index: openacs-4/packages/acs-core-docs/www/programming-with-aolserver.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/programming-with-aolserver.html,v diff -u -r1.49.2.10 -r1.49.2.11 --- openacs-4/packages/acs-core-docs/www/programming-with-aolserver.html 21 Jun 2016 07:44:36 -0000 1.49.2.10 +++ openacs-4/packages/acs-core-docs/www/programming-with-aolserver.html 23 Jun 2016 08:32:46 -0000 1.49.2.11 @@ -5,9 +5,9 @@
When using AOLserver, remember that there are effectively two types of global namespace, not one: -
Server-global: As you'd expect, there is +
Server-global: As you'd expect, there is
only one server-global namespace per server, and variables set within it can
-be accessed by any Tcl code running subsequently, in any of the server's
+be accessed by any Tcl code running subsequently, in any of the server's
threads. To set/get server-global variables, use AOLserver 3's nsv
API
(which supersedes ns_share
from the pre-3.0 API).
Script-global: Each Tcl script (ADP, Tcl page,
@@ -21,23 +21,23 @@
procedure. This distinction is important to understand in order to use
global
correctly when programming AOLserver.
Also, AOLserver purges all script-global variables in a thread (i.e., Tcl -interpreter) between HTTP requests. If it didn't, that would affect (and +interpreter) between HTTP requests. If it didn't, that would affect (and complicate) our use of script-global variables dramatically, which would then be better described as thread-global variables. Given -AOLserver's behaviour, however, "script-global" is a more +AOLserver's behaviour, however, "script-global" is a more appropriate term.
ns_schedule_proc
and ad_schedule_proc
each take a
-thread
flag to cause a scheduled procedure to run
asychronously, in its own thread. It almost always seems like a good idea to
-specify this switch, but there's a problem.
+specify this switch, but there's a problem.
It turns out that whenever a task scheduled with ns_schedule_proc
-thread
or ad_schedule_proc -thread t
is run, AOLserver
creates a brand new thread and a brand new interpreter, and reinitializes the
procedure table (essentially, loads all procedures that were created during
server initialization into the new interpreter). This happens every
time the task is executed - and it is a very expensive process that
should not be taken lightly!
The moral: if you have a lightweight scheduled procedure
-which runs frequently, don't use the -thread
+which runs frequently, don't use the -thread
switch.
Note also that thread is initialized with a copy of what was installed during server startup, so if the procedure table have changed since startup (e.g. using the APM watch @@ -50,7 +50,7 @@ that can be triggered from inside a procedure e.g., a permission denied exception. At this point, the procedure that detects invalid permission wants to write an error message to the user, and completely abort execution of the -caller thread.
return
doesn't work, because the procedure may be +caller thread.return
doesn't work, because the procedure may be nested several levels deep. We therefore usead_script_abort
to abort the remainder of the thread. Note that usingreturn
instead ofad_script_abort
may raise some security issues: an attacker could @@ -62,7 +62,7 @@
Many functions have a single return value. For instance, util_email_valid_p
returns a number: 1 or 0. Other functions need to return a composite value.
-For instance, consider a function that looks up a user's name and email
+For instance, consider a function that looks up a user's name and email
address, given an ID. One way to implement this is to return a three-element
list and document that the first element contains the name, and the second
contains the email address. The problem with this technique is that, because
@@ -106,14 +106,14 @@
}
Using Arrays and Pass-By-Reference
-Sometimes pass-by-value incurs too much overhead, and you'd rather -pass-by-reference. Specifically, if you're writing a proc that uses +Sometimes pass-by-value incurs too much overhead, and you'd rather +pass-by-reference. Specifically, if you're writing a proc that uses arrays internally to build up some value, there are many entries in the -array, and you're planning on iterating over the proc many times. In this -case, pass-by-value is expensive, and you'd use pass-by-reference. +array, and you're planning on iterating over the proc many times. In this +case, pass-by-value is expensive, and you'd use pass-by-reference.
The transformation of the array into a list and back to an array takes, in our test environment, approximately 10 microseconds per entry -of 100 character's length. Thus you can process about 100 entries per +of 100 character's length. Thus you can process about 100 entries per milisecond. The time depends almost completely on the number of entries, and almost not at all on the size of the entries.
You implement pass-by-reference in Tcl by taking the name of an array @@ -139,18 +139,18 @@
We prefer pass-by-value over pass-by-reference. Pass-by-reference makes
the code harder to read and debug, because changing a value in one place has
side effects in other places. Especially if have a chain of
-upvar
s through several layers of the call stack, you'll have
+upvar
s through several layers of the call stack, you'll have
a hard time debugging.
Multisets: Using ns_set
s and Pass-By-Reference
-An array is a type of set, which means you can't have multiple +An array is a type of set, which means you can't have multiple entries with the same key. Data structures that can have multiple entries for the same key are known as a multiset or bag.
If your data can have multiple entries with the same key,
you should use the AOLserver built-in
ns_set
. You can also do a case-insensitive lookup on an
-ns_set
, something you can't easily do on an array. This is
+ns_set
, something you can't easily do on an array. This is
especially useful for things like HTTP headers, which happen to have these
exact properties.
You always use pass-by-reference with ns_set
s, since they
-don't have any built-in way of generating and reconstructing themselves
+don't have any built-in way of generating and reconstructing themselves
from a string representation. Instead, you pass the handle to the set.
ad_proc ad_get_user_info { @@ -170,10 +170,10 @@ doc_body_append "[ns_set get $user_info namelink] ([ns_set get $user_info emaillink])"
-We don't recommend ns_set
as a general mechanism for passing
+We don't recommend ns_set
as a general mechanism for passing
sets (as opposed to multisets) of data. Not only do they inherently use
-pass-by-reference, which we dis-like, they're also somewhat clumsy to
-use, since Tcl doesn't have built-in syntactic support for them.
+pass-by-reference, which we dis-like, they're also somewhat clumsy to
+use, since Tcl doesn't have built-in syntactic support for them.
Consider for example a loop over the entries in a ns_set
as
compared to an array: