active_delivery 1.0.0 → 1.1.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/CHANGELOG.md +18 -0
- data/README.md +7 -4
- data/lib/.rbnext/3.0/abstract_notifier/async_adapters/active_job.rb +12 -3
- data/lib/.rbnext/3.0/abstract_notifier/base.rb +223 -0
- data/lib/.rbnext/3.0/active_delivery/base.rb +6 -5
- data/lib/.rbnext/3.0/active_delivery/lines/base.rb +14 -2
- data/lib/.rbnext/3.0/active_delivery/lines/mailer.rb +4 -0
- data/lib/.rbnext/3.1/abstract_notifier/async_adapters/active_job.rb +36 -0
- data/lib/.rbnext/3.1/abstract_notifier/base.rb +14 -8
- data/lib/.rbnext/3.1/active_delivery/base.rb +6 -5
- data/lib/.rbnext/3.1/active_delivery/lines/base.rb +14 -2
- data/lib/abstract_notifier/async_adapters/active_job.rb +12 -3
- data/lib/abstract_notifier/base.rb +13 -7
- data/lib/abstract_notifier/testing.rb +2 -2
- data/lib/active_delivery/base.rb +6 -5
- data/lib/active_delivery/lines/base.rb +14 -2
- data/lib/active_delivery/lines/mailer.rb +4 -0
- data/lib/active_delivery/lines/notifier.rb +4 -0
- data/lib/active_delivery/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dfc96638e6c019dd1b13f57eef8ab3b9bf2a34df2b58ca7f7ea8ea167886c59e
|
4
|
+
data.tar.gz: b50d556edef4a01fc7d1a8af1659a05f99a821584c2d4818418401f3a03350dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 518d226591f5114383c2d138c163b4bac13e62666cce4f7edde7d2df5bca7e770c17576f00fee378b9a8733cc72372960efa2692839a6dc4d274d130787fcb41
|
7
|
+
data.tar.gz: 2bd5eed0775fd32d83ca45364d8ecdc4f28c275eb2ffbbcad768ef98d8581b1cd0e66eb72f7e012c9d4dbd0a18e8a72cb40a858f0459614e18a5ee3e24fb0420
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 1.1.0 (2023-12-01) ❄️
|
6
|
+
|
7
|
+
- Support delayed delivery options (e.g, `wait_until`). ([@palkan][])
|
8
|
+
|
5
9
|
## 📬 1.0.0 (2023-08-29)
|
6
10
|
|
7
11
|
- Add `resolver_pattern` option to specify naming pattern for notifiers without using Procs. ([@palkan][])
|
@@ -43,6 +47,20 @@
|
|
43
47
|
|
44
48
|
- Add `#deliver_via(*lines)` RSpec matcher. ([@palkan][])
|
45
49
|
|
50
|
+
- **BREAKING** The `#resolve_class` method in Line classes now receive a delivery class instead of a name:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
# before
|
54
|
+
def resolve_class(name)
|
55
|
+
name.gsub(/Delivery$/, "Channel").safe_constantize
|
56
|
+
end
|
57
|
+
|
58
|
+
# after
|
59
|
+
def resolve_class(name)
|
60
|
+
name.to_s.gsub(/Delivery$/, "Channel").safe_constantize
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
46
64
|
- Provide ActionMailer-like interface to trigger notifications. ([@palkan][])
|
47
65
|
|
48
66
|
Now you can send notifications as follows:
|
data/README.md
CHANGED
@@ -113,6 +113,9 @@ PostsDelivery.published(user, post).deliver_later
|
|
113
113
|
PostsMailer.published(user, post).deliver_later
|
114
114
|
PostsSMSNotifier.published(user, post).notify_later
|
115
115
|
|
116
|
+
# You can also pass options supported by your async executor (such as ActiveJob)
|
117
|
+
PostsDelivery.published(user, post).deliver_later(wait_until: 1.day.from_now)
|
118
|
+
|
116
119
|
# and whaterver your ActionCableDeliveryLine does
|
117
120
|
# under the hood.
|
118
121
|
```
|
@@ -706,7 +709,7 @@ end
|
|
706
709
|
|
707
710
|
### Background jobs / async notifications
|
708
711
|
|
709
|
-
To use `#notify_later` you **must** configure an async adapter for Abstract Notifier.
|
712
|
+
To use `#notify_later(**delivery_options)` you **must** configure an async adapter for Abstract Notifier.
|
710
713
|
|
711
714
|
We provide an Active Job adapter out of the box and enable it if Active Job is found.
|
712
715
|
|
@@ -718,13 +721,13 @@ class MyAsyncAdapter
|
|
718
721
|
def initialize(options = {})
|
719
722
|
end
|
720
723
|
|
721
|
-
# `
|
722
|
-
def
|
724
|
+
# `enqueue_delivery` method accepts notifier class, action name and notification parameters
|
725
|
+
def enqueue_delivery(delivery, **options)
|
723
726
|
# <Your implementation here>
|
724
727
|
# To trigger the notification delivery, you can use the following snippet:
|
725
728
|
#
|
726
729
|
# AbstractNotifier::NotificationDelivery.new(
|
727
|
-
# notifier_class
|
730
|
+
# delivery.notifier_class, delivery.action_name, **delivery.delivery_params
|
728
731
|
# ).notify_now
|
729
732
|
end
|
730
733
|
end
|
@@ -11,15 +11,24 @@ module AbstractNotifier
|
|
11
11
|
|
12
12
|
DEFAULT_QUEUE = "notifiers"
|
13
13
|
|
14
|
-
attr_reader :job
|
14
|
+
attr_reader :job, :queue
|
15
15
|
|
16
16
|
def initialize(queue: DEFAULT_QUEUE, job: DeliveryJob)
|
17
|
-
@job = job
|
17
|
+
@job = job
|
18
|
+
@queue = queue
|
18
19
|
end
|
19
20
|
|
20
21
|
def enqueue(...)
|
21
|
-
job.perform_later(...)
|
22
|
+
job.set(queue: queue).perform_later(...)
|
22
23
|
end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :enqueue)
|
24
|
+
|
25
|
+
def enqueue_delivery(delivery, **opts)
|
26
|
+
job.set(queue: queue, **opts).perform_later(
|
27
|
+
delivery.notifier_class.name,
|
28
|
+
delivery.action_name,
|
29
|
+
**delivery.delivery_params
|
30
|
+
)
|
31
|
+
end
|
23
32
|
end
|
24
33
|
end
|
25
34
|
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AbstractNotifier
|
4
|
+
# NotificationDelivery payload wrapper which contains
|
5
|
+
# information about the current notifier class
|
6
|
+
# and knows how to trigger the delivery
|
7
|
+
class NotificationDelivery
|
8
|
+
attr_reader :action_name, :notifier_class
|
9
|
+
|
10
|
+
def initialize(notifier_class, action_name, params: {}, args: [], kwargs: {})
|
11
|
+
@notifier_class = notifier_class
|
12
|
+
@action_name = action_name
|
13
|
+
@params = params
|
14
|
+
@args = args
|
15
|
+
@kwargs = kwargs
|
16
|
+
end
|
17
|
+
|
18
|
+
def processed
|
19
|
+
return @processed if instance_variable_defined?(:@processed)
|
20
|
+
|
21
|
+
@processed = notifier.process_action(action_name, *args, **kwargs) || Notification.new(nil)
|
22
|
+
end
|
23
|
+
|
24
|
+
alias_method :notification, :processed
|
25
|
+
|
26
|
+
def notify_later(**opts)
|
27
|
+
if notifier_class.async_adapter.respond_to?(:enqueue_delivery)
|
28
|
+
notifier_class.async_adapter.enqueue_delivery(self, **opts)
|
29
|
+
else
|
30
|
+
notifier_class.async_adapter.enqueue(notifier_class.name, action_name, params: params, args: args, kwargs: kwargs)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def notify_now
|
35
|
+
return unless notification.payload
|
36
|
+
|
37
|
+
notifier.deliver!(notification)
|
38
|
+
end
|
39
|
+
|
40
|
+
def delivery_params ; {params: params, args: args, kwargs: kwargs}; end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
attr_reader :params, :args, :kwargs
|
45
|
+
|
46
|
+
def notifier
|
47
|
+
@notifier ||= notifier_class.new(action_name, **params)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Notification object contains the compiled payload to be delivered
|
52
|
+
class Notification
|
53
|
+
attr_reader :payload
|
54
|
+
|
55
|
+
def initialize(payload)
|
56
|
+
@payload = payload
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Base class for notifiers
|
61
|
+
class Base
|
62
|
+
class ParamsProxy
|
63
|
+
attr_reader :notifier_class, :params
|
64
|
+
|
65
|
+
def initialize(notifier_class, params)
|
66
|
+
@notifier_class = notifier_class
|
67
|
+
@params = params
|
68
|
+
end
|
69
|
+
|
70
|
+
# rubocop:disable Style/MethodMissingSuper
|
71
|
+
def method_missing(method_name, *args, **kwargs)
|
72
|
+
NotificationDelivery.new(notifier_class, method_name, params: params, args: args, kwargs: kwargs)
|
73
|
+
end
|
74
|
+
# rubocop:enable Style/MethodMissingSuper
|
75
|
+
|
76
|
+
def respond_to_missing?(*args)
|
77
|
+
notifier_class.respond_to_missing?(*args)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class << self
|
82
|
+
attr_writer :driver
|
83
|
+
|
84
|
+
def driver
|
85
|
+
return @driver if instance_variable_defined?(:@driver)
|
86
|
+
|
87
|
+
@driver =
|
88
|
+
if superclass.respond_to?(:driver)
|
89
|
+
superclass.driver
|
90
|
+
else
|
91
|
+
raise "Driver not found for #{name}. " \
|
92
|
+
"Please, specify driver via `self.driver = MyDriver`"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def async_adapter=(args)
|
97
|
+
adapter, options = Array(args)
|
98
|
+
@async_adapter = AsyncAdapters.lookup(adapter, options)
|
99
|
+
end
|
100
|
+
|
101
|
+
def async_adapter
|
102
|
+
return @async_adapter if instance_variable_defined?(:@async_adapter)
|
103
|
+
|
104
|
+
@async_adapter =
|
105
|
+
if superclass.respond_to?(:async_adapter)
|
106
|
+
superclass.async_adapter
|
107
|
+
else
|
108
|
+
AbstractNotifier.async_adapter
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def default(method_name = nil, **hargs, &block)
|
113
|
+
return @defaults_generator = block if block
|
114
|
+
|
115
|
+
return @defaults_generator = proc { send(method_name) } unless method_name.nil?
|
116
|
+
|
117
|
+
@default_params =
|
118
|
+
if superclass.respond_to?(:default_params)
|
119
|
+
superclass.default_params.merge(hargs).freeze
|
120
|
+
else
|
121
|
+
hargs.freeze
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def defaults_generator
|
126
|
+
return @defaults_generator if instance_variable_defined?(:@defaults_generator)
|
127
|
+
|
128
|
+
@defaults_generator =
|
129
|
+
if superclass.respond_to?(:defaults_generator)
|
130
|
+
superclass.defaults_generator
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def default_params
|
135
|
+
return @default_params if instance_variable_defined?(:@default_params)
|
136
|
+
|
137
|
+
@default_params =
|
138
|
+
if superclass.respond_to?(:default_params)
|
139
|
+
superclass.default_params.dup
|
140
|
+
else
|
141
|
+
{}
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def method_missing(method_name, *args, **kwargs)
|
146
|
+
if action_methods.include?(method_name.to_s)
|
147
|
+
NotificationDelivery.new(self, method_name, args: args, kwargs: kwargs)
|
148
|
+
else
|
149
|
+
super
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def with(params)
|
154
|
+
ParamsProxy.new(self, params)
|
155
|
+
end
|
156
|
+
|
157
|
+
def respond_to_missing?(method_name, _include_private = false)
|
158
|
+
action_methods.include?(method_name.to_s) || super
|
159
|
+
end
|
160
|
+
|
161
|
+
# See https://github.com/rails/rails/blob/b13a5cb83ea00d6a3d71320fd276ca21049c2544/actionpack/lib/abstract_controller/base.rb#L74
|
162
|
+
def action_methods
|
163
|
+
@action_methods ||= begin
|
164
|
+
# All public instance methods of this class, including ancestors
|
165
|
+
methods = (public_instance_methods(true) -
|
166
|
+
# Except for public instance methods of Base and its ancestors
|
167
|
+
Base.public_instance_methods(true) +
|
168
|
+
# Be sure to include shadowed public instance methods of this class
|
169
|
+
public_instance_methods(false))
|
170
|
+
|
171
|
+
methods.map!(&:to_s)
|
172
|
+
|
173
|
+
methods.to_set
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
attr_reader :params, :notification_name
|
179
|
+
|
180
|
+
def initialize(notification_name, **params)
|
181
|
+
@notification_name = notification_name
|
182
|
+
@params = params.freeze
|
183
|
+
end
|
184
|
+
|
185
|
+
def process_action(...)
|
186
|
+
public_send(...)
|
187
|
+
end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :process_action)
|
188
|
+
|
189
|
+
def deliver!(notification)
|
190
|
+
self.class.driver.call(notification.payload)
|
191
|
+
end
|
192
|
+
|
193
|
+
def notification(**payload)
|
194
|
+
merge_defaults!(payload)
|
195
|
+
|
196
|
+
payload[:body] = implicit_payload_body unless payload.key?(:body)
|
197
|
+
|
198
|
+
raise ArgumentError, "Notification body must be present" if
|
199
|
+
payload[:body].nil? || payload[:body].empty?
|
200
|
+
|
201
|
+
@notification = Notification.new(payload)
|
202
|
+
end
|
203
|
+
|
204
|
+
private
|
205
|
+
|
206
|
+
def implicit_payload_body
|
207
|
+
# no-op — override to provide custom logic
|
208
|
+
end
|
209
|
+
|
210
|
+
def merge_defaults!(payload)
|
211
|
+
defaults =
|
212
|
+
if self.class.defaults_generator
|
213
|
+
instance_exec(&self.class.defaults_generator)
|
214
|
+
else
|
215
|
+
self.class.default_params
|
216
|
+
end
|
217
|
+
|
218
|
+
defaults.each do |k, v|
|
219
|
+
payload[k] = v unless payload.key?(k)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
@@ -12,9 +12,9 @@ module ActiveDelivery
|
|
12
12
|
@metadata = metadata.freeze
|
13
13
|
end
|
14
14
|
|
15
|
-
def deliver_later ; owner.perform_notify(self); end
|
15
|
+
def deliver_later(**opts) ; owner.perform_notify(self, enqueue_options: opts); end
|
16
16
|
|
17
|
-
def deliver_now ; owner.perform_notify(self, sync: true); end
|
17
|
+
def deliver_now(**opts) ; owner.perform_notify(self, sync: true); end
|
18
18
|
|
19
19
|
def delivery_class ; owner.class; end
|
20
20
|
end
|
@@ -216,22 +216,23 @@ module ActiveDelivery
|
|
216
216
|
|
217
217
|
protected
|
218
218
|
|
219
|
-
def perform_notify(delivery, sync: false)
|
219
|
+
def perform_notify(delivery, sync: false, enqueue_options: {})
|
220
220
|
delivery_lines.each do |type, line|
|
221
221
|
next unless line.notify?(delivery.notification)
|
222
222
|
|
223
|
-
notify_line(type, line, delivery, sync: sync)
|
223
|
+
notify_line(type, line, delivery, sync: sync, enqueue_options: enqueue_options)
|
224
224
|
end
|
225
225
|
end
|
226
226
|
|
227
227
|
private
|
228
228
|
|
229
|
-
def notify_line(type, line, delivery, sync:)
|
229
|
+
def notify_line(type, line, delivery, sync:, enqueue_options:)
|
230
230
|
line.notify(
|
231
231
|
delivery.notification,
|
232
232
|
*delivery.params,
|
233
233
|
params: params,
|
234
234
|
sync: sync,
|
235
|
+
enqueue_options: enqueue_options,
|
235
236
|
**delivery.options
|
236
237
|
)
|
237
238
|
true
|
@@ -37,9 +37,21 @@ module ActiveDelivery
|
|
37
37
|
def notify_later(handler, mid, *__rest__, &__block__)
|
38
38
|
end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :notify_later)
|
39
39
|
|
40
|
-
def
|
40
|
+
def notify_later_with_options(handler, enqueue_options, mid, *__rest__, &__block__)
|
41
|
+
notify_later(handler, mid, *__rest__, &__block__)
|
42
|
+
end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :notify_later_with_options)
|
43
|
+
|
44
|
+
def notify(mid, *args, params:, sync:, enqueue_options:, **kwargs)
|
41
45
|
clazz = params.empty? ? handler_class : handler_class.with(**params)
|
42
|
-
sync
|
46
|
+
if sync
|
47
|
+
return notify_now(clazz, mid, *args, **kwargs)
|
48
|
+
end
|
49
|
+
|
50
|
+
if enqueue_options.empty?
|
51
|
+
notify_later(clazz, mid, *args, **kwargs)
|
52
|
+
else
|
53
|
+
notify_later_with_options(clazz, enqueue_options, mid, *args, **kwargs)
|
54
|
+
end
|
43
55
|
end
|
44
56
|
|
45
57
|
def handler_class
|
@@ -19,6 +19,10 @@ module ActiveDelivery
|
|
19
19
|
def notify_later(mailer, mid, *__rest__, &__block__)
|
20
20
|
mailer.public_send(mid, *__rest__, &__block__).deliver_later
|
21
21
|
end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :notify_later)
|
22
|
+
|
23
|
+
def notify_later_with_options(mailer, enqueue_options, mid, *__rest__, &__block__)
|
24
|
+
mailer.public_send(mid, *__rest__, &__block__).deliver_later(**enqueue_options)
|
25
|
+
end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :notify_later_with_options)
|
22
26
|
end
|
23
27
|
|
24
28
|
ActiveDelivery::Base.register_line :mailer, Mailer, resolver: Mailer::DEFAULT_RESOLVER
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AbstractNotifier
|
4
|
+
module AsyncAdapters
|
5
|
+
class ActiveJob
|
6
|
+
class DeliveryJob < ::ActiveJob::Base
|
7
|
+
def perform(notifier_class, ...)
|
8
|
+
AbstractNotifier::NotificationDelivery.new(notifier_class.constantize, ...).notify_now
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
DEFAULT_QUEUE = "notifiers"
|
13
|
+
|
14
|
+
attr_reader :job, :queue
|
15
|
+
|
16
|
+
def initialize(queue: DEFAULT_QUEUE, job: DeliveryJob)
|
17
|
+
@job = job
|
18
|
+
@queue = queue
|
19
|
+
end
|
20
|
+
|
21
|
+
def enqueue(...)
|
22
|
+
job.set(queue: queue).perform_later(...)
|
23
|
+
end
|
24
|
+
|
25
|
+
def enqueue_delivery(delivery, **opts)
|
26
|
+
job.set(queue: queue, **opts).perform_later(
|
27
|
+
delivery.notifier_class.name,
|
28
|
+
delivery.action_name,
|
29
|
+
**delivery.delivery_params
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
AbstractNotifier.async_adapter ||= :active_job
|
@@ -5,10 +5,10 @@ module AbstractNotifier
|
|
5
5
|
# information about the current notifier class
|
6
6
|
# and knows how to trigger the delivery
|
7
7
|
class NotificationDelivery
|
8
|
-
attr_reader :action_name
|
8
|
+
attr_reader :action_name, :notifier_class
|
9
9
|
|
10
|
-
def initialize(
|
11
|
-
@
|
10
|
+
def initialize(notifier_class, action_name, params: {}, args: [], kwargs: {})
|
11
|
+
@notifier_class = notifier_class
|
12
12
|
@action_name = action_name
|
13
13
|
@params = params
|
14
14
|
@args = args
|
@@ -23,8 +23,12 @@ module AbstractNotifier
|
|
23
23
|
|
24
24
|
alias_method :notification, :processed
|
25
25
|
|
26
|
-
def notify_later
|
27
|
-
|
26
|
+
def notify_later(**opts)
|
27
|
+
if notifier_class.async_adapter.respond_to?(:enqueue_delivery)
|
28
|
+
notifier_class.async_adapter.enqueue_delivery(self, **opts)
|
29
|
+
else
|
30
|
+
notifier_class.async_adapter.enqueue(notifier_class.name, action_name, params: params, args: args, kwargs: kwargs)
|
31
|
+
end
|
28
32
|
end
|
29
33
|
|
30
34
|
def notify_now
|
@@ -33,12 +37,14 @@ module AbstractNotifier
|
|
33
37
|
notifier.deliver!(notification)
|
34
38
|
end
|
35
39
|
|
40
|
+
def delivery_params ; {params: params, args: args, kwargs: kwargs}; end
|
41
|
+
|
36
42
|
private
|
37
43
|
|
38
|
-
attr_reader :
|
44
|
+
attr_reader :params, :args, :kwargs
|
39
45
|
|
40
46
|
def notifier
|
41
|
-
@notifier ||=
|
47
|
+
@notifier ||= notifier_class.new(action_name, **params)
|
42
48
|
end
|
43
49
|
end
|
44
50
|
|
@@ -178,7 +184,7 @@ module AbstractNotifier
|
|
178
184
|
|
179
185
|
def process_action(...)
|
180
186
|
public_send(...)
|
181
|
-
end
|
187
|
+
end
|
182
188
|
|
183
189
|
def deliver!(notification)
|
184
190
|
self.class.driver.call(notification.payload)
|
@@ -12,9 +12,9 @@ module ActiveDelivery
|
|
12
12
|
@metadata = metadata.freeze
|
13
13
|
end
|
14
14
|
|
15
|
-
def deliver_later = owner.perform_notify(self)
|
15
|
+
def deliver_later(**opts) = owner.perform_notify(self, enqueue_options: opts)
|
16
16
|
|
17
|
-
def deliver_now = owner.perform_notify(self, sync: true)
|
17
|
+
def deliver_now(**opts) = owner.perform_notify(self, sync: true)
|
18
18
|
|
19
19
|
def delivery_class = owner.class
|
20
20
|
end
|
@@ -216,22 +216,23 @@ module ActiveDelivery
|
|
216
216
|
|
217
217
|
protected
|
218
218
|
|
219
|
-
def perform_notify(delivery, sync: false)
|
219
|
+
def perform_notify(delivery, sync: false, enqueue_options: {})
|
220
220
|
delivery_lines.each do |type, line|
|
221
221
|
next unless line.notify?(delivery.notification)
|
222
222
|
|
223
|
-
notify_line(type, line, delivery, sync: sync)
|
223
|
+
notify_line(type, line, delivery, sync: sync, enqueue_options: enqueue_options)
|
224
224
|
end
|
225
225
|
end
|
226
226
|
|
227
227
|
private
|
228
228
|
|
229
|
-
def notify_line(type, line, delivery, sync:)
|
229
|
+
def notify_line(type, line, delivery, sync:, enqueue_options:)
|
230
230
|
line.notify(
|
231
231
|
delivery.notification,
|
232
232
|
*delivery.params,
|
233
233
|
params: params,
|
234
234
|
sync: sync,
|
235
|
+
enqueue_options: enqueue_options,
|
235
236
|
**delivery.options
|
236
237
|
)
|
237
238
|
true
|
@@ -37,9 +37,21 @@ module ActiveDelivery
|
|
37
37
|
def notify_later(handler, mid, ...)
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
40
|
+
def notify_later_with_options(handler, enqueue_options, mid, ...)
|
41
|
+
notify_later(handler, mid, ...)
|
42
|
+
end
|
43
|
+
|
44
|
+
def notify(mid, *args, params:, sync:, enqueue_options:, **kwargs)
|
41
45
|
clazz = params.empty? ? handler_class : handler_class.with(**params)
|
42
|
-
sync
|
46
|
+
if sync
|
47
|
+
return notify_now(clazz, mid, *args, **kwargs)
|
48
|
+
end
|
49
|
+
|
50
|
+
if enqueue_options.empty?
|
51
|
+
notify_later(clazz, mid, *args, **kwargs)
|
52
|
+
else
|
53
|
+
notify_later_with_options(clazz, enqueue_options, mid, *args, **kwargs)
|
54
|
+
end
|
43
55
|
end
|
44
56
|
|
45
57
|
def handler_class
|
@@ -11,14 +11,23 @@ module AbstractNotifier
|
|
11
11
|
|
12
12
|
DEFAULT_QUEUE = "notifiers"
|
13
13
|
|
14
|
-
attr_reader :job
|
14
|
+
attr_reader :job, :queue
|
15
15
|
|
16
16
|
def initialize(queue: DEFAULT_QUEUE, job: DeliveryJob)
|
17
|
-
@job = job
|
17
|
+
@job = job
|
18
|
+
@queue = queue
|
18
19
|
end
|
19
20
|
|
20
21
|
def enqueue(...)
|
21
|
-
job.perform_later(...)
|
22
|
+
job.set(queue:).perform_later(...)
|
23
|
+
end
|
24
|
+
|
25
|
+
def enqueue_delivery(delivery, **opts)
|
26
|
+
job.set(queue:, **opts).perform_later(
|
27
|
+
delivery.notifier_class.name,
|
28
|
+
delivery.action_name,
|
29
|
+
**delivery.delivery_params
|
30
|
+
)
|
22
31
|
end
|
23
32
|
end
|
24
33
|
end
|
@@ -5,10 +5,10 @@ module AbstractNotifier
|
|
5
5
|
# information about the current notifier class
|
6
6
|
# and knows how to trigger the delivery
|
7
7
|
class NotificationDelivery
|
8
|
-
attr_reader :action_name
|
8
|
+
attr_reader :action_name, :notifier_class
|
9
9
|
|
10
|
-
def initialize(
|
11
|
-
@
|
10
|
+
def initialize(notifier_class, action_name, params: {}, args: [], kwargs: {})
|
11
|
+
@notifier_class = notifier_class
|
12
12
|
@action_name = action_name
|
13
13
|
@params = params
|
14
14
|
@args = args
|
@@ -23,8 +23,12 @@ module AbstractNotifier
|
|
23
23
|
|
24
24
|
alias_method :notification, :processed
|
25
25
|
|
26
|
-
def notify_later
|
27
|
-
|
26
|
+
def notify_later(**opts)
|
27
|
+
if notifier_class.async_adapter.respond_to?(:enqueue_delivery)
|
28
|
+
notifier_class.async_adapter.enqueue_delivery(self, **opts)
|
29
|
+
else
|
30
|
+
notifier_class.async_adapter.enqueue(notifier_class.name, action_name, params:, args:, kwargs:)
|
31
|
+
end
|
28
32
|
end
|
29
33
|
|
30
34
|
def notify_now
|
@@ -33,12 +37,14 @@ module AbstractNotifier
|
|
33
37
|
notifier.deliver!(notification)
|
34
38
|
end
|
35
39
|
|
40
|
+
def delivery_params = {params:, args:, kwargs:}
|
41
|
+
|
36
42
|
private
|
37
43
|
|
38
|
-
attr_reader :
|
44
|
+
attr_reader :params, :args, :kwargs
|
39
45
|
|
40
46
|
def notifier
|
41
|
-
@notifier ||=
|
47
|
+
@notifier ||= notifier_class.new(action_name, **params)
|
42
48
|
end
|
43
49
|
end
|
44
50
|
|
@@ -36,12 +36,12 @@ module AbstractNotifier
|
|
36
36
|
Driver.send_notification payload.merge(via: notifier.class)
|
37
37
|
end
|
38
38
|
|
39
|
-
def notify_later
|
39
|
+
def notify_later(**opts)
|
40
40
|
return super unless AbstractNotifier.test?
|
41
41
|
|
42
42
|
payload = notification.payload
|
43
43
|
|
44
|
-
Driver.enqueue_notification payload.merge(via: notifier.class)
|
44
|
+
Driver.enqueue_notification payload.merge(via: notifier.class, **opts)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
data/lib/active_delivery/base.rb
CHANGED
@@ -12,9 +12,9 @@ module ActiveDelivery
|
|
12
12
|
@metadata = metadata.freeze
|
13
13
|
end
|
14
14
|
|
15
|
-
def deliver_later = owner.perform_notify(self)
|
15
|
+
def deliver_later(**opts) = owner.perform_notify(self, enqueue_options: opts)
|
16
16
|
|
17
|
-
def deliver_now = owner.perform_notify(self, sync: true)
|
17
|
+
def deliver_now(**opts) = owner.perform_notify(self, sync: true)
|
18
18
|
|
19
19
|
def delivery_class = owner.class
|
20
20
|
end
|
@@ -216,22 +216,23 @@ module ActiveDelivery
|
|
216
216
|
|
217
217
|
protected
|
218
218
|
|
219
|
-
def perform_notify(delivery, sync: false)
|
219
|
+
def perform_notify(delivery, sync: false, enqueue_options: {})
|
220
220
|
delivery_lines.each do |type, line|
|
221
221
|
next unless line.notify?(delivery.notification)
|
222
222
|
|
223
|
-
notify_line(type, line, delivery, sync:)
|
223
|
+
notify_line(type, line, delivery, sync:, enqueue_options:)
|
224
224
|
end
|
225
225
|
end
|
226
226
|
|
227
227
|
private
|
228
228
|
|
229
|
-
def notify_line(type, line, delivery, sync:)
|
229
|
+
def notify_line(type, line, delivery, sync:, enqueue_options:)
|
230
230
|
line.notify(
|
231
231
|
delivery.notification,
|
232
232
|
*delivery.params,
|
233
233
|
params:,
|
234
234
|
sync:,
|
235
|
+
enqueue_options:,
|
235
236
|
**delivery.options
|
236
237
|
)
|
237
238
|
true
|
@@ -37,9 +37,21 @@ module ActiveDelivery
|
|
37
37
|
def notify_later(handler, mid, ...)
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
40
|
+
def notify_later_with_options(handler, enqueue_options, mid, ...)
|
41
|
+
notify_later(handler, mid, ...)
|
42
|
+
end
|
43
|
+
|
44
|
+
def notify(mid, *args, params:, sync:, enqueue_options:, **kwargs)
|
41
45
|
clazz = params.empty? ? handler_class : handler_class.with(**params)
|
42
|
-
sync
|
46
|
+
if sync
|
47
|
+
return notify_now(clazz, mid, *args, **kwargs)
|
48
|
+
end
|
49
|
+
|
50
|
+
if enqueue_options.empty?
|
51
|
+
notify_later(clazz, mid, *args, **kwargs)
|
52
|
+
else
|
53
|
+
notify_later_with_options(clazz, enqueue_options, mid, *args, **kwargs)
|
54
|
+
end
|
43
55
|
end
|
44
56
|
|
45
57
|
def handler_class
|
@@ -19,6 +19,10 @@ module ActiveDelivery
|
|
19
19
|
def notify_later(mailer, mid, ...)
|
20
20
|
mailer.public_send(mid, ...).deliver_later
|
21
21
|
end
|
22
|
+
|
23
|
+
def notify_later_with_options(mailer, enqueue_options, mid, ...)
|
24
|
+
mailer.public_send(mid, ...).deliver_later(**enqueue_options)
|
25
|
+
end
|
22
26
|
end
|
23
27
|
|
24
28
|
ActiveDelivery::Base.register_line :mailer, Mailer, resolver: Mailer::DEFAULT_RESOLVER
|
@@ -38,6 +38,10 @@ module ActiveDelivery
|
|
38
38
|
handler.public_send(mid, *args).notify_later
|
39
39
|
end
|
40
40
|
|
41
|
+
def notify_later_with_options(handler, enqueue_options, mid, *args)
|
42
|
+
handler.public_send(mid, *args).notify_later(**enqueue_options)
|
43
|
+
end
|
44
|
+
|
41
45
|
private
|
42
46
|
|
43
47
|
attr_reader :resolver
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_delivery
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,11 +94,13 @@ files:
|
|
94
94
|
- bin/console
|
95
95
|
- bin/setup
|
96
96
|
- lib/.rbnext/3.0/abstract_notifier/async_adapters/active_job.rb
|
97
|
+
- lib/.rbnext/3.0/abstract_notifier/base.rb
|
97
98
|
- lib/.rbnext/3.0/active_delivery/base.rb
|
98
99
|
- lib/.rbnext/3.0/active_delivery/callbacks.rb
|
99
100
|
- lib/.rbnext/3.0/active_delivery/lines/base.rb
|
100
101
|
- lib/.rbnext/3.0/active_delivery/lines/mailer.rb
|
101
102
|
- lib/.rbnext/3.0/active_delivery/testing.rb
|
103
|
+
- lib/.rbnext/3.1/abstract_notifier/async_adapters/active_job.rb
|
102
104
|
- lib/.rbnext/3.1/abstract_notifier/base.rb
|
103
105
|
- lib/.rbnext/3.1/active_delivery/base.rb
|
104
106
|
- lib/.rbnext/3.1/active_delivery/lines/base.rb
|
@@ -146,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
148
|
- !ruby/object:Gem::Version
|
147
149
|
version: '0'
|
148
150
|
requirements: []
|
149
|
-
rubygems_version: 3.4.
|
151
|
+
rubygems_version: 3.4.20
|
150
152
|
signing_key:
|
151
153
|
specification_version: 4
|
152
154
|
summary: Ruby and Rails framework for managing all types of notifications in one place
|