create blog

go home go home
  1. about
  2. code
  3. wiki
  4. blog

Archive for August, 2009

Running Orbited (or other Twisted Services) as a Windows Service

Tuesday, August 4th, 2009

It took me awhile to figure out how to run Orbited and Dolores as Windows Services. Unfortunately, while I love Mac, almost every other computer at my workplace is Windows, including the servers. When deploying my web application, I can’t really just leave instructions like: “When you restart the server, please run these two scripts.”

They need to be Windows Services.

Thankfully, it isn’t actually too hard. You just need a couple of Python packages (which I actually don’t remember installing, so they may have come with Twisted or Python), and then all you have to do is write a couple of very simple scripts. Here are mine:

Orbited Service

import OrbitedManager # a copy of orbited.start with some very minor modifications, which I'll include after the break
import time
 
# Service Utilities
import win32serviceutil
import win32service
import win32event
 
class WindowsService(win32serviceutil.ServiceFramework):
	_svc_name_ = "Orbited"
	_svc_display_name_ = "Orbited Server"
 
	def __init__(self, args):
		win32serviceutil.ServiceFramework.__init__(self, args)
		self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
 
	def SvcStop(self):
		self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
		win32event.SetEvent(self.hWaitStop)
 
	def SvcDoRun(self):
		import servicemanager
		OrbitedManager.start()
		while True:
			retval = win32event.WaitForSingleObject(self.hWaitStop, 10)
			if not retval == win32event.WAIT_TIMEOUT:
				OrbitedManager.stop()
				break
				time.sleep(5.0)
 
 
if __name__=='__main__':
	win32serviceutil.HandleCommandLine(WindowsService)

Dolores Service

import Dolores
import time
 
# Service Utilities
import win32serviceutil
import win32service
import win32event
 
class WindowsService(win32serviceutil.ServiceFramework):
	_svc_name_ = "Dolores"
	_svc_display_name_ = "Dolores Server"
 
	def __init__(self, args):
		win32serviceutil.ServiceFramework.__init__(self, args)
		self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
 
	def SvcStop(self):
		self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
		win32event.SetEvent(self.hWaitStop)
 
	def SvcDoRun(self):
		import servicemanager
		Dolores.start()
		while True:
			retval = win32event.WaitForSingleObject(self.hWaitStop, 10)
			if not retval == win32event.WAIT_TIMEOUT:
				Dolores.stop()
				break
				time.sleep(5.0)
 
 
if __name__=='__main__':
	win32serviceutil.HandleCommandLine(WindowsService)

That’s the basics, but as you may have noticed, I also changed Orbited’s start script. I did this because the original did not play nicely with threads.

Instead of changing it in its original location in the filesystem, I created a copy of it in the local directory (as you can see, I’m not importing Orbited.OrbitedManager).

(more…)

Dolores & Cornelius, Sitting in a Tree. Of Comet, Orbited and Python.

Tuesday, August 4th, 2009

I’ll give you a moment to allow you to get that disturbing image out of your head.

I have been working on a web application. I’ll hopefully be able to post the application soon.

I needed the server to be able to send updates to the client via Comet. I’d never done any Comet before, so I wasn’t sure what to do.

A lot of articles had examples making use of message queues and who knows what else. They were a tad overwhelming. While a message queue of some sort may eventually be a good idea, for now, all I needed to do was push a non-vital progress indicator for a job (15%, 20%, 30%, and so on) to the client so the user could see what was happening. I wanted more than one job to be supported, and the overall system should eventually allow sending updates when elements in the user’s filesystem are updated.

So, I’d like to be able to send:

UPDATE process/at/my/process/path; {progress:.5}
UPDATE file/at/my/file/path.txt

In short, I’d like to send paths, along (sometimes) with little tiny messages.

Also, each instance of the web app should only receive updates to paths they are listening to, and they should only be allowed to listen to paths they actually have access to. Or, at least, that should be the case once I implement permission management in the app &emdash; right now, anything goes, which is fine for the moment because it is limited to test use on our local network.

So, I made a little script, called Dolores, which handles all of this, and another script, named Cornelius, which connects to it (incidentally, there are two Corneliuses: a Python one, and a JavaScript one).

I have posted it here in case anyone is interested. I used Orbited in JavaScript to connect to the server. In a separate post in just a few moments, I’ll write about something a tad more useful than the Dolores & Cornelius code I’m writing about here: how to run the Orbited (and, actually, Dolores) as a Windows service.

(more…)