Skip to content

Commit a6ef208

Browse files
committed
Merge branch 'sunbirddcim-Use_skip_locked'
2 parents e8c88e5 + 28acedb commit a6ef208

4 files changed

Lines changed: 10 additions & 74 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
All notable changes to this project will be documented in this file.
44

5-
## Unreleased, 3.3.0
5+
## [MASTER] - WIP - 2019-07-18
66
- Fixed a bug in the offset calculation of `.enqueue_at`.
77
- Use the jsonb type for the args column from now on. If not available, fall back to json or text.
88
- `enqueue`, `enqueue_at`, `enqueue_in` return job hash with id.
@@ -13,6 +13,8 @@ All notable changes to this project will be documented in this file.
1313
- Change to only support >= Postgres 9.6. We will be bringing in newer changes and testing on only 9.6+ going forward.
1414
- Change to only support currently supported Ruby versions: 2.4, 2.5 and 2.6.
1515
- Add tests for installing fresh on rails 5.2.3 + running migrations
16+
- Bump to version 4, breaking changes (requirements of ruby, postgres)
17+
- Use skip-locked see - https://github.com/QueueClassic/queue_classic/pull/303
1618

1719
## [3.0.0rc] - 2014-01-07
1820

lib/queue_classic/queue.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,12 @@ def enqueue_in(seconds, method, *args)
9090

9191
def lock
9292
QC.log_yield(:measure => 'queue.lock') do
93-
s = "SELECT * FROM lock_head($1, $2)"
94-
if r = conn_adapter.execute(s, name, top_bound)
93+
s = "UPDATE queue_classic_jobs SET locked_at = now(), locked_by = pg_backend_pid()
94+
WHERE id IN ( SELECT id FROM queue_classic_jobs WHERE locked_at IS NULL AND
95+
q_name = $1 AND scheduled_at <= now() LIMIT 1 FOR NO KEY UPDATE SKIP LOCKED )
96+
RETURNING *"
97+
98+
if r = conn_adapter.execute(s, name)
9599
{}.tap do |job|
96100
job[:id] = r["id"]
97101
job[:q_name] = r["q_name"]

lib/queue_classic/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module QC
4-
VERSION = "3.3.0.ALPHA"
4+
VERSION = "4.0.0-alpha1"
55
end

sql/ddl.sql

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,3 @@
1-
-- We are declaring the return type to be queue_classic_jobs.
2-
-- This is ok since I am assuming that all of the users added queues will
3-
-- have identical columns to queue_classic_jobs.
4-
-- When QC supports queues with columns other than the default, we will have to change this.
5-
6-
CREATE OR REPLACE FUNCTION lock_head(q_name varchar, top_boundary integer)
7-
RETURNS SETOF queue_classic_jobs AS $$
8-
DECLARE
9-
unlocked bigint;
10-
relative_top integer;
11-
job_count integer;
12-
BEGIN
13-
-- The purpose is to release contention for the first spot in the table.
14-
-- The select count(*) is going to slow down dequeue performance but allow
15-
-- for more workers. Would love to see some optimization here...
16-
17-
EXECUTE 'SELECT count(*) FROM '
18-
|| '(SELECT * FROM queue_classic_jobs '
19-
|| ' WHERE locked_at IS NULL'
20-
|| ' AND q_name = '
21-
|| quote_literal(q_name)
22-
|| ' AND scheduled_at <= '
23-
|| quote_literal(now())
24-
|| ' LIMIT '
25-
|| quote_literal(top_boundary)
26-
|| ') limited'
27-
INTO job_count;
28-
29-
SELECT TRUNC(random() * (top_boundary - 1))
30-
INTO relative_top;
31-
32-
IF job_count < top_boundary THEN
33-
relative_top = 0;
34-
END IF;
35-
36-
LOOP
37-
BEGIN
38-
EXECUTE 'SELECT id FROM queue_classic_jobs '
39-
|| ' WHERE locked_at IS NULL'
40-
|| ' AND q_name = '
41-
|| quote_literal(q_name)
42-
|| ' AND scheduled_at <= '
43-
|| quote_literal(now())
44-
|| ' ORDER BY id ASC'
45-
|| ' LIMIT 1'
46-
|| ' OFFSET ' || quote_literal(relative_top)
47-
|| ' FOR UPDATE NOWAIT'
48-
INTO unlocked;
49-
EXIT;
50-
EXCEPTION
51-
WHEN lock_not_available THEN
52-
-- do nothing. loop again and hope we get a lock
53-
END;
54-
END LOOP;
55-
56-
RETURN QUERY EXECUTE 'UPDATE queue_classic_jobs '
57-
|| ' SET locked_at = (CURRENT_TIMESTAMP),'
58-
|| ' locked_by = (select pg_backend_pid())'
59-
|| ' WHERE id = $1'
60-
|| ' AND locked_at is NULL'
61-
|| ' RETURNING *'
62-
USING unlocked;
63-
64-
RETURN;
65-
END $$ LANGUAGE plpgsql;
66-
67-
CREATE OR REPLACE FUNCTION lock_head(tname varchar) RETURNS SETOF queue_classic_jobs AS $$ BEGIN
68-
RETURN QUERY EXECUTE 'SELECT * FROM lock_head($1,10)' USING tname;
69-
END $$ LANGUAGE plpgsql;
70-
711
-- queue_classic_notify function and trigger
722
CREATE FUNCTION queue_classic_notify() RETURNS TRIGGER AS $$ BEGIN
733
perform pg_notify(new.q_name, ''); RETURN NULL;

0 commit comments

Comments
 (0)