Hi,
In message 200309071203.04502.fxn@hashref.com,
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 = “@count=#{@count+=1}”
res[‘content-type’] = “text/html”
end
end
svr = WEBrick::HTTPServer.new(:Port => 10080)
counter = AccessCounter.new(svr)
svr.mount(“/”, counter)
svr.start
···
`Xavier Noria fxn@hashref.com’ wrote:
–
gotoyuzo