riverqueue 0.11.0 → 0.12.0

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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +132 -0
  3. data/LICENSE +374 -0
  4. data/docs/README.md +765 -0
  5. data/docs/migrations.md +121 -0
  6. data/docs/testing.md +173 -0
  7. data/docs/workers.md +126 -0
  8. data/exe/river +7 -0
  9. data/lib/cli.rb +55 -0
  10. data/lib/client.rb +314 -54
  11. data/lib/client_runtime.rb +612 -0
  12. data/lib/config.rb +154 -0
  13. data/lib/driver/job_row_decoder.rb +85 -0
  14. data/lib/driver/postgres_capabilities.rb +41 -0
  15. data/lib/driver/runtime.rb +661 -0
  16. data/lib/driver.rb +13 -6
  17. data/lib/errors.rb +83 -0
  18. data/lib/event.rb +78 -0
  19. data/lib/insert_opts.rb +40 -11
  20. data/lib/job.rb +28 -13
  21. data/lib/job_persisted_logging/plugin.rb +108 -0
  22. data/lib/migration_cli.rb +90 -0
  23. data/lib/migrator.rb +189 -0
  24. data/lib/params.rb +96 -0
  25. data/lib/periodic_cron.rb +24 -0
  26. data/lib/periodic_job.rb +135 -0
  27. data/lib/resumable.rb +148 -0
  28. data/lib/riverqueue/testing/minitest.rb +18 -0
  29. data/lib/riverqueue/testing/rspec.rb +109 -0
  30. data/lib/riverqueue/testing.rb +134 -0
  31. data/lib/riverqueue.rb +16 -0
  32. data/lib/unique_args.rb +97 -0
  33. data/lib/unique_bitmask.rb +14 -12
  34. data/lib/worker.rb +152 -0
  35. data/lib/worker_runner.rb +106 -0
  36. data/migration/LICENSE +374 -0
  37. data/migration/README.md +11 -0
  38. data/migration/manifest.json +38 -0
  39. data/migration/postgresql/main/001_create_river_migration.down.sql +1 -0
  40. data/migration/postgresql/main/001_create_river_migration.up.sql +8 -0
  41. data/migration/postgresql/main/002_initial_schema.down.sql +5 -0
  42. data/migration/postgresql/main/002_initial_schema.up.sql +96 -0
  43. data/migration/postgresql/main/003_river_job_tags_non_null.down.sql +3 -0
  44. data/migration/postgresql/main/003_river_job_tags_non_null.up.sql +3 -0
  45. data/migration/postgresql/main/004_pending_and_more.down.sql +42 -0
  46. data/migration/postgresql/main/004_pending_and_more.up.sql +45 -0
  47. data/migration/postgresql/main/005_migration_unique_client.down.sql +57 -0
  48. data/migration/postgresql/main/005_migration_unique_client.up.sql +79 -0
  49. data/migration/postgresql/main/006_bulk_unique.down.sql +16 -0
  50. data/migration/postgresql/main/006_bulk_unique.up.sql +40 -0
  51. data/migration/postgresql/main/007_notification_outbox_sqlite_jsonb_and_sql_cleanup.down.sql +56 -0
  52. data/migration/postgresql/main/007_notification_outbox_sqlite_jsonb_and_sql_cleanup.up.sql +44 -0
  53. data/migration/postgresql/main/008_job_id_autoincrement.down.sql +3 -0
  54. data/migration/postgresql/main/008_job_id_autoincrement.up.sql +3 -0
  55. data/migration/sqlite/main/001_create_river_migration.down.sql +1 -0
  56. data/migration/sqlite/main/001_create_river_migration.up.sql +8 -0
  57. data/migration/sqlite/main/002_initial_schema.down.sql +8 -0
  58. data/migration/sqlite/main/002_initial_schema.up.sql +19 -0
  59. data/migration/sqlite/main/003_river_job_tags_non_null.down.sql +6 -0
  60. data/migration/sqlite/main/003_river_job_tags_non_null.up.sql +6 -0
  61. data/migration/sqlite/main/004_pending_and_more.down.sql +26 -0
  62. data/migration/sqlite/main/004_pending_and_more.up.sql +33 -0
  63. data/migration/sqlite/main/005_migration_unique_client.down.sql +37 -0
  64. data/migration/sqlite/main/005_migration_unique_client.up.sql +64 -0
  65. data/migration/sqlite/main/006_bulk_unique.down.sql +7 -0
  66. data/migration/sqlite/main/006_bulk_unique.up.sql +63 -0
  67. data/migration/sqlite/main/007_notification_outbox_sqlite_jsonb_and_sql_cleanup.down.sql +255 -0
  68. data/migration/sqlite/main/007_notification_outbox_sqlite_jsonb_and_sql_cleanup.up.sql +261 -0
  69. data/migration/sqlite/main/008_job_id_autoincrement.down.sql +121 -0
  70. data/migration/sqlite/main/008_job_id_autoincrement.up.sql +123 -0
  71. data/sig/client.rbs +95 -0
  72. data/sig/driver.rbs +170 -0
  73. data/sig/insert_opts.rbs +25 -0
  74. data/sig/job.rbs +72 -0
  75. data/sig/job_persisted_logging/plugin.rbs +29 -0
  76. data/sig/migrator.rbs +44 -0
  77. data/sig/riverqueue.rbs +2 -0
  78. data/sig/runtime.rbs +382 -0
  79. data/sig/testing.rbs +95 -0
  80. data/sig/unique_args.rbs +8 -0
  81. data/sig/unique_bitmask.rbs +8 -0
  82. data/sig/worker_runner.rbs +22 -0
  83. metadata +165 -10
