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