Commit Graph

578 Commits

Author SHA1 Message Date
Selwin Ong fc86e9ab5e
Jobs can return Retry object to retry execution (#2159)
* Jobs can return a Retry object

* Fix test on Redis < 5

* Fix ruff warnings

* Minor house keeping

* More minor fixes

* More typing improvements

* More fixes

* Fix typing
2024-12-01 15:58:05 +07:00
Nguyễn Hồng Quân 26a3577443
Replace Black with Ruff as formatter tool (#2152) 2024-11-20 15:34:27 +07:00
Ethan Wolinsky fb017d2c29
Delete expired groups from registry (#2150) 2024-11-20 08:08:33 +07:00
Alex Prabhat Bara dbbbd09463
Set ended_at for a job when using is_async=False (#2142)
* set ended_at for is_async=False job

* added test to check ended_at is set for is_async=False job
2024-11-16 14:56:51 +07:00
Uriel Sandoval b44ae85a8d
Adds validation to avoid ":" when user pass job_id (#2138) 2024-11-09 14:03:55 +07:00
François Charlier 3e2e26e702
Add an exception handler for the pubsub thread (#2132)
* Add an exception handler for the pubsub thread

After a connection error to Redis the pubsub thread was stopped and the
worker could not receive commands anymore.

This commit adds an exception handler for the thread that adds a log
message and ignores `redis.exceptions.ConnectionError`. Any other
exception is re-raised.

redis-py internal mechanism allows the pubsub thread to recover its
connection and reinstall the pubsub channel subscription to allow the
worker to receive commands again after connection errors.

It tries to behave the same as the main worker loop retry mechanism but
without the backoff wait factor.

Fixes #1836
Fixes #2070

* Add test for untested line, improve logging and comments

Add *args & **kwargs to tests.fixtures.raise_exc to pass tests with Python 3.7
2024-10-17 11:15:47 +07:00
Anton Daneyko f4283afe68
Allow to get job count and job IDs without cleanup (#2133)
Prior to this commit it was not possible to get a number of jobs in a
registry or list job IDs without triggering a cleanup.
Calling cleanup caused issues for:
 * Monitoring tools (see https://github.com/rq/rq/pull/2104) and
 * Cases with high number of jobs in the registries (see
   https://github.com/rq/rq/pull/2003).
 * Cases where a failure callback is registered and but the
   `get_job_ids` is called not from the main thread.

In this commit:
 1. A new `BaseRegistry.get_job_count` method is added. It is a side
    effect free version of `BaseRegistry.count` and runs in O(1).
 2. A `cleanup` parameter added to `get_job_ids` that allows to avoid
    clean up if it is set to `False`.

Resolves https://github.com/rq/rq/pull/2104.
Resolves https://github.com/rq/rq/pull/2003.
2024-10-17 11:14:54 +07:00
Selwin Ong ba5c338441 Fix flaky tests 2024-10-13 07:27:23 +07:00
Bobby Watson 809a20a8cc
[AWS Elasticache Serverless Redis] Handle redis servers that return non-string versions (#2131)
* Handle redis servers that return non-string versions

* Add tests for AWS elasticache redis version output
2024-10-13 07:09:13 +07:00
Selwin Ong fda862e600
RQ execution fixes (#2128)
* Execution objects now return UTC timestamps

* execution.job should return a full Job instance

* worker.maintain_heartbeats() should extend execution TTL

* Don't use cached_property since it's not supported on Python 3.7

* Fixed type hint of execution._job
2024-10-02 09:13:13 +07:00
Selwin Ong 9d35ed106d
Worker ttl clarifications (#2126)
* add info about running docs in README

* update jekyll config to fix error

* update docs to clarify misc timeout values

* update readme

* update argument from default_worker_ttl -> worker_ttl

* Fix black formatting

* argument should still be respected until it's deprecated

* Updated CHANGES.md

* Updated CHANGES.md

---------

Co-authored-by: Sean Villars <sean@setpoint.io>
2024-09-16 11:37:00 +07:00
Terence Honles ccdff1f003
Ensure the Redis socket timeout is long enough for blocking operations (#2120)
This change checks for Redis connection socket timeouts that are too
short for operations such as BLPOP, and adjusts them to at least be the
expected timeout.
2024-09-07 08:53:55 +07:00
Harm Berntsen 193de26cff
Implement TTL for deferred jobs (#2111)
* Add new deferred_ttl attribute to jobs

* Add DeferredJobRegistry to cleanup

* Use normal ttl for deferred jobs as well

* Test that jobs landing in deferred queue get a TTL

* Pass pipeline in job cleanup

* Remove cleanup call

We pass a ttl of -1 which does not do anything

* Pass exc_info to add

The add implementation overwrites it so it won't get lost this way

* Remove extraneous save call

The add function already saves the job for us. So no need to save it
twice.

* Tune cleanup function description

* Test cleanup also works for deleted jobs

* Replace testconn with connection

---------

Co-authored-by: Raymond Guo <raymond.guo@databricks.com>
2024-08-11 19:23:28 +07:00
Selwin Ong e21d1ae133
Remove RQTestCase.testconn (#2109)
* Remove self.testconn from RQTestCase

* Minor cleanup

* Remove the use of self.testconn.
2024-08-04 10:11:47 +07:00
Maria Khrustaleva 5cfd853546
Enqueue dependents when job is abandoned and moved to FailedJobRegistry (#2008)
* Enqueue dependents when job is abandoned

* Add test

* Run CI
2024-07-18 10:16:09 +07:00
Simó Albert i Beltran df5e99ba0b
Register queue also for deferred job (#2108)
* Add test to list queue with only deferred jobs

Signed-off-by: Simó Albert i Beltran <sim6@probeta.net>

* Register queue also for deferred job

Without this change queues initialized with only deferred jobs are not
listed by `rq.Queue.all()`.

Signed-off-by: Simó Albert i Beltran <sim6@probeta.net>

---------

Signed-off-by: Simó Albert i Beltran <sim6@probeta.net>
2024-07-18 09:42:21 +07:00
Joe Carey 180c9afba0
Update Job.get_status and Job.restore to consistently return JobStatus Enum (#2039)
* fix #2038

* raise exception if there is no status in redis

* add get_status failure test
2024-05-26 09:37:55 +07:00
Selwin Ong 4c28ec617a
Delete legacy.py (#2083)
* Delete legacy.py

* Deleted Sentry's built in integration.

* Fixed ruff warnings.
2024-05-02 08:20:41 +07:00
Selwin Ong b52457afb6 Merge branch 'v1' 2024-05-01 14:20:29 +07:00
Selwin Ong e2d144d772 Moved intermediate queue cleaning functionality to intermediate_queue.cleanup() 2024-04-28 20:48:07 +07:00
Selwin Ong a7f19d966f Done implementing clean_intermediate_queue() 2024-04-28 20:32:30 +07:00
Selwin Ong aae428500c Skip intermediate queue tests if Redis < 6.2.0 2024-04-28 19:51:21 +07:00
Selwin Ong 3ca348049f Ensure intermediate_queue is empty before running tests 2024-04-28 19:37:53 +07:00
Selwin Ong 7d4c7eee30 Added intermediate_queue.get_job_ids() 2024-04-28 19:24:24 +07:00
Selwin Ong 50467b4d58 Made IntermediateQueue class 2024-04-27 19:54:20 +07:00
Selwin Ong 673b70dad0 Fix test_clean_large_registry 2024-04-27 15:00:42 +07:00
Selwin Ong fd261d5d8f Fix test_clean_large_registry 2024-04-13 14:38:53 +07:00
Ethan Wolinsky 2fc5484852
Execute custom handlers when abandoned job is found (#2057)
* Execute custom handlers when abandoned job is found

* Make exception_handlers optional

* Run exception handlers before checking retry

* Test abandoned job handler is called

* Improve test coverage

* Fix handler order
2024-03-23 16:46:07 +07:00
Selwin Ong bab0061da1
Removed utils.utcnow() (#2056)
* Bump version to 1.16.1

* Partially replaced utcnow() with now()

* Removed utils.utcnow

* Fix lint
2024-03-11 19:44:12 +07:00
Ethan Wolinsky 3a3787dcc3
Group jobs into batches and retrieve by batch name (#1945)
* Batch.py initial commit

* Add method to refresh batch status

* Clean up Redis key properties

* Remove persist_job method

* Execute refresh method when fetching batch

* Add batch_id to job

* Add option to batch jobs with enqueue_many

* Add set_batch_id method

* Handle batch_ttl when job is started

* Renew ttl on all jobs in batch when a job finishes

* Use fetch_jobs method in refresh()

* Remove batch TTL

During worker maintenance task, worker will loop through batches and
delete expired jobs.
When all jobs are expired, the batch is deleted.

* Fix buggy connection

* Raise batch error in fetch method

* Fix fetch connection arg

* Add testing for batch

* Remove unused import

* Update batch documentation

* Add batch ID to job persistence test

* Test that empty batch is removed from batch list

* Make default batch ID full uuid4 to match Job

* Add method to return batch key

* Add all method to return iterable of batches

* Revert changes to queue.py

* Separate batch creating from job enqueueing.

Batches can be created by passing an array of jobs.

* Fix bug with stopped callback in enqueue_many

* Rename delete_expired_jobs batch method

* Use exists to identify expired jobs

* Remove jobs attribute from batch

Jobs have to be explicitly fetched using the get_jobs method

* Don't add batch_id to job in _add_jobs method

This should be done when the job is created before it is saved to redis.

* Use cleanup method to determine if batch should be deleted

* Add get_jobs method

This method will return an array of jobs belonging to the batch.

* Update create method to not allow jobs arg

Jobs should be added to batches in the Queue.enqueue_many
function

* Add batch_id to job create method

* Delete set_batch_id method

The batch ID should be set atomically when the job is created

* Add batch argument to queue.enqueue_many

This will be how jobs can be batched. The batch ID is added to each job
created by enqueue_many, and then those jobs are all added to the batch
in Redis using the batch's _add_jobs method

* Update batch tests to use new enqueue_many arg

* Fix batch_id for non_batched jobs

* Use different pipeline name

* Don't use fetch method when enqueuing jobs

If the batch is empty, fetch will delete it from Redis

* Test enqueuing batched jobs with string ID

* Update batch documentation

* Remove unused variables

* Fix expired job tracking bug

* Add delete_job method

* Use delete_job method on batch

* Pass multiple jobs into srem command

* Add multiple keys to exists call

* Pipeline _add_jobs call

* Fix missing job_id arg

* Move clean_batch_registry to Batch class

* Remove unused variables

* Fix missing dependency deletion

I accidentally deleted this earlier

* Move batch enqueueing to batch class

* Update batch docs

* Add test for batched jobs with str queue arg

* Don't delete batch in cleanup

* Change Batch to Group

* Import EnqueueData for type hint

* Sort imports

* Remove local config file

* Rename clean_group_registries method

* Update feature version

* Fix group constant names

* Only allow Queue in enqueue many

* Move cleanup logic to classmethod

* Remove str group test

* Remove unused import

* Make pipeline mandatory in _add_jobs method

* Rename expired job ids array

* Add slow decorator

* Assert job 1 data in group

* Rename id arg to name

* Only run cleanup when jobs are retrieved

* Remove job_ids variable

* Fix group name arg

* Fix group name arg

* Clean groups before fetching

* Use uuid4().hex for shorter id

* Move cleanup logic to instance method

* Use all method when cleaning group registry

* Check if group exists instead of catching error

* Cleanup expired jobs

* Apply black formatting

* Fix black formatting

* Pipeline group cleanup

* Fix pipeline call to exists

* Add pyenv version file

* Remove group cleanup after job completes

* Use existing pipeline

* Remove unneeded pipeline check

* Fix empty call

* Test group __repr__ method

* Remove unnecessary pipeline assignment

* Remove unused delete method

* Fix pipeline name

* Remove unnecessary conditional block
2024-03-11 15:08:53 +07:00
Selwin Ong 97b2d83164 Minor test case change to trigger Github Actions 2024-02-24 10:19:23 +07:00
Rob Hudson 0935f47213 Store project metadata in pyproject.toml (PEP 621) (#1952) 2024-02-24 10:07:56 +07:00
Ethan Wolinsky efd4bd82d7 Delete maintenance lock after registries cleaned (#2024)
* Delete maintenance lock after registries cleaned

* Fix test to assert that lock is released

* Remove deprecated test case
2024-02-24 09:54:47 +07:00
Ethan Wolinsky 1e6953b534 Fix bug with stopped callback in enqueue_many (#1954)
* Fix bug with stopped callback in enqueue_many

* Add test for callbacks enqueued using enqueue_many
2024-02-24 09:51:20 +07:00
Christofer Saputra 49f12451ba Set workerpool with_scheduler defaults to True (#2027)
* Set workerpool with_scheduler defaults to True

* Add delay before sending shutdown command

* Black format

* Delay a bit longer for test
2024-02-24 09:50:26 +07:00
Andrew Nisbet 87da060648 Add result blocking (#1939)
* Add result blocking

* Dev tidyup

* Skip XREAD test on old redis versions

* Lint

* Clarify that the latest result is returned.

* Fix job test ordering

* Remove test latency hack

* Readability improvements
2024-02-24 09:48:28 +07:00
Ethan Wolinsky 690a6451db
Delete maintenance lock after registries cleaned (#2024)
* Delete maintenance lock after registries cleaned

* Fix test to assert that lock is released

* Remove deprecated test case
2024-02-24 09:44:44 +07:00
Selwin Ong 67624eba0b
Deprecate current connection (#2043)
* Removed pop_connection from Worker.find_by_key()

* Removed push_connection from worker.work()

* Remove push_connection from workers.py and cli

* Remove get_current_connection() from worker._set_connection()

* Fix failing tests

* Removed the use of get_current_connection()

* WIP removing get_connection()

* Fixed tests in test_dependencies.py

* Fixed a few test files

* test_worker.py now passes

* Fix HerokuWorker

* Fix schedule_access_self test

* Fix ruff errors
2024-02-21 07:37:15 +07:00
Christofer Saputra dcf644596d
Set workerpool with_scheduler defaults to True (#2027)
* Set workerpool with_scheduler defaults to True

* Add delay before sending shutdown command

* Black format

* Delay a bit longer for test
2024-02-13 09:33:06 +07:00
Mindiell a8209391ff
Fix 'quiet' option for 'worker_pool' comand (#2010)
* Fix 'quiet' option for 'worker_pool' comand

* Added test for 'quiet' option

---------

Co-authored-by: Mindiell <mindiell@mindiell.net>
2023-12-24 10:16:18 +07:00
Selwin Ong 3c89f9dada
Job with multiple executions (#1964)
* Initial work on Execution class

* Executions are now created and deleted when jobs are performed

* Added execution.heartbeat()

* Added a way to get execution IDs from execution registry

* Job.fetch should also support execution composite key

* Added ExecutionRegistry.get_executions()

* execution.heartbeat() now also updates StartedJobRegistry

* Added job.get_executions()

* Added worker.prepare_execution()

* Simplified start_worker function in fixtures.py

* Minor test fixes

* Black

* Fixed a failing shutdown test

* Removed Execution.create from worker.prepare_job_execution

* Fix Sentry test

* Minor fixes

* Better test coverage

* Readded back worker.set_current_job_working_time()

* Reverse the order of handle_exception and handle_job_failure

* Fix SSL test

* job.delete() also deletes executions.

* Set job._status to FAILED as soon as job raises an exception

* Exclusively use execution.composite_key in StartedJobRegistry

* Use codecov v3

* Format with black

* Remove print statement

* Remove Redis server 3 from tests

* Remove support for Redis server < 4

* Fixed ruff warnings

* Added tests and remove unused code

* Linting fixes
2023-11-03 17:05:59 +07:00
Craig de Stigter a044248430
Don't use `os.setsid()` after forking workhorse (#1970)
In 9adcd7e50c a change was made to make
the workhorse process into a session leader. This appears to have been
done in order to set the process group ID of the workhorse so that it
can be killed easily along with its descendants when
`Worker.kill_horse()` is called.

However, `setsid` is overkill for this purpose; it sets not only the
process group ID but also the session ID. This can cause issues for user
jobs which may rely on session IDs being less-than-unique for arbitrary
reasons.

This change switches to `setpgrp`; this sets the process group ID so
that the workhorse and its descendants can be killed *without* changing
the session ID.
2023-09-23 17:35:29 +07:00
Selwin Ong 0f4d041578
Worker methods cleanup (#1967)
* Moved some common methods to BaseWorker

* Cleaned up more worker methods

* Warning cleanups

* Fix tests
2023-08-17 08:44:46 +07:00
Ethan Wolinsky 89fa8ae0b5
Fix bug with stopped callback in enqueue_many (#1954)
* Fix bug with stopped callback in enqueue_many

* Add test for callbacks enqueued using enqueue_many
2023-07-19 10:46:48 +07:00
Rob Hudson 9933128dd2
Store project metadata in pyproject.toml (PEP 621) (#1952) 2023-07-09 17:34:25 +07:00
Rob Hudson d756867914
Add the Python dev packages for Python headers to tests/Dockerfile (#1951)
* Add the Python dev packages for Python headers

* Drop support for Python 3.6 in testing workflows
2023-06-29 09:54:44 +07:00
Andrew Nisbet 2d705f5d1c
Add result blocking (#1939)
* Add result blocking

* Dev tidyup

* Skip XREAD test on old redis versions

* Lint

* Clarify that the latest result is returned.

* Fix job test ordering

* Remove test latency hack

* Readability improvements
2023-06-21 08:53:42 +07:00
Fred Söderberg d4159ee804
Do not run dependent jobs when parent or job is canceled (#1947) 2023-06-18 10:25:12 +07:00
Simon Blanchard c2bec19b09
pass exc_string as an argument to log (#1934)
* pass exc_string as an argument to log

* fix test of exception log by accessing right arg

* fix black "error"
2023-06-08 15:55:58 +07:00
Rishabh Ranjan a53966c918
callback func as string (#1905)
* callback func as string

* add tests for string callbacks; update documentation and type annotations

* lint

* concise test for string callback

* add string callbacks to existing tests

* remove string callback testcase; extend existing testcases
2023-05-26 08:40:56 +07:00