The filters which are registered via ns_register_filter
and Ns_RegisterFilter() are run in FIFO order. This
can be inconvenient for a couple of reasons:
1) it places constraints on code layout, which procs
go where, how you name files to force load order etc.
2) because of initialisation order -- C modules
first, private Tcl library second -- it is impossible
to overide a C filter from Tcl.
This patch adds two new filter options:
NS_FILTER_FIRST
NS_FILTER_LAST
which can be ORed into the 'when' clause.
Example:
when = NS_FILTER_PREAUTH | NS_FILTER_FIRST;
Ns_RegisterFilter(server, method, url, MyFilter,
when, callback);
The filter is added to the head of the filter list
rather than the tail, which is still the default. It
will be run first unless another filter is registered
with the NS_FILTER_FIRST option.
I don't think a more elaborate scheme of numerical
priorities is worth the effort. However, this patch is
fully forwards and backwards compatible, should someone
else decide to impelement such a thing.
This patch adds the corresponding '-first' flag as an
option to the ns_register_filter command. It functions
as expected.
One of the primary motivations for this patch is to
shortcut filter processing. It's very convenient to
register site-wide filters which do chores such as
session management, authorization etc. Some
directories should not have the overhead, such as
/downloads or /images.
With the 4.1 thread pool feature, you can segregate
these URLs into a pool of their own, but to get the
full benefit you have to register your shortcut filters
via the C API. If you use the Tcl API, then each
thread in the downloads threadpool needs a heavyweight
Tcl interp which it wont otherwise use. Interps are
allocated on demand, so if you don't run any Tcl code,
they never get allocated.
This patch introduces the new command:
ns_register_filter_shortcut when method urlPattern
It registers a preauth, postauth or trace filter
NS_FILTER_FIRST for the given method and URL which
simply returns NS_FILTER_BREAK, therefore preventing
further filter processing.
register filters at head of queue
Logged In: YES
user_id=95086
Absolutely nothing against. Idea is clear and it
adds interesting options.
Couple of ideas for discussion
mainly cosmetic nature:
1.
Add ns_insert_filter (aka ns_register_filer -first)
Add ns_append_filter (the original ns_register_filter)
ns_register_filter stays for compat issues and
can be dropped at some major release.
2.
ns_register_filter_shortcut functionality is clear.
Only the command name is little bit awkward
maybe:
ns_ignore_filters
or
ns_shortcut_filters
One way or another I see no problems at the
moment. Lets see if somebody else complains.
Logged In: YES
user_id=21885
I'd really like to fold all these filter-related things into one
single ns_filter command with "insert" or "append" as
subcommands.
I'd also like to see some rudimentary benchmarks
demonstrating what kind of performance gain can be had by
having the functionality proposed in this RFE. Nothing
excessive, but at least some req/sec numbers and how much
that increases after the new functionality is implemented.
Logged In: YES
user_id=95086
Like:
ns_filter insert|append|list|replace|ignore
kind of thing?
Sounds good. Stephen?
There is another RFE which suggests the "list"
option and provides some code.
Wouldn't it be wise to combine both?
Concerning speed: this is not the only issue.
It is also memory footprint, thread initialization
time, less constraints on the alloc machinery
and CPU while loading/initializing interp per thread
and all those things.
Logged In: YES
user_id=21885
If you set minthreads=maxthreads, don't the Tcl interps get
created and initialized once and stay that way? When they
get returned to the conn thread pool, they just get "cleaned
up" which should be very lightweight if you don't actually USE
the Tcl interpreter to service the request. The only way to
dump the interpreter is to invoke [ns_markfordelete] at that
point.
I think I'm going to propose an RFE to improve fastpath
performance using nscache similar to Netscape Enterprise
Server's "nsfc" file cache. This would eliminate the need for
this RFE 1012103 for serving static content that doesn't
require a Tcl interp as a side effect. It would also be the
prerequisite step for implementing another RFE I want to file,
ns_adp_cache.
Logged In: YES
user_id=95086
Don't forget that a fully loaded interp might be
a 20+MB beast. By setting minthreads=maxthreads
and put minthreads to 5 you might allocate 100+MB
core for plain nothing. Unless, of course, you
do not employ my "ttrace" extension, if you know
what I mean.
Besides, there is really nothing wrong in more
control about registered filters that I can
think of. There are already 2 RFE's pointing
to this item. People are not doing this just
for fun.
Logged In: YES
user_id=21885
Zoran, I hear what you're saying about overall nsd process
footprint. I consider these two scenarios the "likely" cases:
1) Serving mostly static content. Very few Tcl procs or add-
on modules loaded. Very small per-thread memory footprint.
2) Serving mostly dynamic content. Large Tcl library or
number of add-on modules loaded. Fairly large per-thread
memory footprint.
In both cases, I recommend minthreads=maxthreads. In
scenario #1, this RFE gains you very little -- Tcl interp
footprint is small.
So, this RFE sounds like it might benefit people in scenario
#2. But: this RFE doesn't set aside threads *without* a Tcl
interp, it simply allows you to insert a filter that returns
filter_break from a C function. But, this happens within
ConnRun(), by which time you already have a Tcl interp fully
initialized. So, the thread servicing the request still "requires"
a "heavyweight Tcl interp that it won't otherwise use" so you
still have the memory footprint issue. All this RFE does is
offer a C function that implements "return filter_break".
So, to me, this seems like purely a speed optimization and
has no impact on memory utilization. In which case, I ask
again: can we see some benchmarks? Or, again, am I missing
something?
With regard to the new "-first" switch -- this can be achieved
by just registering the shortcut filter before registering any
other filters at start-up time. If you want to do this at run-
time (say, from the control port), you would require "-first" --
however, for now, folks can get around this by restarting the
nsd and ordering their filters at start-up time.
Logged In: YES
user_id=87254
The interps for conn threads are allocated lazily on demand,
not on thread creation. So, if you set
minthreads=maxthreads=10, on startup 10 threads will be
created. 10 Tcl interps will not be created and initialized.
If you can prevent your conn threads from ever running Tcl,
no interp will ever be allocated. By shortcutting global
Tcl filters, you can force a threadpool of 50 threads
dedicated to static downloads to consume very little memory.
Note: interps, once created, are cached on a per conn thread
basis. So if you define two virtual servers, each conn
thread may actualy have two interps allocated.
Logged In: YES
user_id=87254
I like the sound of an ns_filter command with subcommands
for insert, append, and list. If we can decide on naming, I
can take a shot at implementing this, if you'd like.
I'm not keen on an ns_request command which subsumes filter
and proc subcommands. There already is a concept of
'request' in AOLserver, and it's not this. Is something
like ns_proc, ns_handler, or ns_opproc suitable as a top
level command for registered procs, analogous to the
ns_filter command?
Logged In: YES
user_id=21885
First, lets limit the scope of this discussion to filters. I vote
for "ns_filter" as the top-level command name.
Second, in your comment on 2004-08-19 20:16, you describe
a scenario I omitted:
3) Serving only static content. No request invokes Tcl,
therefore no interp is initialized. Smallest memory footprint.
To me, if you're doing #3, why not use Apache. It's better at
the task. If you're using AOLserver, it's because you're doing
#2 or #3. In which case, SOME requests to the server will
pass through the Tcl interp for some connections which may
cause them to be initialized, and in the average case over a
reasonable period of time, eventually all conn threads will
have an initialized Tcl interp., so again, memory footprint is
not the issue here, not unless you restart your nsd process
often enough so that not all threads end up with an initialized
Tcl interp.
Now, I think I see where this is going: suppose you have two
pools, one of which is registered for "/images" and should only
serve fastpath (static) content. if you have a Tcl-based
filter on something like URL "/", it'll get executed on every
request, even those for "/images" and the Ns_GetConnInterp
() from ProcFilter() will cause you to initialize a Tcl interp.
But, with this RFE, you could create an "exclusion list" for
those very broad URL filters.
In order for this RFE to be useful, it needs to be well-
documented so people can configure their servers correctly to
take advantage of it. Who will write it?
Logged In: YES
user_id=87254
Thinking about it some more, I'm not so keen on 'ns_filter'
as a top level command. There are already a group of
related functions: ns_register_filter, ns_register_proc,
ns_register_trace, ns_register_adp. Plus, these are pretty
much *the* core AOLserver procs. I think it would be
confusing both to rename everything, and to rename just one
thing. Better to rename nothing.
That leaves the question of where to put the 'list' command.
Take a look at ns_info and ns_server, both seem likely
candidates for extension. Interestingly, ns_server takes a
-server switch, alowing you tao gather info on a server
other than the current one. That's something we didn't
consider.
On an implementation note, take a look at proc.c. We should
be reusing that for listing both C and Tcl filters and procs.
If that all sounds vaguely reasonable, then this RFE remains
pretty simple. I much prefer ns_shortcut_filter to the
originaly proposed mouthful. I think '-first' is fine, but
I'd also be perfectly happy with ns_insert_filter. Patch
appliers discretion :-)
Logged In: YES
user_id=95086
Good that we're comming to consensus.
ns_filter <option> arg ?... arg?
Who will document? Normally, somebody implementing
new commands should do simple ABC's:
a. implement the command (this is obvious)
b. add decent documentation to it
c. write test cases
Now that we have the place where to put documenation
I see no problems.
Logged In: YES
user_id=1081558
In adding more ns_filter related functionality, it would be
worthwhile to add a way to remove filters too, imo.
ns_filter insert|append|list|replace|ignore|delete
Recent changes added a scheme of numerical priorities to registered filters along with the ability to insert a filter rather than append. Both of these changes cover the requested functionality.