Forum OpenACS Q&A: Re: Tracking actual traffic usage with ad_returnfile_background?

Thanks Gustaf,

I should've seen the commented ns_log line in the end-delivery proc and figured this out myself 😉

I'm not familiar with xotcl, so I'm wondering is there's an easy way for my "own" package to overwrite the end-delivery proc? So I could basically leave the xotcl-core package unchanges while getting a callback for my own logging needs after the connection is terminated? (That's basically the extent of my needs -- objectifying the delivery is probably overkill if I can just hack the way it's done at the moment.)

Thanks,
Steffen

Steffen,

turning the fileSpooler into an object is quite trivial and should have done at the first place already (i have committed this to CVS HEAD). One question is whether the fileSpooler and/or every spooling act should be an object. For the sake of making a minimal change, i objectified just the fileSpooler. Otherwise it would be possible to customize every single spooling act with different behavior.

By turning the file spooler into an XOTcl object, it is possible to overload/extend every method in multiple ways, such as e.g. via mixins (see e.g. http://nm.wu-wien.ac.at/research/publications/xotcl-tclconf.pdf).

When you upgrade from CVS, and add e.g. a file xotcl-core/tcl/custom-bgdelivery-procs.tcl with the content below, you can add your logging there. For the sake of performance, i would suggest to avoid blocking operations in the bgdelivery thread. Make sure, that the this code is sourced after bgdelivery-procs.tcl.

One can as well add the custom behavior dynamically at runtime of the server. This could be done e.g. via ds/shell by issuing there

 
bgdelivery do eval {
   Class customSpooler
   customSpooler instproc end-delivery args {
      ns_log notice "CUSTOM end-delivery $args"
      next
   }
   ::fileSpooler mixin add customSpooler
}
Adding/changeing behavior via ds/shell is often convenient for debugging or developing.

Some background information about the code below. To understand it, one has to know the following about about initialization of the Tcl threads in aolserver: the Tcl threads are created on demand, that is, at the time, when e.g. the first bgdelivery happens. At that time, a thread is created and initialized with an initcmd. The code below simply adds commands to the initcmd of the bgdelivery thread. Therefore, the customSpooler will only exist in the background thread.

Hope this helps,

-gustaf neumann

#
# Save this content e.g. as 
# xotcl-core/tcl/custom-bgdelivery-procs.tcl
#
bgdelivery append initcmd {

  # A small class to overload the end-delivery method of the fileSpooler
  
  Class customSpooler
  customSpooler instproc end-delivery {filename fd channel bytes args} {
    #
    # A file delivery finished, do some custom behavior; here the files
    # are still open...
    #
    ns_log notice "CUSTOM end-delivery, bytes written = $bytes"
    
    # call the standard behavior of the fileSpooler (e.g. closing files)
    next
    
    # The standard behavior has finished, we could do here something as well...
  }

  # register the customSpooler to the fileSpooler
  ::fileSpooler mixin add customSpooler

  ns_log notice "+++ SPOOL customSpooler registered"
  
}