Gustaf, I'm going to ask that the patch be removed and replaced with a module. I've already written one which does the same thing.
We are in a bad habit in this community of letting anything happen at the least possible cost to those who modify core code. This is a perfect example of the situation. We now have two new subcommands for ns_conn. Some would phrase it as only two. But, for instance, most commands have like four total subcommands. Regardless of the number, we have just added two undocumented commands to the core code. We have a major problem with documentation here, and we know why: developers are not required (not even encouraged!) to do any work documenting new code or features. They don't have to provide any examples which work with AOLserver. All that they have to do is to commit a patch. This easy five minute job now requires everyone else to do work. Second, the patch does nothing for AOLserver without at least figuring out where to get the ::thread package. Again, there is no documentation on where to get it, how to install it or use it. But the example code which was referenced below is part of a much larger project: OpenACS, and a very recent version of it. In fact, it is part of OpenACS that isn't even necessary for the core features, and is only there for optimization as you have pointed out. The examples are written in xotcl, which I have tried to figure out for a year or more with little success. Third, some technical issues: New features which don't require core changes should be done as modules, unless there is an obvious close relationship to the core functions. In this case, the new feature is so foreign to the normal workings of AOLserver that the code should be isolated from the core until it is fully understood. Since you didn't write the original code, I assume that you can't really explain all the details of what is going on and why. I spent a lot of time looking at this new feature and seeing if there was anything similar in AOLserver. What I discovered was quite the opposite. There is not a single example where two conns (conns, not sockets) are returning data to clients in the same thread. It is possible that the AOL team once considered this, but none of the core API support this in any way. Each is written to work in a single thread (or block) and contains an internal event loop (in C). It is impossible to imagine that the core could be rearranged to support a generic multiplexing of client returns. When you survey how many different types of returns there are, you will immediately understand why. The easiest way to put it is that reading client data is essentially a binary read until passed to a connection thread. Once the connection thread has all the binary data, it can do conversions as needed. AOLserver request model is a pipeline which is specialized per request. We can consider this new feature as creating a branch where the original pipeline continues (like after ns_conn close), and another branch sends data to the client. But AOLserver has no control over the new branch. It could fail and we would never know. There are no logs of failures. Actually, not quite true, it looks like if the delivery fails for some reason, or if you don't call [ns_conn contentsentlength $filelength], you get zero bytes in the access.log. On the surface, the patch appears (as described) to do something like ns_returnfile. All the patch does is to make a copy of the connection and wrap the sock in a Tcl_Channel. It doesn't create a worker thread, doesn't pass the conn to this thread, it doesn't write headers or open the static file. There is no way to signal for shutdown and to a thread join. All of this work has to be done by the developer, including debugging, testing, and everything else. So what we have is a new way for everyone to start doing things in different ways, wondering why it doesn't work, complaining about why it doesn't work the way they expect, etc. Some will probably offer their own patches to make it work better. When we accept the patch, we allow you to transfer all this mess to the AOLserver community. Now we have to answer all these concerns, you don't. This also short circuits discussion about the best way to do this in AOLserver, and what to recommend to new users. Why? We just had another good discussion about the performance of AOLserver for static content. We discovered that the model for AOLserver works very well in this context, so much so that we are kind of scrathing our heads over any need to think too hard about performance improvements. There really are better things to work on. There seems to be an obsession among new developers that performance tweaking is the first thing to be considered when writing code. They think about a few lines of code, one syscall vs another. But when you read the AOLserver sources, it really starts to dawn on you: it ain't easy. Fortunately it is already written, so why not use it to best advantage? Part of that being done for you is the module system. If new functionality can be added without patching the core it does two important things: it provides examples of how to do it, and proves (as in tests) the sound design of the core. If developers are encouraged to provide patches instead of modules it works against these goals. Anyway, I fully support the code in module form. I don't completely understand the performance or security impact, but as a module, users can take it or not by their own choice. If I had to do a similar task, I would probably create a unique code and create a symlink to the actual file, then redirect the user to that file using another instance of AOLserver. The other instance would check the age of the symlink and serve the file if under some configured amount. If the entire file gets served, remove the link. This way, you can fully leverage the REST style, and it will likely release your expensive connection thread even faster than the current example. Using the code as a module (minus the ability to transfer the channel), here is an example of use (the string bgwrite could easily be changed to anything else, I chose it before I realized that the code doesn't do any bgwriting.): # Get nContentSent (should be 0) set contentsentlength [ns_bgwrite contentsentlength] # Set nContentSent (to zero) ns_bgwrite contentsentlength $contentsentlength # Dup sock and wrap in Tcl_Channel set channel [ns_bgwrite channel] # File to return: set dir [file dirname [info script]] set image sns-thumb.jpg set file [file join $dir $image] # Get length of file: set contentLength [file size $file] # Get content type: set contentType [ns_guesstype $file] # Create last modified header data: set lastModified [ns_httptime [file mtime $file]] # Create header: set header "HTTP/1.1 200 OK Last-Modified: $lastModified MIME-Version: 1.0 Date: [ns_httptime [ns_time]] Server: AOLserver/4.5.0 Content-Type: $contentType Content-Length: $contentLength Connection: close " # Open file to send: set inFd [open $file r] # Configure channels: fconfigure $inFd -translation binary fconfigure $channel -translation binary # put headers (could block forever): puts $channel $header # fcopy file to channel. fcopy $inFd $channel -command [list close $channel] #^^in a conn thread, this only sends the first 4096 bytes # while in background mode (caused by -command switch) # The following still happens regardless of fcopy status: # Set nContentSent so log file will look normal: ns_bgwrite contentsentlength $contentLength # Log something ns_log Notice "File $file has contentlength = $contentLength" # No need to return, as [ns_bgwrite channel] has effect of [ns_conn close]. # Traces will still run on this thread # what happens to keepalive? ### Log File Messages: # error.log [-default:0-] Notice: File /web/nsd45/servers/jnm/pages/sns-thumb.jpg has contentlength = 28672 [-default:0-] Notice: running ::traceFilter, sleeping for '1' seconds # access.log 192.168.1.102 - - [01/Oct/2007:06:58:23 -0700] "GET /nsbgwrite.tcl HTTP/1.0" 200 28672 "" "" # access.log without setting nContentSent 192.168.1.102 - - [30/Sep/2007:22:00:25 -0700] "GET /nsbgwrite.tcl HTTP/1.0" 200 0 "" "" tom jackson On Saturday 29 September 2007 13:55, Gustaf Neumann wrote: > Tom Jackson schrieb: > > Okay, after looking further into this patch, I see that it doesn't > > actually add any functionality to AOLserver. It looks like you would have > > to install a newer version of OpenACS to use this. > > as i wrote in my earlier mail, the patch is simple and small and adds > just two > subcommands to ns_conn. Thanks to dossy, the patch is commited to cvs. > head. > > The applications to "ns_conn channel" are on the tcl layer and > are quite simple to use. Look into the xotcl-core package > (xotcl-core/tcl/bgdelivery-procs.tcl) in the openacs cvs repository. > With the patch, xotcl-core and libthread, one can replace e.g. > ns_returnfile 200 $mime_type $filename > by > ad_returnfile_background 200 $mime_type $filename > in cr_write_content in acs-content-repository/tcl/revision-procs.tcl > to use the background delivery for content sent from the > content repository (e.g. file store). -- AOLserver - http://www.aolserver.com/ To Remove yourself from this list, simply send an email to <[EMAIL PROTECTED]> with the body of "SIGNOFF AOLSERVER" in the email message. You can leave the Subject: field of your email blank.