mirror of https://github.com/peter4431/rq.git
				
				
				
			Add an actual awesome worker structure.
To put messages on queues, use this:
    @job('normal')
    def foo(x, y):
        return x + y
    foo.delay(4, 5)
To run workers, start any number of these:
    $ python runworker.py high normal low
You can give arbitrary queue names, they are not limited to these
priority-based names.  They just serve as a useful example.
			
			
				main
			
			
		
							parent
							
								
									606f7f7cb3
								
							
						
					
					
						commit
						a5a8925608
					
				| @ -0,0 +1,17 @@ | |||||||
|  | from logbook import Logger | ||||||
|  | from .worker import Worker | ||||||
|  | 
 | ||||||
|  | def run_daemon(queue_keys, rv_ttl=500): | ||||||
|  |     """Simple implementation of a Redis queue worker, based on | ||||||
|  |     http://flask.pocoo.org/snippets/73/ | ||||||
|  | 
 | ||||||
|  |     Will listen endlessly on the given queue keys. | ||||||
|  |     """ | ||||||
|  |     worker = Worker(queue_keys, rv_ttl) | ||||||
|  | 
 | ||||||
|  |     log = Logger('worker') | ||||||
|  |     log.info('Listening for messages on Redis queues:') | ||||||
|  |     for key in queue_keys: | ||||||
|  |         log.info('- %s' % (key,)) | ||||||
|  | 
 | ||||||
|  |     worker.work() | ||||||
| @ -0,0 +1,78 @@ | |||||||
|  | import sys | ||||||
|  | import os | ||||||
|  | import random | ||||||
|  | import time | ||||||
|  | import procname | ||||||
|  | from logbook import Logger | ||||||
|  | from pickle import loads, dumps | ||||||
|  | from rdb import conn | ||||||
|  | from . import to_queue_key | ||||||
|  | 
 | ||||||
|  | class NoQueueError(Exception): pass | ||||||
|  | 
 | ||||||
|  | class Worker(object): | ||||||
|  |     def __init__(self, queue_names, rv_ttl=500): | ||||||
|  |         self.queue_names = queue_names | ||||||
|  |         self.rv_ttl = rv_ttl | ||||||
|  |         self._working = False | ||||||
|  |         self.log = Logger('worker') | ||||||
|  |         self.validate_queues() | ||||||
|  | 
 | ||||||
|  |     def validate_queues(self): | ||||||
|  |         if not self.queue_names: | ||||||
|  |             raise NoQueueError('Give each worker at least one queue.') | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def queue_keys(self): | ||||||
|  |         return map(to_queue_key, self.queue_names) | ||||||
|  | 
 | ||||||
|  |     def is_idle(self): | ||||||
|  |         return not self.is_working() | ||||||
|  | 
 | ||||||
|  |     def is_working(self): | ||||||
|  |         return self._working | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def pid(self): | ||||||
|  |         return os.getpid() | ||||||
|  | 
 | ||||||
|  |     def procline(self, message): | ||||||
|  |         self.log.debug(message) | ||||||
|  |         procname.setprocname('rq: %s' % (message,)) | ||||||
|  | 
 | ||||||
|  |     def work(self): | ||||||
|  |         while True: | ||||||
|  |             self.procline('Waiting on %s' % (', '.join(self.queue_names),)) | ||||||
|  |             queue, msg = conn.blpop(self.queue_keys) | ||||||
|  |             self.fork_and_perform_task(queue, msg) | ||||||
|  | 
 | ||||||
|  |     def fork_and_perform_task(self, queue, msg): | ||||||
|  |         child_pid = os.fork() | ||||||
|  |         if child_pid == 0: | ||||||
|  |             random.seed() | ||||||
|  |             self.log = Logger('horse') | ||||||
|  |             try: | ||||||
|  |                 self.procline('Processing work since %d' % (time.time(),)) | ||||||
|  |                 self._working = True | ||||||
|  |                 self.perform_task(queue, msg) | ||||||
|  |             except Exception, e: | ||||||
|  |                 self.log.exception(e) | ||||||
|  |                 sys.exit(1) | ||||||
|  |             sys.exit(0) | ||||||
|  |         else: | ||||||
|  |             self.procline('Forked %d at %d' % (child_pid, time.time())) | ||||||
|  |             os.waitpid(child_pid, 0) | ||||||
|  |             self._working = False | ||||||
|  | 
 | ||||||
|  |     def perform_task(self, queue, msg): | ||||||
|  |         func, key, args, kwargs = loads(msg) | ||||||
|  |         self.procline('Processing %s from %s since %s' % (func.__name__, queue, time.time())) | ||||||
|  |         try: | ||||||
|  |             rv = func(*args, **kwargs) | ||||||
|  |         except Exception, e: | ||||||
|  |             rv = e | ||||||
|  |         if rv is not None: | ||||||
|  |             p = conn.pipeline() | ||||||
|  |             conn.set(key, dumps(rv)) | ||||||
|  |             conn.expire(key, self.rv_ttl) | ||||||
|  |             p.execute() | ||||||
					Loading…
					
					
				
		Reference in New Issue