[TransWarp] Multiapp multithreaded server and configurable services

Radek Kanovsky rk at dat.cz
Fri Jun 20 11:11:04 EDT 2003


with the help of PEAK and Twisted I want to build threaded application
server that will be able to serve multiple applications. Every
application is composed from PEAK components and hierarchy typicaly
looks like this:

    +- svc1
    |    +- dm11
    |         +- svc111
    |         +- svc112
    +- svc2
         +- dm21
         +- svc22

Application instances reside in pools. Number of instances is
configurable according to assumed application load. app_root1 typicaly
holds database connection or any other resource. Server has
some number of worker threads that get application instance from pool
and do its work upon client request. App instance is returned then
back into pool.

Applications are very simmilar and components svc1, dm21, svc22, ...
will be often components from library. Every component will be configurable
with zconfig or some custom XML format (not decided yet). This configuration
must be able to address specific component on specific path in specific
application. I must be able to say, that component '/svc1/dm11/svc111'
of application 'app1' has value 'vvv' of property 'ppp' or '/svc2/'
has subservice 'dm22' of some type. Subservices of some specific service
are defined staticaly in python module (via bindService) or can be specified
in configuration: "service '/svc2' has subservice 'dm21' of class

What is the problem?

Assume that 'app2:/dm1' and 'app1:/svc1/dm11' are the same library
components lib.contact:ContactDM. There is undesirable to create child
components inherited from ContactDM only for purpose of modifying some
parameters (parameters are configured in custom config as possible).
But this ContactDM can have some classAttr (typicaly cache)
that canot be shared on 'app2:/dm1' and 'app1:/svc1/dm11' occurences
of ContactDM class. Obviously this components will be working on different
databases or tables and cannot share cache.

I have started to code some binding utilities that could solve my problem
but I want to ensure that PEAK doesn't provide some solution before doing
useless work. My solution looks like this and I will be able to post
more details here soon:

class bindService(binding.Once) :
    """Adapts service parameter to IServiceFactory and creates
       its copy upon first request. Parameter can be directly subclass
       of Service or subclass of IServiceFactory. If it is interface,
       class that implements it can be configured. Information that
       lib.contact:ContactDM implements IContactFactory is configurable
       per application and specific component occurence (path).
       serviceAttrs are replaced with classAttrs in copy.
       classAttrs are kept intact.
       Additionaly it loads parameters from appropriate part of
       custom configuration into created IService instance.

       Configuration is obtained from ServiceRoot that must
       be known during calling bindService.computeValue().
    def __init__(self, service, **kw) :
        self.service = service
class Service (binding.Component) :
    """Parent of all service classes. It has methods for allocating
       persistent resources, doing authorization and subservices lookup.

class serviceAttr (object) :
    """binding.classAttr variant.

class ServiceRoot (Service, ConfigurationRoot) :
    """Eats custom configuration and provides it to subservices.



More information about the PEAK mailing list