async-background 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/async/background/queue/store.rb +27 -17
- data/lib/async/background/runner.rb +8 -5
- data/lib/async/background/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c9a1ac97495dc7d6a39adf802a847b62e3601df0fe0ef4aa70dbcc248a2f77b8
|
|
4
|
+
data.tar.gz: 74bab717411caf3e8a7b469666e9df5f8f59d540ebd98446c5e44e167cacd3c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fe41a129f66a72c51016397b866ee9ff31b973d5e92ee6af1f61c05ce87f8f85f9824a68499caefcf950cdb33186c74749817e0ae8b89a483ede580d412e13fc
|
|
7
|
+
data.tar.gz: 92208ce41c49095cdf652b798ed892e4db5ae12c504cfe94c45bf124054256a94906fba14f68365f938a6d7289c76ca79d7ae7f6fac53bb76d8097d463db684f
|
|
@@ -7,6 +7,7 @@ module Async
|
|
|
7
7
|
module Queue
|
|
8
8
|
class Store
|
|
9
9
|
SCHEMA = <<~SQL
|
|
10
|
+
PRAGMA auto_vacuum = INCREMENTAL;
|
|
10
11
|
CREATE TABLE IF NOT EXISTS jobs (
|
|
11
12
|
id INTEGER PRIMARY KEY,
|
|
12
13
|
class_name TEXT NOT NULL,
|
|
@@ -16,26 +17,30 @@ module Async
|
|
|
16
17
|
locked_by INTEGER,
|
|
17
18
|
locked_at REAL
|
|
18
19
|
);
|
|
19
|
-
CREATE INDEX IF NOT EXISTS
|
|
20
|
+
CREATE INDEX IF NOT EXISTS idx_jobs_status_id ON jobs(status, id);
|
|
20
21
|
SQL
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
MMAP_SIZE = 268_435_456
|
|
24
|
+
PRAGMAS = ->(mmap_size) {
|
|
25
|
+
<<~SQL
|
|
26
|
+
PRAGMA journal_mode = WAL;
|
|
27
|
+
PRAGMA synchronous = NORMAL;
|
|
28
|
+
PRAGMA mmap_size = #{mmap_size};
|
|
29
|
+
PRAGMA cache_size = -16000;
|
|
30
|
+
PRAGMA temp_store = MEMORY;
|
|
31
|
+
PRAGMA busy_timeout = 5000;
|
|
32
|
+
PRAGMA journal_size_limit = 67108864;
|
|
33
|
+
SQL
|
|
34
|
+
}.freeze
|
|
31
35
|
|
|
32
36
|
CLEANUP_INTERVAL = 300
|
|
33
37
|
CLEANUP_AGE = 3600
|
|
34
38
|
|
|
35
39
|
attr_reader :path
|
|
36
40
|
|
|
37
|
-
def initialize(path: self.class.default_path)
|
|
41
|
+
def initialize(path: self.class.default_path, mmap: true)
|
|
38
42
|
@path = path
|
|
43
|
+
@mmap = mmap
|
|
39
44
|
@db = nil
|
|
40
45
|
@schema_checked = false
|
|
41
46
|
@last_cleanup_at = nil
|
|
@@ -44,7 +49,7 @@ module Async
|
|
|
44
49
|
def ensure_database!
|
|
45
50
|
require_sqlite3
|
|
46
51
|
db = SQLite3::Database.new(@path)
|
|
47
|
-
db.execute_batch(PRAGMAS)
|
|
52
|
+
db.execute_batch(PRAGMAS.call(@mmap ? MMAP_SIZE : 0))
|
|
48
53
|
db.execute_batch(SCHEMA)
|
|
49
54
|
db.execute("PRAGMA wal_checkpoint(TRUNCATE)")
|
|
50
55
|
db.close
|
|
@@ -59,11 +64,16 @@ module Async
|
|
|
59
64
|
|
|
60
65
|
def fetch(worker_id)
|
|
61
66
|
ensure_connection
|
|
67
|
+
@db.execute("BEGIN IMMEDIATE")
|
|
62
68
|
row = @fetch_stmt.execute(worker_id, realtime_now).first
|
|
69
|
+
@db.execute("COMMIT")
|
|
63
70
|
return unless row
|
|
64
71
|
|
|
65
72
|
maybe_cleanup
|
|
66
73
|
{ id: row[0], class_name: row[1], args: JSON.parse(row[2]) }
|
|
74
|
+
rescue
|
|
75
|
+
@db.execute("ROLLBACK") rescue nil
|
|
76
|
+
raise
|
|
67
77
|
end
|
|
68
78
|
|
|
69
79
|
def complete(job_id)
|
|
@@ -86,7 +96,7 @@ module Async
|
|
|
86
96
|
return unless @db && !@db.closed?
|
|
87
97
|
|
|
88
98
|
finalize_statements
|
|
89
|
-
@db.execute("PRAGMA optimize")
|
|
99
|
+
@db.execute("PRAGMA optimize") rescue nil
|
|
90
100
|
@db.close
|
|
91
101
|
@db = nil
|
|
92
102
|
end
|
|
@@ -111,7 +121,7 @@ module Async
|
|
|
111
121
|
require_sqlite3
|
|
112
122
|
finalize_statements
|
|
113
123
|
@db = SQLite3::Database.new(@path)
|
|
114
|
-
@db.execute_batch(PRAGMAS)
|
|
124
|
+
@db.execute_batch(PRAGMAS.call(@mmap ? MMAP_SIZE : 0))
|
|
115
125
|
|
|
116
126
|
unless @schema_checked
|
|
117
127
|
@db.execute_batch(SCHEMA)
|
|
@@ -151,10 +161,10 @@ module Async
|
|
|
151
161
|
end
|
|
152
162
|
|
|
153
163
|
def finalize_statements
|
|
154
|
-
%i[
|
|
155
|
-
stmt = instance_variable_get(name)
|
|
164
|
+
%i[enqueue_stmt fetch_stmt complete_stmt fail_stmt requeue_stmt cleanup_stmt].each do |name|
|
|
165
|
+
stmt = instance_variable_get(:"@#{name}")
|
|
156
166
|
stmt&.close rescue nil
|
|
157
|
-
instance_variable_set(name, nil)
|
|
167
|
+
instance_variable_set(:"@#{name}", nil)
|
|
158
168
|
end
|
|
159
169
|
end
|
|
160
170
|
|
|
@@ -13,11 +13,11 @@ module Async
|
|
|
13
13
|
QUEUE_POLL_INTERVAL = 5
|
|
14
14
|
|
|
15
15
|
class Runner
|
|
16
|
-
attr_reader :logger, :semaphore, :heap, :worker_index, :total_workers, :shutdown, :metrics
|
|
16
|
+
attr_reader :logger, :semaphore, :heap, :worker_index, :total_workers, :shutdown, :metrics, :queue_store
|
|
17
17
|
|
|
18
18
|
def initialize(
|
|
19
19
|
config_path:, job_count: 2, worker_index:, total_workers:,
|
|
20
|
-
queue_notifier: nil, queue_db_path: nil
|
|
20
|
+
queue_notifier: nil, queue_db_path: nil, queue_mmap: true
|
|
21
21
|
)
|
|
22
22
|
@logger = Console.logger
|
|
23
23
|
@worker_index = worker_index
|
|
@@ -31,7 +31,7 @@ module Async
|
|
|
31
31
|
@semaphore = ::Async::Semaphore.new(job_count)
|
|
32
32
|
@heap = build_heap(config_path)
|
|
33
33
|
|
|
34
|
-
setup_queue(queue_notifier, queue_db_path)
|
|
34
|
+
setup_queue(queue_notifier, queue_db_path, queue_mmap)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def run
|
|
@@ -62,7 +62,7 @@ module Async
|
|
|
62
62
|
|
|
63
63
|
private
|
|
64
64
|
|
|
65
|
-
def setup_queue(queue_notifier, queue_db_path)
|
|
65
|
+
def setup_queue(queue_notifier, queue_db_path, queue_mmap)
|
|
66
66
|
@listen_queue = false
|
|
67
67
|
return unless queue_notifier
|
|
68
68
|
|
|
@@ -76,7 +76,10 @@ module Async
|
|
|
76
76
|
|
|
77
77
|
@listen_queue = true
|
|
78
78
|
@queue_notifier = queue_notifier
|
|
79
|
-
@queue_store = Queue::Store.new(
|
|
79
|
+
@queue_store = Queue::Store.new(
|
|
80
|
+
path: queue_db_path || Queue::Store.default_path,
|
|
81
|
+
mmap: queue_mmap
|
|
82
|
+
)
|
|
80
83
|
|
|
81
84
|
recovered = @queue_store.recover(worker_index)
|
|
82
85
|
logger.info { "Async::Background queue: recovered #{recovered} stale jobs" } if recovered > 0
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: async-background
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Roman Hajdarov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: async
|