undertow 0.2.1 → 0.4.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.
- checksums.yaml +4 -4
- data/lib/undertow/drain_job.rb +16 -9
- data/lib/undertow/dsl.rb +7 -7
- data/lib/undertow/trackable.rb +17 -0
- data/lib/undertow/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: 1aa09fe4d1c2e088f4b7ca874175db916486f8a6296d49af88544bec8ec254be
|
|
4
|
+
data.tar.gz: 30115bb681233cf045251670a9f2ed369e6290340414f5f031f292cd2e26fe23
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a68ec79086258526eb24fbd2690b5df15701975706ee4ae09bbbd800d4e024d1b9c4546d7df03f465de7bbdcd4efc6252b73ac2244252b74d6f93707ea5dff1b
|
|
7
|
+
data.tar.gz: 9406d057b05d1a76fade09a0d3b3b698d3503a11bccfdd68591f4eead07bce128dfd3b431fbf4e6078eac092bc4f641a51d0dda036bdd200ab928dbec24155af
|
data/lib/undertow/drain_job.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Undertow
|
|
|
5
5
|
# each model's configured on_drain handler.
|
|
6
6
|
#
|
|
7
7
|
# Publishes two ActiveSupport::Notifications events:
|
|
8
|
-
# drain.undertow , after a successful on_drain call ({ model:,
|
|
8
|
+
# drain.undertow , after a successful on_drain call ({ model:, upserted_ids:, deleted_ids:, duration_ms: })
|
|
9
9
|
# error.undertow , when on_drain raises ({ model:, exception: })
|
|
10
10
|
class DrainJob < ActiveJob::Base
|
|
11
11
|
queue_as { Undertow.configuration.queue_name }
|
|
@@ -30,9 +30,9 @@ module Undertow
|
|
|
30
30
|
# preventing the race where srem fires after a concurrent sadd.
|
|
31
31
|
Buffer.deregister_model(model_name)
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
deleted_ids
|
|
35
|
-
return if
|
|
33
|
+
upserted_ids = Buffer.pop_pending(model_name, max)
|
|
34
|
+
deleted_ids = Buffer.pop_deleted(model_name, max)
|
|
35
|
+
return if upserted_ids.empty? && deleted_ids.empty?
|
|
36
36
|
|
|
37
37
|
# If the batch was capped, re-register so the next scheduler tick picks up.
|
|
38
38
|
Buffer.reregister_model(model_name) if Buffer.remaining(model_name).positive?
|
|
@@ -41,19 +41,26 @@ module Undertow
|
|
|
41
41
|
raise "No Undertow config registered for #{model_name}" unless config
|
|
42
42
|
raise "#{model_name} is missing undertow_on_drain" unless config.on_drain
|
|
43
43
|
|
|
44
|
-
config.on_drain.call(model_name,
|
|
44
|
+
duration_ms = measure_ms { config.on_drain.call(model_name, upserted_ids, deleted_ids) }
|
|
45
45
|
|
|
46
46
|
ActiveSupport::Notifications.instrument('drain.undertow', {
|
|
47
47
|
model: model_name,
|
|
48
|
-
|
|
49
|
-
deleted_ids: deleted_ids
|
|
48
|
+
upserted_ids: upserted_ids,
|
|
49
|
+
deleted_ids: deleted_ids,
|
|
50
|
+
duration_ms: duration_ms
|
|
50
51
|
})
|
|
51
52
|
rescue StandardError => e
|
|
52
|
-
Buffer.restore_pending(model_name,
|
|
53
|
-
Buffer.restore_deleted(model_name, deleted_ids)
|
|
53
|
+
Buffer.restore_pending(model_name, upserted_ids) if upserted_ids&.any?
|
|
54
|
+
Buffer.restore_deleted(model_name, deleted_ids) if deleted_ids&.any?
|
|
54
55
|
Buffer.reregister_model(model_name)
|
|
55
56
|
ActiveSupport::Notifications.instrument('error.undertow', { model: model_name, exception: e })
|
|
56
57
|
Rails.logger.error("[Undertow::DrainJob] #{model_name}: #{e.message}") if defined?(Rails)
|
|
57
58
|
end
|
|
59
|
+
|
|
60
|
+
def measure_ms
|
|
61
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
62
|
+
yield
|
|
63
|
+
((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000).round(2)
|
|
64
|
+
end
|
|
58
65
|
end
|
|
59
66
|
end
|
data/lib/undertow/dsl.rb
CHANGED
|
@@ -5,14 +5,14 @@ module Undertow
|
|
|
5
5
|
# that calls these methods automatically registers itself with Undertow and
|
|
6
6
|
# gets Trackable behavior wired in at boot, no include needed.
|
|
7
7
|
#
|
|
8
|
-
# class
|
|
9
|
-
# undertow_on_drain ->(model_name,
|
|
10
|
-
# undertow_skip %w[
|
|
8
|
+
# class Post < ApplicationRecord
|
|
9
|
+
# undertow_on_drain ->(model_name, upserted_ids, deleted_ids) { PostSyncJob.perform_later(upserted_ids, deleted_ids) }
|
|
10
|
+
# undertow_skip %w[view_count updated_at]
|
|
11
11
|
#
|
|
12
|
-
# undertow_depends_on :
|
|
13
|
-
# undertow_depends_on :
|
|
14
|
-
# resolver: ->(
|
|
15
|
-
# watched_columns: %w[
|
|
12
|
+
# undertow_depends_on :author, foreign_key: :author_id, watched_columns: %w[name bio]
|
|
13
|
+
# undertow_depends_on :tag,
|
|
14
|
+
# resolver: ->(tag) { Post.joins(:post_tags).where(post_tags: { tag_id: tag.id }) },
|
|
15
|
+
# watched_columns: %w[name slug]
|
|
16
16
|
# end
|
|
17
17
|
#
|
|
18
18
|
module DSL
|
data/lib/undertow/trackable.rb
CHANGED
|
@@ -39,6 +39,23 @@ module Undertow
|
|
|
39
39
|
Buffer.push_deleted(name, ids)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
# Enqueues records into the pending buffer without going through AR
|
|
43
|
+
# callbacks. Use this to replay a batch through the drain handler without
|
|
44
|
+
# triggering other model lifecycle callbacks, e.g. from a console or a
|
|
45
|
+
# data migration.
|
|
46
|
+
#
|
|
47
|
+
# Post.undertow_requeue(Post.where(author_id: 123))
|
|
48
|
+
# Post.undertow_requeue([136543, 136544])
|
|
49
|
+
# Post.undertow_requeue # all records
|
|
50
|
+
def undertow_requeue(scope_or_ids = :all)
|
|
51
|
+
ids = case scope_or_ids
|
|
52
|
+
when :all then pluck(:id)
|
|
53
|
+
when ActiveRecord::Relation then scope_or_ids.pluck(:id)
|
|
54
|
+
else Array(scope_or_ids)
|
|
55
|
+
end
|
|
56
|
+
_push_undertow_pending(ids)
|
|
57
|
+
end
|
|
58
|
+
|
|
42
59
|
def _push_dep_pending(record, dep)
|
|
43
60
|
ids = _dep_ids_for(record, dep)
|
|
44
61
|
_push_undertow_pending(ids) if ids.any?
|
data/lib/undertow/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: undertow
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nathan Allen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|