@@ -0,0 +1,123 @@
1
+ -- Rebuild river_job so automatically generated IDs are never reused after the
2
+ -- job holding the largest ID is deleted. Unlike PostgreSQL sequences, SQLite's
3
+ -- default ROWID allocator may otherwise reuse that deleted ID.
4
+
5
+ -- Rebuilding river_job would discard schema installed by River Pro. Check
6
+ -- schema objects instead of migration records to also catch manually applied
7
+ -- Pro migrations and the legacy workflow migration line.
8
+ CREATE TEMP TABLE river_job_pro_schema_guard (
9
+ id integer NOT NULL
10
+ );
11
+
12
+ CREATE TEMP TRIGGER river_job_pro_schema_guard_enforce
13
+ BEFORE INSERT ON river_job_pro_schema_guard
14
+ WHEN EXISTS (
15
+ SELECT 1
16
+ FROM /* TEMPLATE: schema */sqlite_master
17
+ WHERE name IN ('river_job_sequence', 'river_job_workflow_scheduling', 'river_workflow')
18
+ )
19
+ BEGIN
20
+ SELECT RAISE(ABORT, 'River SQLite migration 008 cannot run while River Pro schema is installed');
21
+ END;
22
+
23
+ INSERT INTO river_job_pro_schema_guard (id) VALUES (1);
24
+
25
+ DROP TRIGGER river_job_pro_schema_guard_enforce;
26
+ DROP TABLE river_job_pro_schema_guard;
27
+
28
+ DROP INDEX /* TEMPLATE: schema */river_job_kind;
29
+ DROP INDEX /* TEMPLATE: schema */river_job_state_and_finalized_at_index;
30
+ DROP INDEX /* TEMPLATE: schema */river_job_prioritized_fetching_index;
31
+ DROP INDEX /* TEMPLATE: schema */river_job_unique_idx;
32
+
33
+ ALTER TABLE /* TEMPLATE: schema */river_job RENAME TO river_job_old;
34
+
35
+ CREATE TABLE /* TEMPLATE: schema */river_job (
36
+ id integer PRIMARY KEY AUTOINCREMENT,
37
+ args blob NOT NULL DEFAULT (jsonb('{}')),
38
+ attempt integer NOT NULL DEFAULT 0,
39
+ attempted_at timestamp,
40
+ attempted_by blob, -- json
41
+ created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
42
+ errors blob, -- json
43
+ finalized_at timestamp,
44
+ kind text NOT NULL,
45
+ max_attempts integer NOT NULL DEFAULT 25,
46
+ metadata blob NOT NULL DEFAULT (jsonb('{}')),
47
+ priority integer NOT NULL DEFAULT 1,
48
+ queue text NOT NULL DEFAULT 'default',
49
+ state text NOT NULL DEFAULT 'available',
50
+ scheduled_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
51
+ tags blob NOT NULL DEFAULT (jsonb('[]')),
52
+ unique_key blob,
53
+ unique_states integer,
54
+ CONSTRAINT finalized_or_finalized_at_null CHECK (
55
+ (finalized_at IS NULL AND state NOT IN ('cancelled', 'completed', 'discarded')) OR
56
+ (finalized_at IS NOT NULL AND state IN ('cancelled', 'completed', 'discarded'))
57
+ ),
58
+ CONSTRAINT priority_in_range CHECK (priority >= 1 AND priority <= 4),
59
+ CONSTRAINT queue_length CHECK (length(queue) > 0 AND length(queue) < 128),
60
+ CONSTRAINT kind_length CHECK (length(kind) > 0 AND length(kind) < 128),
61
+ CONSTRAINT state_valid CHECK (state IN ('available', 'cancelled', 'completed', 'discarded', 'pending', 'retryable', 'running', 'scheduled'))
62
+ );
63
+
64
+ INSERT INTO /* TEMPLATE: schema */river_job (
65
+ id,
66
+ args,
67
+ attempt,
68
+ attempted_at,
69
+ attempted_by,
70
+ created_at,
71
+ errors,
72
+ finalized_at,
73
+ kind,
74
+ max_attempts,
75
+ metadata,
76
+ priority,
77
+ queue,
78
+ state,
79
+ scheduled_at,
80
+ tags,
81
+ unique_key,
82
+ unique_states
83
+ )
84
+ SELECT
85
+ id,
86
+ args,
87
+ attempt,
88
+ attempted_at,
89
+ attempted_by,
90
+ created_at,
91
+ errors,
92
+ finalized_at,
93
+ kind,
94
+ max_attempts,
95
+ metadata,
96
+ priority,
97
+ queue,
98
+ state,
99
+ scheduled_at,
100
+ tags,
101
+ unique_key,
102
+ unique_states
103
+ FROM /* TEMPLATE: schema */river_job_old;
104
+
105
+ DROP TABLE /* TEMPLATE: schema */river_job_old;
106
+
107
+ CREATE INDEX /* TEMPLATE: schema */river_job_kind ON river_job (kind);
108
+ CREATE INDEX /* TEMPLATE: schema */river_job_state_and_finalized_at_index ON river_job (state, finalized_at) WHERE finalized_at IS NOT NULL;
109
+ CREATE INDEX /* TEMPLATE: schema */river_job_prioritized_fetching_index ON river_job (state, queue, priority, scheduled_at, id);
110
+ CREATE UNIQUE INDEX /* TEMPLATE: schema */river_job_unique_idx ON river_job (unique_key)
111
+ WHERE unique_key IS NOT NULL
112
+ AND unique_states IS NOT NULL
113
+ AND CASE state
114
+ WHEN 'available' THEN unique_states & (1 << 0)
115
+ WHEN 'cancelled' THEN unique_states & (1 << 1)
116
+ WHEN 'completed' THEN unique_states & (1 << 2)
117
+ WHEN 'discarded' THEN unique_states & (1 << 3)
118
+ WHEN 'pending' THEN unique_states & (1 << 4)
119
+ WHEN 'retryable' THEN unique_states & (1 << 5)
120
+ WHEN 'running' THEN unique_states & (1 << 6)
121
+ WHEN 'scheduled' THEN unique_states & (1 << 7)
122
+ ELSE 0
123
+ END >= 1;
data/sig/client.rbs ADDED
@@ -0,0 +1,95 @@
1
+ module River
2
+ MAX_ATTEMPTS_DEFAULT: Integer
3
+ PRIORITY_DEFAULT: Integer
4
+ QUEUE_DEFAULT: String
5
+
6
+ class Client
7
+ @config: Config
8
+ @driver: _Driver
9
+ @runtime: ClientRuntime
10
+ @time_now_utc: ^() -> Time
11
+
12
+ attr_reader config: Config
13
+ attr_reader driver: _Driver
14
+
15
+ def initialize: (_Driver driver, ?config: Config?) -> void
16
+ def __finish_claimed_job: (JobRow, ?Exception?) -> untyped
17
+ def __perform_job: (Integer, ?allow_scheduled: bool) -> untyped
18
+ def __interrupt_workers: () -> untyped
19
+ def __runtime_healthy?: () -> bool
20
+ def id: () -> String
21
+ def insert: (jobArgs, ?insert_opts: InsertOpts?, ?max_attempts: Integer?,
22
+ ?metadata: Hash[String | Symbol, untyped]?, ?priority: Integer?, ?queue: (String | Symbol)?,
23
+ ?scheduled_at: Time?, ?state: jobStateInput?, ?tags: Array[String]?, ?unique_opts: UniqueOpts?) -> JobInsertResult
24
+ def insert_many: (Array[jobArgs | InsertManyParams]) -> Array[JobInsertResult]
25
+ def job_cancel: (Integer) -> JobRow
26
+ def job_delete: (Integer) -> JobRow
27
+ def job_delete_many: (?JobListParams?, ?after: untyped, ?after_id: untyped,
28
+ ?ids: untyped, ?kinds: untyped, ?limit: untyped, ?metadata: untyped, ?priorities: untyped,
29
+ ?queues: untyped, ?sort_by: untyped, ?sort_order: untyped, ?states: untyped,
30
+ ?tags_all: untyped, ?tags_any: untyped) -> untyped
31
+ def job_get: (Integer) -> JobRow
32
+ def job_list: (?JobListParams?, ?after: untyped, ?after_id: untyped,
33
+ ?ids: untyped, ?kinds: untyped, ?limit: untyped, ?metadata: untyped, ?priorities: untyped,
34
+ ?queues: untyped, ?sort_by: untyped, ?sort_order: untyped, ?states: untyped,
35
+ ?tags_all: untyped, ?tags_any: untyped) -> untyped
36
+ def job_retry: (Integer) -> JobRow
37
+ def job_update: (Integer, ?JobUpdateParams?, ?attempt: untyped, ?attempted_at: untyped,
38
+ ?attempted_by: untyped, ?errors: untyped, ?finalized_at: untyped, ?max_attempts: untyped,
39
+ ?metadata: untyped, ?state: untyped) -> JobRow
40
+ def periodic_jobs: () -> PeriodicJobBundle
41
+ def queue_add: (String | Symbol, QueueConfig | Integer) -> self
42
+ def queue_get: (String | Symbol) -> Queue
43
+ def queue_list: (?max: Integer) -> untyped
44
+ def queue_pause: (String | Symbol) -> bool
45
+ def queue_remove: (String | Symbol) -> self
46
+ def queue_resume: (String | Symbol) -> bool
47
+ def queue_update: (String | Symbol, metadata: Hash[untyped, untyped]) -> Queue
48
+ def start: () -> self
49
+ def started?: () -> bool
50
+ def stop: (?wait: bool) -> self
51
+ def stop_and_cancel: () -> self
52
+ def stopped?: () -> bool
53
+ def subscribe: (*Symbol | String kinds, ?buffer_size: Integer) -> Subscription
54
+
55
+ DEFAULT_UNIQUE_STATES: Array[jobStateAll]
56
+ EMPTY_INSERT_OPTS: InsertOpts
57
+ REQUIRED_UNIQUE_STATES: Array[jobStateAll]
58
+ TAG_RE: Regexp
59
+
60
+ private def insert_and_check_unique_job: (Driver::JobInsertParams) -> JobInsertResult
61
+ private def make_insert_params: (jobArgs, InsertOpts) -> Driver::JobInsertParams
62
+ private def make_unique_key_and_bitmask: (Driver::JobInsertParams, UniqueOpts) -> [String, String]
63
+ private def run_insert_plugins: (Array[Driver::JobInsertParams]) { () -> Array[JobInsertResult] } -> Array[JobInsertResult]
64
+ private def truncate_time: (Time, Integer | Rational) -> Time
65
+ private def uint64_to_int64: (Integer) -> Integer
66
+ private def validate_tags: (Array[String]) -> Array[String]
67
+ private def validate_unique_states: (Array[jobStateInput]) -> Array[jobStateAll]
68
+ end
69
+
70
+ class InsertManyParams
71
+ @args: jobArgs
72
+ @insert_opts: InsertOpts?
73
+
74
+ attr_reader args: jobArgs
75
+ attr_reader insert_opts: InsertOpts?
76
+
77
+ def initialize: (jobArgs job, ?insert_opts: InsertOpts?, ?max_attempts: Integer?,
78
+ ?metadata: Hash[String | Symbol, untyped]?, ?priority: Integer?, ?queue: (String | Symbol)?,
79
+ ?scheduled_at: Time?, ?state: jobStateInput?, ?tags: Array[String]?, ?unique_opts: UniqueOpts?) -> void
80
+ def is_a?: (Class) -> bool
81
+ end
82
+
83
+ class JobInsertResult
84
+ @job: JobRow
85
+ @unique_skipped_as_duplicate: bool
86
+
87
+ attr_reader job: JobRow
88
+ def unique_skipped_as_duplicate?: () -> bool
89
+ alias unique_skipped_as_duplicated unique_skipped_as_duplicate?
90
+
91
+ def initialize: (JobRow job, unique_skipped_as_duplicated: bool) -> void
92
+ end
93
+
94
+ class InsertResult = JobInsertResult
95
+ end
data/sig/driver.rbs ADDED
@@ -0,0 +1,170 @@
1
+ module River
2
+ interface _Driver
3
+ def respond_to?: (Symbol, ?bool) -> bool
4
+ def init_driver: () -> void
5
+ def migration_backend: () -> Symbol
6
+ def migration_connection: [A] () { (untyped) -> A } -> A
7
+ def advisory_lock: (Integer) -> void
8
+ def job_cancel: (Integer, ?now: Time) -> JobRow?
9
+ def job_delete: (Integer) -> JobRow?
10
+ def job_delete_finalized: (**untyped) -> Integer
11
+ def job_delete_if_running: (Integer) -> bool
12
+ def job_delete_many: (JobListParams) -> Array[JobRow]
13
+ def job_get_available: (queue: String, max: Integer, attempted_by: String, ?kinds: Array[String]?, ?now: Time) -> Array[JobRow]
14
+ def job_claim: (id: Integer, attempted_by: String, ?allow_scheduled: bool, ?now: Time) -> JobRow?
15
+ def job_get_cancelled_ids: (Array[Integer]) -> Array[Integer]
16
+ def job_complete: (id: Integer, finalized_at: Time, ?metadata: Hash[untyped, untyped]?, ?now: Time) -> (JobRow | :cancelled)?
17
+ def job_get_by_kind_and_unique_properties: (Driver::JobGetByKindAndUniquePropertiesParam) -> JobRow?
18
+ def job_insert: (Driver::JobInsertParams) -> [JobRow, bool]
19
+ def job_insert_many: (Array[Driver::JobInsertParams]) -> Array[[JobRow, bool]]
20
+ def job_metadata_merge: (Integer, Hash[untyped, untyped]) -> JobRow?
21
+ def job_rescue_stuck: (**untyped) -> Integer
22
+ def job_retry: (Integer, ?now: Time) -> JobRow?
23
+ def job_schedule: (?now: Time, ?max: Integer) -> Integer
24
+ def job_set_state_if_running: (**untyped) -> JobRow?
25
+ def job_update: (Integer, JobUpdateParams) -> JobRow?
26
+ def leader_acquire: (String, ?ttl: Integer, ?now: Time) -> bool
27
+ def leader_release: (String) -> untyped
28
+ def leader_renew: (String, ?ttl: Integer, ?now: Time) -> bool
29
+ def notification_delete_before: (horizon: Time, ?max: Integer) -> Integer
30
+ def queue_get: (String) -> Queue?
31
+ def queue_list: (?max: Integer) -> Array[Queue]
32
+ def queue_pause: (String, ?now: Time) -> untyped
33
+ def queue_resume: (String, ?now: Time) -> untyped
34
+ def queue_update: (String, metadata: Hash[untyped, untyped], ?now: Time) -> Queue?
35
+ def queue_upsert: (String, ?metadata: Hash[untyped, untyped], ?now: Time) -> Queue?
36
+ def transaction: [T] () { () -> T } -> T
37
+
38
+ # this set of methods is used only in tests
39
+ def advisory_lock_try: (Integer) -> bool
40
+ def job_get_by_id: (Integer) -> JobRow?
41
+ def job_list: (?JobListParams | :all) -> Array[JobRow]
42
+ def rollback_exception: -> Exception
43
+ end
44
+
45
+ module Driver
46
+ class JobRowDecoder
47
+ ZERO_TIME: Time
48
+ @errors: Array[String]
49
+ def self.attempt_error: (untyped) -> AttemptError
50
+ def self.error_time: (untyped) -> Time
51
+ def self.error_integer: (untyped) -> Integer
52
+ def self.error_string: (untyped) -> String
53
+ def initialize: () -> void
54
+ def json: (Symbol, untyped, ?type: Class?, ?strings: bool, ?default: untyped) -> untyped
55
+ def decoded: (Symbol, untyped, ?type: Class?, ?strings: bool, ?default: untyped) -> untyped
56
+ def finish: (JobRow) -> JobRow
57
+ end
58
+
59
+ class PostgresCapabilities
60
+ attr_reader supports_listen_notify: bool
61
+ attr_reader unique_insert_mode: :metadata_nonce | :returning_old | :xmax
62
+ attr_reader unique_insert_sql: String
63
+ def initialize: (product: String, version_num: Integer, yb_listen_notify_enabled: bool) -> void
64
+
65
+ class Cache
66
+ @mutex: Mutex
67
+ @values: Hash[untyped, PostgresCapabilities]
68
+ def initialize: () -> void
69
+ def fetch: (untyped) { () -> PostgresCapabilities } -> PostgresCapabilities
70
+ end
71
+ end
72
+
73
+ class JobGetByKindAndUniquePropertiesParam
74
+ attr_accessor created_at: [Time, Time]?
75
+ attr_accessor encoded_args: String?
76
+ attr_accessor kind: String
77
+ attr_accessor queue: String?
78
+ attr_accessor state: Array[jobStateAll]?
79
+
80
+ def initialize: (kind: String, ?created_at: [Time, Time]?, ?encoded_args: String?, ?queue: String?, ?state: Array[jobStateAll]?) -> void
81
+ end
82
+
83
+ class JobInsertParams
84
+ attr_accessor args: untyped
85
+ attr_accessor encoded_args: String
86
+ attr_accessor kind: String
87
+ attr_accessor max_attempts: Integer
88
+ attr_accessor metadata: Hash[untyped, untyped]
89
+ attr_accessor priority: Integer
90
+ attr_accessor queue: String
91
+ attr_accessor scheduled_at: Time?
92
+ attr_accessor state: jobStateAll
93
+ attr_accessor tags: Array[String]?
94
+ attr_accessor unique_key: String?
95
+ attr_accessor unique_states: String?
96
+
97
+ def initialize: (?args: untyped, encoded_args: String, kind: String, max_attempts: Integer, ?metadata: Hash[untyped, untyped], priority: Integer, queue: String, scheduled_at: Time?, state: jobStateAll, tags: Array[String]?, ?unique_key: String?, ?unique_states: String?) -> void
98
+ end
99
+
100
+ module Runtime
101
+ def runtime_read_job: (untyped) -> untyped
102
+ def runtime_decode_sqlite_job: (untyped) -> JobRow
103
+ def runtime_decode_postgres_job: (untyped) -> JobRow
104
+ @postgres_capabilities_cache: PostgresCapabilities::Cache
105
+ def init_driver: () -> void
106
+ def postgres_capabilities: () -> PostgresCapabilities
107
+ def postgres_notify_insert: (Array[JobInsertParams]) -> void
108
+ def job_get_cancelled_ids: (Array[Integer]) -> Array[Integer]
109
+ def job_complete: (id: untyped, finalized_at: untyped, ?metadata: untyped, ?now: untyped) -> untyped
110
+ def job_cancel: (untyped, ?now: untyped) -> untyped
111
+ def job_delete: (untyped) -> untyped
112
+ def job_delete_finalized: (retention: untyped, ?now: untyped, ?max: untyped) -> untyped
113
+ def job_delete_if_running: (untyped) -> untyped
114
+ def job_delete_many: (untyped) -> untyped
115
+ def job_get_available: (queue: untyped, max: untyped, attempted_by: untyped, ?kinds: untyped, ?now: untyped) -> untyped
116
+ def job_claim: (id: untyped, attempted_by: untyped, ?allow_scheduled: untyped, ?now: untyped) -> untyped
117
+ private def runtime_claim_jobs: (untyped, untyped, untyped, untyped) -> untyped
118
+ def job_list: (?untyped) -> untyped
119
+ def job_metadata_merge: (untyped, untyped) -> untyped
120
+ def job_rescue_stuck: (horizon: untyped, retry_policy: untyped, ?now: untyped, ?max: untyped) -> untyped
121
+ def job_retry: (untyped, ?now: untyped) -> untyped
122
+ def job_schedule: (?now: untyped, ?max: untyped) -> untyped
123
+ def job_set_state_if_running: (id: untyped, state: untyped, ?now: untyped, ?attempt: untyped, ?error: untyped, ?finalized_at: untyped, ?metadata: untyped, ?scheduled_at: untyped) -> untyped
124
+ def job_update: (untyped, untyped) -> untyped
125
+ def leader_acquire: (untyped, ?ttl: untyped, ?now: untyped) -> untyped
126
+ def leader_release: (untyped) -> untyped
127
+ def leader_renew: (untyped, ?ttl: untyped, ?now: untyped) -> untyped
128
+ def notification_delete_before: (horizon: untyped, ?max: untyped) -> untyped
129
+ def queue_get: (untyped) -> untyped
130
+ def queue_list: (?max: untyped) -> untyped
131
+ def queue_pause: (untyped, ?now: untyped) -> untyped
132
+ def queue_resume: (untyped, ?now: untyped) -> untyped
133
+ def queue_update: (untyped, metadata: untyped, ?now: untyped) -> untyped
134
+ def queue_upsert: (untyped, ?metadata: untyped, ?now: untyped) -> untyped
135
+
136
+ private
137
+
138
+ def job_get_by_id: (untyped) -> untyped
139
+ def runtime_append_error: (untyped) -> untyped
140
+ def runtime_cancel_attempted: () -> untyped
141
+ def runtime_connection_pool: () -> untyped
142
+ def runtime_cursor_clause: (untyped) -> String
143
+ def runtime_execute: (String) -> untyped
144
+ def runtime_in_clause: (untyped, untyped) -> untyped
145
+ def runtime_job_list_without_params: () -> untyped
146
+ def runtime_job_rows: (String) -> untyped
147
+ def runtime_json: (untyped) -> untyped
148
+ def runtime_merge_metadata: (untyped) -> untyped
149
+ def runtime_metadata_equals: (untyped, untyped) -> untyped
150
+ def runtime_nullable_time: (untyped) -> untyped
151
+ def runtime_notify: (String, untyped) -> untyped
152
+ def sqlite_insert_nonces: (Array[JobInsertParams]) -> Array[String]
153
+ def runtime_parse_json: (untyped) -> untyped
154
+ def runtime_parse_time: (untyped) -> untyped
155
+ def runtime_postgres?: () -> bool
156
+ def runtime_query_rows: (String) -> untyped
157
+ def runtime_queue_columns: () -> untyped
158
+ def runtime_queue_from_row: (untyped) -> untyped
159
+ def runtime_quote: (untyped) -> String
160
+ def runtime_returning_ids: (untyped) -> untyped
161
+ def runtime_state: (untyped) -> untyped
162
+ def runtime_tag_contains: (untyped) -> untyped
163
+ def runtime_time: (untyped) -> untyped
164
+ def runtime_unique_violation_class: () -> singleton(Exception)
165
+ def runtime_update_value: (untyped, untyped) -> untyped
166
+ def runtime_value: (untyped, untyped) -> untyped
167
+ def transaction: () { () -> untyped } -> untyped
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,25 @@
1
+ module River
2
+ class InsertOpts
3
+ attr_accessor max_attempts: Integer?
4
+ attr_accessor metadata: Hash[String | Symbol, untyped]?
5
+ attr_accessor priority: Integer?
6
+ attr_accessor queue: (String | Symbol)?
7
+ attr_accessor scheduled_at: Time?
8
+ attr_accessor state: jobStateInput?
9
+ attr_accessor tags: Array[String]?
10
+ attr_accessor unique_opts: UniqueOpts?
11
+
12
+ def initialize: (?max_attempts: Integer?, ?metadata: Hash[String | Symbol, untyped]?, ?priority: Integer?, ?queue: (String | Symbol)?, ?scheduled_at: Time?, ?state: jobStateInput?, ?tags: Array[String]?, ?unique_opts: UniqueOpts?) -> void
13
+ end
14
+
15
+ class UniqueOpts
16
+ def empty?: () -> bool
17
+ attr_accessor by_args: bool? | Array[String | Symbol | Array[String | Symbol]]?
18
+ attr_accessor by_period: (Integer | Rational)?
19
+ attr_accessor by_queue: bool?
20
+ attr_accessor by_state: Array[jobStateInput]?
21
+ attr_accessor exclude_kind: bool?
22
+
23
+ def initialize: (?by_args: bool? | Array[String | Symbol | Array[String | Symbol]]?, ?by_period: (Integer | Rational)?, ?by_queue: bool?, ?by_state: Array[jobStateInput]?, ?exclude_kind: bool?) -> void
24
+ end
25
+ end
data/sig/job.rbs ADDED
@@ -0,0 +1,72 @@
1
+ module River
2
+ JOB_STATE_AVAILABLE: "available"
3
+ JOB_STATE_CANCELLED: "cancelled"
4
+ JOB_STATE_COMPLETED: "completed"
5
+ JOB_STATE_DISCARDED: "discarded"
6
+ JOB_STATE_PENDING: "pending"
7
+ JOB_STATE_RETRYABLE: "retryable"
8
+ JOB_STATE_RUNNING: "running"
9
+ JOB_STATE_SCHEDULED: "scheduled"
10
+
11
+ type jobStateAll = "available" | "cancelled" | "completed" | "discarded" | "pending" | "retryable" | "running" | "scheduled"
12
+ type jobStateInput = jobStateAll | :available | :cancelled | :completed | :discarded | :pending | :retryable | :running | :scheduled
13
+
14
+ interface _JobArgs
15
+ def is_a?: (Class) -> bool
16
+ def kind: () -> (String | Symbol)
17
+ def respond_to?: (Symbol) -> bool
18
+ def to_json: () -> String
19
+ end
20
+
21
+ interface _JobArgsWithInsertOpts
22
+ include _JobArgs
23
+
24
+ def insert_opts: () -> InsertOpts?
25
+ end
26
+
27
+ type jobArgs = _JobArgs | _JobArgsWithInsertOpts
28
+
29
+ class JobArgsHash
30
+ @hash: Hash[String | Symbol, untyped]
31
+ @kind: String
32
+
33
+ attr_reader kind: String
34
+
35
+ def initialize: (String | Symbol kind, Hash[String | Symbol, untyped] hash) -> void
36
+ def to_json: () -> String
37
+ end
38
+
39
+ class JobRow
40
+ attr_accessor __decode_error: JobRowDecodeError?
41
+ attr_accessor args: Hash[String, untyped]
42
+ attr_accessor attempt: Integer
43
+ attr_accessor attempted_at: Time?
44
+ attr_accessor attempted_by: Array[String]?
45
+ attr_accessor created_at: Time
46
+ attr_accessor errors: Array[AttemptError]?
47
+ attr_accessor finalized_at: Time?
48
+ attr_accessor id: Integer
49
+ attr_accessor kind: String
50
+ attr_accessor max_attempts: Integer
51
+ attr_accessor metadata: Hash[String, untyped]
52
+ attr_accessor priority: Integer
53
+ attr_accessor queue: String
54
+ attr_accessor scheduled_at: Time
55
+ attr_accessor state: jobStateAll
56
+ attr_accessor tags: Array[String]?
57
+ attr_accessor unique_key: String?
58
+ attr_accessor unique_states: Array[jobStateAll]?
59
+
60
+ def initialize: (id: Integer, args: Hash[String, untyped], attempt: Integer, ?attempted_at: Time?, ?attempted_by: Array[String]?, created_at: Time, ?errors: Array[AttemptError]?, ?finalized_at: Time?, kind: String, max_attempts: Integer, metadata: Hash[String, untyped], priority: Integer, queue: String, scheduled_at: Time, state: jobStateAll, ?tags: Array[String]?, ?unique_key: String?, ?unique_states: Array[jobStateAll]?) -> void
61
+ end
62
+
63
+ class AttemptError
64
+ attr_accessor at: Time
65
+ attr_accessor attempt: Integer
66
+ attr_accessor error: String
67
+ attr_accessor trace: String
68
+
69
+ def initialize: (at: Time, attempt: Integer, error: String, trace: String) -> void
70
+ def to_h: () -> Hash[Symbol, untyped]
71
+ end
72
+ end
@@ -0,0 +1,29 @@
1
+ module River
2
+ module JobPersistedLogging
3
+ class Plugin
4
+ @logger_factory: (^(Buffer) -> untyped)?
5
+ @max_size_bytes: Integer
6
+ @max_total_bytes: Integer
7
+
8
+ def initialize: (?max_size_bytes: Integer, ?max_total_bytes: Integer) ?{ (Buffer) -> untyped } -> void
9
+ def work: [T] (Job, ^() -> T) -> T
10
+
11
+ private
12
+
13
+ def persist_log: (Job, Buffer) -> void
14
+
15
+ class Buffer
16
+ @closed: bool
17
+ @data: String
18
+ @limit: Integer
19
+ @mutex: Mutex
20
+ @truncated: bool
21
+
22
+ def initialize: (Integer) -> void
23
+ def close: () -> nil
24
+ def finish: () -> [String, bool]
25
+ def write: (_ToS) -> Integer
26
+ end
27
+ end
28
+ end
29
+ end
data/sig/migrator.rbs ADDED
@@ -0,0 +1,44 @@
1
+ class Gem::Specification
2
+ def self.find_all_by_name: (String, *untyped) -> Array[Gem::Specification]
3
+ end
4
+
5
+ module River
6
+ module MigrationCLI
7
+ def self.detect_driver: () -> String
8
+ def self.run: (Array[String], ?err: untyped, ?out: untyped) -> Integer
9
+ end
10
+ class Migrator
11
+ class Migration < Data
12
+ attr_reader version: Integer
13
+ attr_reader name: String
14
+ attr_reader sql_up: String
15
+ attr_reader sql_down: String
16
+ def self.new: (Integer, untyped, String, String) -> instance
17
+ end
18
+ class Status < Data
19
+ attr_reader version: Integer
20
+ attr_reader name: String
21
+ attr_reader applied: bool
22
+ def self.new: (Integer, String, bool) -> instance
23
+ end
24
+ @backend: Symbol
25
+ @connection: untyped
26
+ @driver: untyped
27
+ @line: String
28
+ @migrations: Array[Migration]
29
+ @mutex: Mutex
30
+ @requested_schema: untyped
31
+ @schema: untyped
32
+ attr_reader migrations: Array[Migration]
33
+ def initialize: (untyped, ?line: String, ?migrations_path: String, ?schema: untyped) -> void
34
+ def migrate: (?direction: Symbol, ?dry_run: bool, ?steps: untyped, ?target: untyped) -> Array[Migration]
35
+ def status: () -> Array[Status]
36
+ private
37
+ def execute: (String) -> untyped
38
+ def existing_versions: () -> Array[Integer]
39
+ def line_column?: () -> bool
40
+ def query: (String) -> untyped
41
+ def session: [A] (?lock: bool) { () -> A } -> A
42
+ def table: () -> String
43
+ end
44
+ end
@@ -0,0 +1,2 @@
1
+ module River
2
+ end