Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Use the service as a controller with multiple threads. One thread (Main) is supposed to synchronize and queue commands and use the win32 serviceframework for communication, registerting to the system etc. Another thread (Worker) is supposed to wait on commands from queue and execute them. If you execute arbitrary code as separate processes then you can spawn those from the worker thread and simply read back the results once they are done and clean up.</p> <p>This way, when a stop arrives your main thread will register it to the worker in its queue, which will wake up and try to signal the other process(es) to quit, wait a bit and clean up or terminate them forcefully.</p> <p><strong>Update:</strong></p> <p>Below is a sample concept on how you could have a service that is always responsive and runs as long as necessary. Each worker may throw</p> <pre><code>... import threading ... class InterruptedException(Exception): pass class WorkerThread(threading.Thread): def __init__(self, controller): self._controller = controller self._stop = threading.Event() super(WorkerThread, self).__init__() def stop(self): self._stop.set() def stopped(self): return self._stop.isSet() def run(self): try: # Insert the code you want to run as a service here # rather than do "execfile(.../.../blah)" simply do: # You can have your code throw InterruptedException if your code needs to exit # Also check often if self.stopped and then cleanly exit import your_file your_file.main() # if code in another module is not yours or cannot check often if it should stop then use multiprocessing which will spawn separate processes that you can terminate then from here when you need to stop and return # in that case simply block here on self._stop.wait() except InterruptedException as exc: # We are forcefully quitting pass except Exception as e: # Oh oh, did not anticipate this, better report to Windows or log it finally: # Close/release any connections, handles, files etc. # OK, we can stop now win32event.SetEvent(self._controller) def __init__(self, args): win32serviceutil.ServiceFramework.__init__(self, args) self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) self.hWaitDone = win32event.CreateEvent(None, 0, 0, None) def SvcDoRun(self): import servicemanager servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, '')) worker = WorkerThread(self.hWaitDone) worker.start() while True: # Wait for service stop signal rc = win32event.WaitForMultipleObjects([self.hWaitStop, self.hWaitDone], win32event.INFINITE) # Check to see if self.hWaitStop happened as part of Windows Service Management if rc == 0: # Stop signal encountered servicemanager.LogInfoMsg(self._svc_name_ + " - STOPPED!") #For Event Log break if rc == 1: # Wait until worker has fully finished worker.join() # Determine from worker state if we need to start again (because run finished) # Or do whatever if not worker.need_to_start_again(): break worker.start() </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload