Remove dependency on 'times' library (see issue #286).

Basically, for the functionality needed, a dependency on 'times' (which
in turn depends on 'python-dateutil') seem unnecessary.
main
Malthe Borch 11 years ago
parent 09d461c2c0
commit c5a381fbe9

@ -1,6 +1,8 @@
### 0.4.0 ### 0.4.0
(not released yet) (not released yet)
- Removed dependency on the `times` library. Thanks, Malthe!
- Job dependencies! Thanks, Selwin. - Job dependencies! Thanks, Selwin.
- `Queue.all()` and `rqinfo` now report empty queues, too. Thanks, Rob! - `Queue.all()` and `rqinfo` now report empty queues, too. Thanks, Rob!

@ -1,5 +1,4 @@
import inspect import inspect
import times
from uuid import uuid4 from uuid import uuid4
try: try:
from cPickle import loads, dumps, UnpicklingError from cPickle import loads, dumps, UnpicklingError
@ -8,7 +7,7 @@ except ImportError: # noqa
from .local import LocalStack from .local import LocalStack
from .connections import resolve_connection from .connections import resolve_connection
from .exceptions import UnpickleError, NoSuchJobError from .exceptions import UnpickleError, NoSuchJobError
from .utils import import_attribute from .utils import import_attribute, utcnow, utcformat, utcparse
from rq.compat import text_type, decode_redis_hash, as_text from rq.compat import text_type, decode_redis_hash, as_text
@ -192,7 +191,7 @@ class Job(object):
def __init__(self, id=None, connection=None): def __init__(self, id=None, connection=None):
self.connection = resolve_connection(connection) self.connection = resolve_connection(connection)
self._id = id self._id = id
self.created_at = times.now() self.created_at = utcnow()
self._func_name = None self._func_name = None
self._instance = None self._instance = None
self._args = None self._args = None
@ -293,9 +292,9 @@ class Job(object):
def to_date(date_str): def to_date(date_str):
if date_str is None: if date_str is None:
return None return
else: else:
return times.to_universal(as_text(date_str)) return utcparse(as_text(date_str))
try: try:
self.data = obj['data'] self.data = obj['data']
@ -323,7 +322,7 @@ class Job(object):
def dump(self): def dump(self):
"""Returns a serialization of the current job instance""" """Returns a serialization of the current job instance"""
obj = {} obj = {}
obj['created_at'] = times.format(self.created_at or times.now(), 'UTC') obj['created_at'] = utcformat(self.created_at or utcnow())
if self.func_name is not None: if self.func_name is not None:
obj['data'] = dumps(self.job_tuple) obj['data'] = dumps(self.job_tuple)
@ -332,9 +331,9 @@ class Job(object):
if self.description is not None: if self.description is not None:
obj['description'] = self.description obj['description'] = self.description
if self.enqueued_at is not None: if self.enqueued_at is not None:
obj['enqueued_at'] = times.format(self.enqueued_at, 'UTC') obj['enqueued_at'] = utcformat(self.enqueued_at)
if self.ended_at is not None: if self.ended_at is not None:
obj['ended_at'] = times.format(self.ended_at, 'UTC') obj['ended_at'] = utcformat(self.ended_at)
if self._result is not None: if self._result is not None:
obj['result'] = dumps(self._result) obj['result'] = dumps(self._result)
if self.exc_info is not None: if self.exc_info is not None:

@ -1,8 +1,8 @@
import times
import uuid import uuid
from .connections import resolve_connection from .connections import resolve_connection
from .job import Job, Status from .job import Job, Status
from .utils import utcnow
from .exceptions import (DequeueTimeout, InvalidJobOperationError, from .exceptions import (DequeueTimeout, InvalidJobOperationError,
NoSuchJobError, UnpickleError) NoSuchJobError, UnpickleError)
@ -225,7 +225,7 @@ class Queue(object):
if set_meta_data: if set_meta_data:
job.origin = self.name job.origin = self.name
job.enqueued_at = times.now() job.enqueued_at = utcnow()
if job.timeout is None: if job.timeout is None:
job.timeout = self.DEFAULT_TIMEOUT job.timeout = self.DEFAULT_TIMEOUT
@ -371,7 +371,7 @@ class FailedQueue(Queue):
must not be overridden (e.g. `origin` or `enqueued_at`) and other meta must not be overridden (e.g. `origin` or `enqueued_at`) and other meta
data must be inserted (`ended_at` and `exc_info`). data must be inserted (`ended_at` and `exc_info`).
""" """
job.ended_at = times.now() job.ended_at = utcnow()
job.exc_info = exc_info job.exc_info = exc_info
return self.enqueue_job(job, set_meta_data=False) return self.enqueue_job(job, set_meta_data=False)

@ -6,6 +6,7 @@ The formatter for ANSI colored console output is heavily based on Pygments
terminal colorizing code, originally by Georg Brandl. terminal colorizing code, originally by Georg Brandl.
""" """
import importlib import importlib
import datetime
import logging import logging
import os import os
import sys import sys
@ -168,3 +169,15 @@ def import_attribute(name):
module_name, attribute = name.rsplit('.', 1) module_name, attribute = name.rsplit('.', 1)
module = importlib.import_module(module_name) module = importlib.import_module(module_name)
return getattr(module, attribute) return getattr(module, attribute)
def utcnow():
return datetime.datetime.utcnow()
def utcformat(dt):
return dt.strftime(u"%Y-%m-%dT%H:%M:%SZ")
def utcparse(string):
return datetime.datetime.strptime(string, "%Y-%m-%dT%H:%M:%SZ")

@ -3,7 +3,6 @@ import os
import errno import errno
import random import random
import time import time
import times
try: try:
from procname import setprocname from procname import setprocname
except ImportError: except ImportError:
@ -16,7 +15,7 @@ import logging
from .queue import Queue, get_failed_queue from .queue import Queue, get_failed_queue
from .connections import get_current_connection from .connections import get_current_connection
from .job import Job, Status from .job import Job, Status
from .utils import make_colorizer from .utils import make_colorizer, utcnow, utcformat
from .logutils import setup_loghandlers from .logutils import setup_loghandlers
from .exceptions import NoQueueError, UnpickleError, DequeueTimeout from .exceptions import NoQueueError, UnpickleError, DequeueTimeout
from .timeouts import death_penalty_after from .timeouts import death_penalty_after
@ -197,7 +196,7 @@ class Worker(object):
queues = ','.join(self.queue_names()) queues = ','.join(self.queue_names())
with self.connection._pipeline() as p: with self.connection._pipeline() as p:
p.delete(key) p.delete(key)
p.hset(key, 'birth', times.format(times.now(), 'UTC')) p.hset(key, 'birth', utcformat(utcnow()))
p.hset(key, 'queues', queues) p.hset(key, 'queues', queues)
p.sadd(self.redis_workers_keys, key) p.sadd(self.redis_workers_keys, key)
p.expire(key, self.default_worker_ttl) p.expire(key, self.default_worker_ttl)
@ -210,7 +209,7 @@ class Worker(object):
# We cannot use self.state = 'dead' here, because that would # We cannot use self.state = 'dead' here, because that would
# rollback the pipeline # rollback the pipeline
p.srem(self.redis_workers_keys, self.key) p.srem(self.redis_workers_keys, self.key)
p.hset(self.key, 'death', times.format(times.now(), 'UTC')) p.hset(self.key, 'death', utcformat(utcnow()))
p.expire(self.key, 60) p.expire(self.key, 60)
p.execute() p.execute()
@ -410,7 +409,7 @@ class Worker(object):
# use the same exc handling when pickling fails # use the same exc handling when pickling fails
job._result = rv job._result = rv
job._status = Status.FINISHED job._status = Status.FINISHED
job.ended_at = times.now() job.ended_at = utcnow()
result_ttl = job.get_ttl(self.default_result_ttl) result_ttl = job.get_ttl(self.default_result_ttl)
pipeline = self.connection._pipeline() pipeline = self.connection._pipeline()

@ -17,7 +17,7 @@ def get_version():
def get_dependencies(): def get_dependencies():
deps = ['redis >= 2.4.13', 'times'] deps = ['redis >= 2.4.13']
if sys.version_info < (2, 7) or \ if sys.version_info < (2, 7) or \
(sys.version_info >= (3, 0) and sys.version_info < (3, 1)): (sys.version_info >= (3, 0) and sys.version_info < (3, 1)):
deps += ['importlib'] deps += ['importlib']

@ -1,6 +1,6 @@
import times from datetime import timedelta
def strip_milliseconds(date): def strip_microseconds(date):
return times.to_universal(times.format(date, 'UTC')) return date - timedelta(microseconds=date.microsecond)

@ -1,8 +1,7 @@
import times
from datetime import datetime from datetime import datetime
from tests import RQTestCase from tests import RQTestCase
from tests.fixtures import Number, some_calculation, say_hello, access_self from tests.fixtures import Number, some_calculation, say_hello, access_self
from tests.helpers import strip_milliseconds from tests.helpers import strip_microseconds
try: try:
from cPickle import loads from cPickle import loads
except ImportError: except ImportError:
@ -11,6 +10,7 @@ from rq.compat import as_text
from rq.job import Job, get_current_job from rq.job import Job, get_current_job
from rq.exceptions import NoSuchJobError, UnpickleError from rq.exceptions import NoSuchJobError, UnpickleError
from rq.queue import Queue from rq.queue import Queue
from rq.utils import utcformat
class TestJob(RQTestCase): class TestJob(RQTestCase):
@ -91,7 +91,7 @@ class TestJob(RQTestCase):
self.testconn.hset('rq:job:some_id', 'data', self.testconn.hset('rq:job:some_id', 'data',
"(S'tests.fixtures.some_calculation'\nN(I3\nI4\nt(dp1\nS'z'\nI2\nstp2\n.") "(S'tests.fixtures.some_calculation'\nN(I3\nI4\nt(dp1\nS'z'\nI2\nstp2\n.")
self.testconn.hset('rq:job:some_id', 'created_at', self.testconn.hset('rq:job:some_id', 'created_at',
'2012-02-07 22:13:24+0000') '2012-02-07T22:13:24Z')
# Fetch returns a job # Fetch returns a job
job = Job.fetch('some_id') job = Job.fetch('some_id')
@ -108,11 +108,11 @@ class TestJob(RQTestCase):
job = Job() job = Job()
job.save() job.save()
expected_date = strip_milliseconds(job.created_at) expected_date = strip_microseconds(job.created_at)
stored_date = self.testconn.hget(job.key, 'created_at').decode('utf-8') stored_date = self.testconn.hget(job.key, 'created_at').decode('utf-8')
self.assertEquals( self.assertEquals(
times.to_universal(stored_date), stored_date,
expected_date) utcformat(expected_date))
# ... and no other keys are stored # ... and no other keys are stored
self.assertEqual( self.assertEqual(
@ -124,11 +124,11 @@ class TestJob(RQTestCase):
job = Job.create(func=some_calculation, args=(3, 4), kwargs=dict(z=2)) job = Job.create(func=some_calculation, args=(3, 4), kwargs=dict(z=2))
job.save() job.save()
expected_date = strip_milliseconds(job.created_at) expected_date = strip_microseconds(job.created_at)
stored_date = self.testconn.hget(job.key, 'created_at').decode('utf-8') stored_date = self.testconn.hget(job.key, 'created_at').decode('utf-8')
self.assertEquals( self.assertEquals(
times.to_universal(stored_date), stored_date,
expected_date) utcformat(expected_date))
# ... and no other keys are stored # ... and no other keys are stored
self.assertEqual( self.assertEqual(

@ -3,7 +3,7 @@ from time import sleep
from tests import RQTestCase, slow from tests import RQTestCase, slow
from tests.fixtures import say_hello, div_by_zero, do_nothing, create_file, \ from tests.fixtures import say_hello, div_by_zero, do_nothing, create_file, \
create_file_after_timeout create_file_after_timeout
from tests.helpers import strip_milliseconds from tests.helpers import strip_microseconds
from rq import Queue, Worker, get_failed_queue from rq import Queue, Worker, get_failed_queue
from rq.job import Job, Status from rq.job import Job, Status
@ -87,7 +87,7 @@ class TestWorker(RQTestCase):
self.assertEquals(q.count, 1) self.assertEquals(q.count, 1)
# keep for later # keep for later
enqueued_at_date = strip_milliseconds(job.enqueued_at) enqueued_at_date = strip_microseconds(job.enqueued_at)
w = Worker([q]) w = Worker([q])
w.work(burst=True) # should silently pass w.work(burst=True) # should silently pass

Loading…
Cancel
Save