durusmail: quixote-users: Re: Design question
Design question
2003-07-02
Re: Design question
2003-07-03
2003-07-03
2003-07-04
Graham Fawcett (2 parts)
2003-07-04
2003-07-04
2003-07-04
Design question
2003-07-04
Re: Design question
Graham Fawcett
2003-07-04
Paul Diaconescu wrote:
> Thanks!
>
> Ahhhh... it's gonna be such beautiful app.
>
>
> torsdagen den 3 juli 2003 kl 04.39 skrev Graham Fawcett:
>
>>
>> The NT service part shouldn't be a problem. Do you need sample code?
>>
>
> Yes, I haven't yet tried it on NT.
>

I'm attaching a sample service launcher. I'm embarrassed to post it, it's not
an example of the Right and Proper Way to run a service, but it ought to do the
trick until someone posts a better one! I use it to run a number of
Medusa-based services with no trouble.

Basically, starting the service just launches your server script in a new
process, and stopping the service kills that process. Inefficient, perhaps, but
it saves having to deal with both win32 and asyncore event loops in the same
process.

Put the file in your application directory, set the configuration variables at
the top, and then run 'python service.py install' from the command line.

You'll need the win32all extensions, of course, or grab an ActiveState
distribution of Python.

>>
>>> 2. Start the backend within the medusa_server.py script. I can't
>>> figure out a way to get the webui to have access to the backend
>>> namespace this way. Maybe subclass the Publisher and pass a reference
>>> to the backend in the request object?
>>
>>
>> Personally, I would prefer this over the implicit
>> start-thread-on-module-import approach. Subclassing
>> Publisher.start_request() is easy and effective.
>>
>
> I did this. Put the backend in request.backend. Nice!
>
>
>>
>> You could always store your exception reports in the database; then
>> they are just data, and the web UI could have a facet for viewing
>> these repots.
>
>
> I've saved those in a list accessible in request.backend.exceptions.
> Supernice!
>
> Now I just have the tedious task of building the webui. Thanks for the
> input.
>

If your experience with Quixote is anything like mine, I think you'll find that
building the web UI will go rather smoothly and pleasantly. Best of luck,

-- Graham

> / Paul D

"""
A very crude NT service manager to run a Python application.
There are no niceties here, all it does is start a new Python
interpreter process, running the specified script. Stopping
the service kills the interpreter process.

Author: Graham Fawcett, patched together from numerous examples.
"""

import time
import win32serviceutil
import win32service
import win32process
import win32event
import win32evtlogutil
import os

                    #----------------------------------------------------------
                                                                # configuration

# full path to your python interpreter
INTERPRETER = 'c:\\python22\\python.exe'

# initial directory for server to start in
STARTDIR = 'c:\\myproject'

# name of python file that runs your server
SERVER = 'startserver.py'

# name and display name of your server
SERVICE_NAME = 'testservice'
SERVICE_DISPLAY = 'Test Service'


                    #----------------------------------------------------------
                                                             # class definition

class SimpleService(win32serviceutil.ServiceFramework):

        _svc_name_ = SERVICE_NAME
        _svc_display_name_ = SERVICE_DISPLAY

        def __init__(self,args):
                win32serviceutil.ServiceFramework.__init__(self,args)
                self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)

        def SvcDoRun(self):
                self.active = 1
                self.Start_SimpleService()
                import servicemanager
                servicemanager.LogMsg(
                        servicemanager.EVENTLOG_INFORMATION_TYPE,
                        servicemanager.PYS_SERVICE_STARTED,
                        (self._svc_name_,''))
                while self.active:
                    #time.sleep(1)
                    timeout = 1000            # in milliseconds
                    rc = win32event.WaitForSingleObject(self.hWaitStop, timeout)
                    # Test return code to see whether our Event was signalled.
                    if rc == win32event.WAIT_OBJECT_0:
                        break

        def SvcStop(self):
                self.active = 0
                import servicemanager

                servicemanager.LogMsg(
                        servicemanager.EVENTLOG_INFORMATION_TYPE,
                        servicemanager.PYS_SERVICE_STOPPED,
                        (self._svc_name_,''))

                try:
                        self.Stop_SimpleService()
                except:
                        pass
                self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
                win32event.SetEvent(self.hWaitStop)


        def Start_SimpleService(self):
                si=win32process.STARTUPINFO()
                result=win32process.CreateProcess(
                            None,
                            '%s %s' % (INTERPRETER,
                                       os.path.join(STARTDIR, SERVER)),
                            None,
                            None,
                            0,
                            0,
                            None,
                            STARTDIR,
                            si)

                self.hSched=result[0]


        def Stop_SimpleService(self):
                        win32process.TerminateProcess(self.hSched, 0)


if __name__=='__main__':
        win32serviceutil.HandleCommandLine(SimpleService)
reply