Forum OpenACS Development: RFC: registering filters ...

Collapse
Posted by Ola Hansson on
I want to propose a change to ad_register_filter so that it actually does register the filter (well, rp_invoke_filter in fact) *on the fly*. Currently "all" that ad_register_filter does is nsv_lappends a job to the "rp_filters"-nsv making sure that it will be ns_register_filter'ed at the next restart.

I always assumed that ad_* was the equivalent to ns_*, only better ...

Well, here is the proposed addition to ad_register_filter - just tuck this at the end:

    # Figure out how to invoke the filter, based on the number of arguments.
    if { [llength [info procs $proc]] == 0 } {
        # [info procs $proc] returns nothing when the procedure has been
        # registered by C code (e.g., ns_returnredirect). Assume that neither
        # "conn" nor "why" is present in this case.
        set arg_count 1
    } else {
        set arg_count [llength [info args $proc]]
    }

    set filter_index ?
    ns_register_filter $kind $method $path rp_invoke_filter [list $filter_index $debug $arg_count $proc $arg]
(BTW, filter_index doesn't seem to be used)

Thoughts?

Collapse
Posted by Jeff Davis on
If you do this you will lose the "priority sorting" that the init script does. Here is the comment from request-processor-init.tcl:
    # This lsort is what makes the priority stuff work. It guarantees
    # that filters are registered in order of priority. AOLServer will
    # then run the filters in the order they were registered.
    set filters [lsort -integer -index 0 $filters]
    nsv_set rp_filters . $filters
filter_index is used in the display page (in the monitoring package iirc) I think...

I am not sure the priority sorting is necessary so maybe it doesn't matter.

Collapse
Posted by Ola Hansson on
Oh, I think I see: ad_register_filter is supposed to only be called from *.init.tcl scripts, I guess (haven't found code to confirm this yet). Does this sound right? Then, after all all the package's init scripts have run, the nsv is scanned and the filters get registered with ns_register_filter in the proper priority order. After all, the nsv doesn't persist after restart so it would have to be populated at boot time.

In my case I was calling ad_register_filter from an after_instantiate callback, and was surprised that the filter was never registered. It did get registered (by ad_register_filter) after a restart, though, due to the fact that I am looping my app's package_ids in an *init.tcl script ...

I guess you should use the ns_ variant outside the init scripts, unless we come up with a persistent storage mechanism. But i wonder if I should still register rp_invoke_filter [list ...] instead of the filter directly ...

Hm, it looks as though some more thinking would be in order, if I can manage that on such a hot day as this.

Collapse
Posted by Jeff Davis on
I like the idea of being able to register procs on a new package without restarting the server; I suspect you could make it work by checking if the call is being made after the server's already completed restarting and if so then do the call directly, otherwise just rely on the normal startup sequence to do it.
Collapse
Posted by Ola Hansson on
My experiments suggest that "apm_first_time_loading" works:
    if { [apm_first_time_loading_p] } {
        # Append the filter to the list.
        nsv_lappend rp_filters . \
            [list $priority $kind $method $path $proc $arg $debug $critical $description [info script]]
    } else {
        # Figure out how to invoke the filter, based on the number of arguments.
        if { [llength [info procs $proc]] == 0 } {
            # [info procs $proc] returns nothing when the procedure has been
            # registered by C code (e.g., ns_returnredirect). Assume that neither
            # "conn" nor "why" is present in this case.
            set arg_count 1
        } else {
            set arg_count [llength [info args $proc]]
        }

        set filter_index {}
        ns_register_filter $kind $method $path rp_invoke_filter [list $filter_index $debug $arg_count $proc $arg]
    }
I will test this some more and, unless I hear otherwise, commit it to HEAD in a couple of days or so.

Thanks Jeff.

Collapse
Posted by Jeff Davis on
I think you should add it to the nsv in any case (since the monitoring package can only list the ones in the nsv).