Skip to content

Commit 0e2c92e

Browse files
author
Matt George
committed
fixed issues with redis connection
1 parent 605d8f8 commit 0e2c92e

File tree

5 files changed

+131
-38
lines changed

5 files changed

+131
-38
lines changed

pyres/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,9 @@ def encode(cls, item):
258258

259259
@classmethod
260260
def decode(cls, item):
261-
if item:
261+
print item
262+
if isinstance(item, basestring):
263+
262264
ret = json.loads(item)
263265
return ret
264266
return None

pyres/horde.py

Lines changed: 118 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,116 @@
1+
import sys
12
try:
23
import multiprocessing
34
except:
4-
import sys
55
sys.exit("multiprocessing was not available")
66

77
import time, os, signal
88
import datetime
99
import logging
1010

11-
from pyres.worker import Worker
1211
from pyres import ResQ
1312
from pyres.exceptions import NoQueueError
1413
from pyres.utils import OrderedDict
14+
from pyres.job import Job
15+
import pyres.json_parser as json
1516

16-
17-
class Minion(multiprocessing.Process, Worker):
17+
class Minion(multiprocessing.Process):
1818
def __init__(self, queues, server, password):
19+
#super(Minion,self).__init__(name='Minion')
1920
multiprocessing.Process.__init__(self, name='Minion')
21+
22+
format = '%(asctime)s %(levelname)s %(filename)s-%(lineno)d: %(message)s'
23+
logHandler = logging.StreamHandler()
24+
logHandler.setFormatter(logging.Formatter(format))
25+
self.logger = multiprocessing.get_logger()
26+
self.logger.addHandler(logHandler)
27+
self.logger.setLevel(logging.DEBUG)
28+
2029
self.queues = queues
21-
self.validate_queues()
2230
self._shutdown = False
23-
self.child = None
2431
self.hostname = os.uname()[1]
25-
if isinstance(server,basestring):
26-
self.resq = ResQ(server=server, password=password)
27-
elif isinstance(server, ResQ):
28-
self.resq = server
29-
else:
30-
raise Exception("Bad server argument")
32+
self.server = server
33+
self.password = password
34+
3135
#Worker.__init__(self, queues=queues, server="localhost:6379", password=None)
32-
#super(Minion,self).__init__(name='Minion')
36+
#
37+
3338
def prune_dead_workers(self):
3439
pass
3540

41+
def schedule_shutdown(self, signum, frame):
42+
self._shutdown = True
43+
44+
def register_signal_handlers(self):
45+
signal.signal(signal.SIGTERM, self.schedule_shutdown)
46+
signal.signal(signal.SIGINT, self.schedule_shutdown)
47+
signal.signal(signal.SIGQUIT, self.schedule_shutdown)
48+
49+
def register_minion(self):
50+
pass
51+
52+
def startup(self):
53+
self.register_signal_handlers()
54+
self.prune_dead_workers()
55+
self.register_minion()
56+
57+
def __str__(self):
58+
return '%s:%s:%s' % (self.hostname, self.pid, ','.join(self.queues))
59+
60+
def reserve(self):
61+
for q in self.queues:
62+
self.logger.debug('checking queue: %s' % q)
63+
job = Job.reserve(q, self.resq, self.__str__())
64+
if job:
65+
self.logger.info('Found job on %s' % q)
66+
return job
67+
68+
def process(self, job):
69+
if not job:
70+
return
71+
try:
72+
self.working_on(job)
73+
return job.perform()
74+
except Exception, e:
75+
exceptionType, exceptionValue, exceptionTraceback = sys.exc_info()
76+
self.logger.error("%s failed: %s" % (job, e))
77+
job.fail(exceptionTraceback)
78+
self.failed()
79+
else:
80+
self.logger.info('completed job')
81+
self.logger.debug('job details: %s' % job)
82+
finally:
83+
self.done_working()
84+
85+
def working_on(self, job):
86+
self.logger.debug('marking as working on')
87+
data = {
88+
'queue': job._queue,
89+
'run_at': int(time.mktime(datetime.datetime.now().timetuple())),
90+
'payload': job._payload
91+
}
92+
data = json.dumps(data)
93+
self.resq.redis["resque:minion:%s" % str(self)] = data
94+
self.logger.debug("minion:%s" % str(self))
95+
#self.logger.debug(self.resq.redis["resque:minion:%s" % str(self)])
96+
97+
def failed(self):
98+
pass
99+
100+
def done_working(self):
101+
self.logger.info('done working')
102+
#self.processed()
103+
self.resq.redis.delete("resque:minion:%s" % str(self))
104+
105+
def unregister_worker(self):
106+
pass
107+
36108
def work(self, interval=5):
109+
37110
self.startup()
38111
while True:
39112
if self._shutdown:
40-
logging.info('shutdown scheduled')
113+
self.logger.info('shutdown scheduled')
41114
break
42115
job = self.reserve()
43116
if job:
@@ -47,6 +120,13 @@ def work(self, interval=5):
47120
self.unregister_worker()
48121

