Skip to content

Commit bb7de40

Browse files
committed
Merge remote branch 'chawco/feature/pyres-web-fixes' into chawco_merge
Conflicts: pyres/failure/redis.py pyres/worker.py resweb/views.py
2 parents 7d51b4e + 7c5e11d commit bb7de40

File tree

5 files changed

+36
-28
lines changed

5 files changed

+36
-28
lines changed

pyres/failure/base.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,36 @@
44
class BaseBackend(object):
55
"""Provides a base class that custom backends can subclass. Also provides basic
66
traceback and message parsing.
7-
7+
88
The ``__init__`` takes these keyword arguments:
9-
9+
1010
``exp`` -- The exception generated by your failure.
11-
11+
1212
``queue`` -- The queue in which the ``Job`` was enqueued when it failed.
13-
13+
1414
``payload`` -- The payload that was passed to the ``Job``.
15-
15+
1616
``worker`` -- The worker that was processing the ``Job`` when it failed.
17-
17+
1818
"""
1919
def __init__(self, exp, queue, payload, worker=None):
2020
excc, _, tb = sys.exc_info()
21-
21+
2222
self._exception = excc
2323
self._traceback = traceback.format_exc()
2424
self._worker = worker
2525
self._queue = queue
2626
self._payload = payload
27-
28-
27+
28+
2929
def _parse_traceback(self, trace):
3030
"""Return the given traceback string formatted for a notification."""
31-
return trace
32-
31+
if not trace:
32+
return []
33+
34+
return trace.split('\n')
35+
3336
def _parse_message(self, exc):
3437
"""Return a message for a notification from the given exception."""
3538
return '%s: %s' % (exc.__class__.__name__, str(exc))
36-
39+

pyres/failure/redis.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ def save(self, resq=None):
1212
if not resq:
1313
resq = ResQ()
1414
data = {
15-
'failed_at' : int(time.mktime(datetime.datetime.now().timetuple())),
15+
'failed_at' : datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'),
1616
'payload' : self._payload,
17+
'exception' : self._exception.__class__.__name__,
1718
'error' : self._parse_message(self._exception),
1819
'backtrace' : self._parse_traceback(self._traceback),
1920
'queue' : self._queue

pyres/worker.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,16 @@ def __str__(self):
112112
return '%s:%s:%s' % (self.hostname, self.pid, ','.join(self.queues))
113113

114114
def work(self, interval=5):
115-
"""Invoked by ``run`` method. ``work`` listens on a list of queues and
116-
sleeps for ``interval`` time.
115+
"""Invoked by ``run`` method. ``work`` listens on a list of queues and sleeps
116+
for ``interval`` time.
117117
118-
``interval`` -- Number of seconds the worker will wait until processing
119-
the next job. Default is "5".
118+
``interval`` -- Number of seconds the worker will wait until processing the next job. Default is "5".
120119
121120
Whenever a worker finds a job on the queue it first calls ``reserve`` on
122-
that job to make sure another worker won't run it, then *forks* itself
123-
to work on that job.
121+
that job to make sure another worker won't run it, then *forks* itself to
122+
work on that job.
124123
125-
Finally, the ``process`` method actually processes the job by eventually
126-
calling the Job instance's ``perform`` method.
124+
Finally, the ``process`` method actually processes the job by eventually calling the Job instance's ``perform`` method.
127125
128126
"""
129127
setproctitle('pyres_worker-%s: Starting' % __version__)
@@ -224,7 +222,7 @@ def working_on(self, job):
224222
logger.debug('marking as working on')
225223
data = {
226224
'queue': job._queue,
227-
'run_at': int(time.mktime(datetime.datetime.now().timetuple())),
225+
'run_at': str(int(time.mktime(datetime.datetime.now().timetuple()))),
228226
'payload': job._payload
229227
}
230228
data = json.dumps(data)
@@ -290,8 +288,7 @@ def all(cls, host="localhost:6379"):
290288
elif isinstance(host, ResQ):
291289
resq = host
292290

293-
return [Worker.find(w,resq)
294-
for w in resq.redis.smembers('resque:workers') or []]
291+
return [Worker.find(w,resq) for w in resq.redis.smembers('resque:workers') or []]
295292

296293
@classmethod
297294
def working(cls, host):

resweb/templates/failed.mustache

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ function delete_all(){
4141
<dd><code>{{payload_class}}</code></dd>
4242
<dt>Arguments</dt>
4343
<dd><pre>{{payload_args}}</pre></dd>
44+
<dt>Exception</dt>
45+
<dd><pre>{{exception}}</pre></dd>
4446
<dt>Error</dt>
4547
<dd>
4648
<a href="#" class="backtrace">{{error}}</a>
47-
<pre style='display:none'>{{traceback}}</pre>
49+
<pre style='display:none'>{{traceback}}</pre>
4850
</dd>
4951
<dt>
5052
Payload Actions

resweb/views.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def queue(self):
5555

5656
def queues(self):
5757
queues = []
58-
for q in self.resq.queues():
58+
for q in sorted(self.resq.queues()):
5959
queues.append({
6060
'queue': q,
6161
'size': str(self.resq.size(q)),
@@ -217,12 +217,17 @@ def size(self):
217217
def failed_jobs(self):
218218
jobs = []
219219
for job in failure.all(self.resq, self._start, self._start + 20):
220+
backtrace = job['backtrace']
221+
222+
if isinstance(backtrace, list):
223+
backtrace = '\n'.join(backtrace)
224+
220225
item = job
221-
item['failed_at'] = str(datetime.datetime.fromtimestamp(float(job['failed_at'])))
226+
item['failed_at'] = job['failed_at']
222227
item['worker_url'] = '/workers/%s/' % job['worker']
223228
item['payload_args'] = str(job['payload']['args'])[:1024]
224229
item['payload_class'] = job['payload']['class']
225-
item['traceback'] = job['backtrace']
230+
item['traceback'] = backtrace
226231
jobs.append(item)
227232

228233
return jobs

0 commit comments

Comments
 (0)