Hi,

In message <200309071203.04502.fxn / hashref.com>,
 `Xavier Noria <fxn / hashref.com>' wrote:
> I am writing a web application where all the requests are served by the 
> same object, which needs initialization. This is being done this way:
> 
>     <<initialize some stuff from the command line parameters>>
>     <<initialize the driver of the application from that stuff>>
>     server.mount_proc(path) { |req, res| driver.process(req, res) }
> 
> That seems to work fine, but I wonder if the driver could be a subclass 
> of HTTPServlet::AbstractServlet so that one would just say
> 
>     server.mount(path, DriverServlet)
> 
> and have one instance serving all the pages and initialized as needed. I 
> have tried to figure it out from the sources but don't see how would it 
> work.

If it's explained simply, servelets are activated in the
following sequence:

  << accept connection and receive HTTP request >>
  << find a ServletClass associated with path of URL >>

  # the third and more arguments of mount() will be passed to options.
  servlet = ServletClass.get_instance(server, *options)
  servlet.service(req, res)

  << send response >>

If it can respond to get_instance and service, any kind of
object can be mounted as a servelet.

AbstractServlet::get_instance just calls new() and instance
of servelet will be created for every request.  Conversely
singleton servelet can be up by overriding of get_instance.

The following sample implements get_instance as a instance
method and initialize a servlet out of server before it's
started.

  require 'webrick'
  
  class AccessCounter < WEBrick::HTTPServlet::AbstractServlet
    def initialize(server)
      @mutex = Mutex.new  # service should be MT-safe
      @count = 0
    end
    def get_instance(server)
      self                # always returns same instance
    end
    def service(req, res)
      @mutex.synchronize{ super }
    end
    def do_GET(req, res)
      res.body = "<html><body>@count=<b>#{@count+=1}</b></body></html>"
      res['content-type'] = "text/html"
    end
  end
  
  svr = WEBrick::HTTPServer.new(:Port => 10080)
  counter = AccessCounter.new(svr)
  svr.mount("/", counter)
  svr.start

-- 
gotoyuzo