49122
def run(self):
123+
124+
if isinstance(self.server,basestring):
125+
self.resq = ResQ(server=self.server, password=self.password)
126+
elif isinstance(self.server, ResQ):
127+
self.resq = self.server
128+
else:
129+
raise Exception("Bad server argument")
50130
self.work()
51131
#while True:
52132
# job = self.q.get()
@@ -69,14 +149,18 @@ def __init__(self, pool_size=5, queues=[], server='localhost:6379', password=Non
69149
self.pid = os.getpid()
70150
self.validate_queues()
71151
self._workers = OrderedDict()
72-
if isinstance(server,basestring):
73-
self.resq = ResQ(server=server, password=password)
74-
elif isinstance(server, ResQ):
75-
self.resq = server
76-
else:
77-
raise Exception("Bad server argument")
152+
self.server = server
153+
self.password = password
154+
78155
#self._workers = list()
79156

157+
def setup_resq(self):
158+
if isinstance(self.server,basestring):
159+
self.resq = ResQ(server=self.server, password=self.password)
160+
elif isinstance(self.server, ResQ):
161+
self.resq = self.server
162+
else:
163+
raise Exception("Bad server argument")
80164
def validate_queues(self):
81165
"Checks if a worker is given atleast one queue to work on."
82166
if not self.queues:
@@ -114,18 +198,20 @@ def _check_commands(self):
114198
if not self._shutdown:
115199
logging.debug('Checking commands')
116200
command_key = 'resque:khan:%s' % self
117-
command = self.resq.redis.lpop(command_key)
118-
logging.debug('COMMAND FOUND:', command)
201+
202+
command = self.resq.redis.lpop('resque:khan:%s' % str(self))
203+
logging.debug('COMMAND FOUND: %s ' % command)
119204
if command:
205+
import pdb;pdb.set_trace()
120206
self.process_command(command)
121207
self._check_commands()
122208

123209
def process_command(self, command):
124-
print 'Processing Command'
210+
logging.info('Processing Command')
125211
#available commands, shutdown, add 1, remove 1
126-
command = self._command_map.get(command, None)
127-
if command:
128-
fn = getattr(self, command)
212+
command_item = self._command_map.get(command, None)
213+
if command_item:
214+
fn = getattr(self, command_item)
129215
if fn:
130216
fn()
131217

@@ -138,8 +224,6 @@ def _add_minion(self):
138224
#parent_conn, child_conn = multiprocessing.Pipe()
139225
m = Minion(self.queues, self.server, self.password)
140226
#m.start()
141-
self._workers[m.pid] = m
142-
logging.info('minion added at %s' % m.pid)
143227
return m
144228
#self._workers.append(m)
145229

@@ -160,21 +244,23 @@ def _remove_minion(self, pid=None):
160244

161245
def register_worker(self):
162246
logging.debug('registering khan')
163-
self.resq.redis.sadd('resque:khans',str(self))
247+
#self.resq.redis.sadd('resque:khans',str(self))
164248
#self.resq._redis.add("worker:#{self}:started", Time.now.to_s)
165-
self.started = datetime.datetime.now()
249+
#self.started = datetime.datetime.now()
166250

167251
def unregister_worker(self):
168252
logging.debug('unregistering khan')
169253
self.resq.redis.srem('resque:khans',str(self))
170254
self.started = None
171255

172-
def work(self, interval=5):
256+
def work(self, interval=2):
173257
self.startup()
174258
for i in range(self.pool_size):
175259
m = self._add_minion()
176260
m.start()
177-
261+
self._workers[m.pid] = m
262+
logging.info('minion added at %s' % m.pid)
263+
self.setup_resq()
178264
while True:
179265
self._check_commands()
180266
if self._shutdown:

pyres/json_parser.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from datetime import datetime
22
try:
3-
import simplejson as json
4-
except ImportError:
3+
#import simplejson as json
54
import json
5+
except ImportError:
6+
import simplejson as json
67

78

89
DATE_FORMAT = '%Y-%m-%dT%H:%M:%S'

setup.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from setuptools import setup, find_packages
22

3-
version='0.7.5.1'
3+
version='0.8'
44
setup(
55
name='pyres',
66
version=version,
@@ -14,7 +14,11 @@
1414
download_url='http://cloud.github.com/downloads/binarydud/pyres/pyres-%s.tar.gz' % version,
1515
include_package_data=True,
1616
package_data={'resweb': ['templates/*.mustache','media/*']},
17-
scripts=['scripts/pyres_worker', 'scripts/pyres_web', 'scripts/pyres_scheduler'],
17+
scripts=[
18+
'scripts/pyres_worker',
19+
'scripts/pyres_web',
20+
'scripts/pyres_scheduler',
21+
'scripts/pyres_manager'],
1822
install_requires=[
1923
'simplejson>=2.0.9',
2024
'itty>=0.6.2',

tests/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class BasicMulti(object):
1515
queue = 'basic'
1616
@staticmethod
1717
def perform(name, age):
18-
print 'name: %s, age: %s'
18+
print 'name: %s, age: %s' % (name, age)
1919

2020

2121
class ReturnAllArgsJob(object):

0 commit comments

Comments
 (0)