lambdakiq 1.0.1 → 2.0.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 +13 -2
- data/Gemfile.lock +1 -1
- data/README.md +73 -49
- data/lib/lambdakiq/error.rb +0 -10
- data/lib/lambdakiq/job.rb +9 -4
- data/lib/lambdakiq/metrics.rb +13 -2
- data/lib/lambdakiq/version.rb +1 -1
- data/lib/lambdakiq/worker.rb +4 -0
- 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: 94804599e9c2e4f8f701c34cee61a7d18db8f9a20fee85a3e24681e2bd555076
|
|
4
|
+
data.tar.gz: 7550236dacfc649a36468bbc4b3a7116a03b90d5943df4cdb0c08f7521ad505f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e7592aaa326a0ed6fa6202c0877b61ed67f00d156078d37840dda13ee4a455ff4de1ac35a377dd95230288fdc6ae054b974ef990190c0a46b59a45eb81c10ee5
|
|
7
|
+
data.tar.gz: 2f8efaa743a20710fd57ad2aa1b0cf8983828100b6ec5880f0815320f186216a5420e362d24b1b21b4e0ae78187c75e517afc4e27ddf5f9d3c3b295803101c16
|
data/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
|
-
|
|
2
1
|
# Keep A Changelog!
|
|
3
2
|
|
|
4
3
|
See this http://keepachangelog.com link for information on how we want this documented formatted.
|
|
5
4
|
|
|
5
|
+
## v2.0.0
|
|
6
|
+
|
|
7
|
+
#### Changed
|
|
8
|
+
|
|
9
|
+
- Leverage new `ReportBatchItemFailures` feature of SQS.
|
|
10
|
+
|
|
11
|
+
## v1.0.2, v1.0.3, v1.0.4
|
|
12
|
+
|
|
13
|
+
#### Fixed
|
|
14
|
+
|
|
15
|
+
- Rails v5.2 compatibility. Metrics logging is are safe for non-Lambdakiq jobs
|
|
16
|
+
|
|
6
17
|
## v1.0.0
|
|
7
18
|
|
|
8
19
|
#### Added
|
|
9
20
|
|
|
10
|
-
|
|
21
|
+
- Initial release.
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-

|
|
2
|
-
|
|
3
1
|

|
|
4
2
|
|
|
3
|
+

|
|
4
|
+
|
|
5
5
|
# Lambdakiq
|
|
6
6
|
|
|
7
7
|
<a href="https://lamby.custominktech.com"><img src="https://user-images.githubusercontent.com/2381/59363668-89edeb80-8d03-11e9-9985-2ce14361b7e3.png" alt="Lamby: Simple Rails & AWS Lambda Integration using Rack." align="right" width="300" /></a>A drop-in replacement for [Sidekiq](https://github.com/mperham/sidekiq) when running Rails in AWS Lambda using the [Lamby](https://lamby.custominktech.com) gem.
|
|
@@ -10,19 +10,18 @@ Lambdakiq allows you to leverage AWS' managed infrastructure to the fullest exte
|
|
|
10
10
|
|
|
11
11
|
## Key Features
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
- Distinct web & jobs Lambda functions.
|
|
14
|
+
- AWS fully managed polling. Event-driven.
|
|
15
|
+
- Maximum 12 retries. Per job configurable.
|
|
16
|
+
- Mirror Sidekiq's retry [backoff](https://github.com/mperham/sidekiq/wiki/Error-Handling#automatic-job-retry) timing.
|
|
17
|
+
- Last retry is at 11 hours 30 minutes.
|
|
18
|
+
- Supports ActiveJob's wait/delay. Up to 15 minutes.
|
|
19
|
+
- Dead messages are stored for up to 14 days.
|
|
20
20
|
|
|
21
21
|
## Project Setup
|
|
22
22
|
|
|
23
23
|
This gem assumes your Rails application is on AWS Lambda, ideally with our [Lamby](https://lamby.custominktech.com) gem. It could be using Lambda's traditional zip package type or the newer [container](https://dev.to/aws-heroes/lambda-containers-with-rails-a-perfect-match-4lgb) format. If Rails on Lambda is new to you, consider following our [quick start](https://lamby.custominktech.com/docs/quick_start) guide to get your first application up and running. From there, to use Lambdakiq, here are steps to setup your project
|
|
24
24
|
|
|
25
|
-
|
|
26
25
|
### Bundle & Config
|
|
27
26
|
|
|
28
27
|
Add the Lambdakiq gem to your `Gemfile`.
|
|
@@ -31,7 +30,7 @@ Add the Lambdakiq gem to your `Gemfile`.
|
|
|
31
30
|
gem 'lambdakiq'
|
|
32
31
|
```
|
|
33
32
|
|
|
34
|
-
Open `config/
|
|
33
|
+
Open `config/environments/production.rb` and set Lambdakiq as your ActiveJob queue adapter.
|
|
35
34
|
|
|
36
35
|
```ruby
|
|
37
36
|
config.active_job.queue_adapter = :lambdakiq
|
|
@@ -46,6 +45,33 @@ class ApplicationJob < ActiveJob::Base
|
|
|
46
45
|
end
|
|
47
46
|
```
|
|
48
47
|
|
|
48
|
+
Using ActionMailer's built-in deliver job with ActiveJob? Make sure to include the Lambdakiq worker and set the queue name depending on your Rails version. You can do this in a newly created `config/initializers//action_mailer.rb` or another initializer of your choice.
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
# Rails 5.x
|
|
52
|
+
ActionMailer::DeliveryJob.include Lambdakiq::Worker
|
|
53
|
+
ActionMailer::DeliveryJob.queue_as ENV['JOBS_QUEUE_NAME']
|
|
54
|
+
# Rails 6.x
|
|
55
|
+
ActionMailer::MailDeliveryJob.include Lambdakiq::Worker
|
|
56
|
+
ActionMailer::MailDeliveryJob.queue_as ENV['JOBS_QUEUE_NAME']
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The same Docker image will be used for both your `web` and `jobs` functions (example setup in following sections) which means the same `app.rb` handler would be used. The [Lamby](https://lamby.custominktech.com) gem automatically detects if Lambdakiq is being used so the following handler works as is.
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
def handler(event:, context:)
|
|
63
|
+
Lamby.handler $app, event, context
|
|
64
|
+
end
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
You can use the Lambdakiq handler directly in cases where your handler is a different method. Likewise there is a `Lambdakiq.jobs?(event)` helper function which returns true if the `messageAttributes` has a `lambdakiq` attribute.
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
def jobs_handler(event:, context:)
|
|
71
|
+
Lambdakiq.handler(event)
|
|
72
|
+
end
|
|
73
|
+
```
|
|
74
|
+
|
|
49
75
|
### SQS Resources
|
|
50
76
|
|
|
51
77
|
Open up your project's SAM [`template.yaml`](https://lamby.custominktech.com/docs/anatomy#file-template-yaml) file and make the following additions and changes. First, we need to create your [SQS queues](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html) under the `Resources` section.
|
|
@@ -91,7 +117,7 @@ Both functions will need capabilities to access the SQS jobs queue. We can add o
|
|
|
91
117
|
|
|
92
118
|
```yaml
|
|
93
119
|
Policies:
|
|
94
|
-
- Version:
|
|
120
|
+
- Version: "2012-10-17"
|
|
95
121
|
Statement:
|
|
96
122
|
- Effect: Allow
|
|
97
123
|
Action:
|
|
@@ -100,6 +126,8 @@ Policies:
|
|
|
100
126
|
- !Sub arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:${JobsQueue.QueueName}
|
|
101
127
|
```
|
|
102
128
|
|
|
129
|
+
### Overview
|
|
130
|
+
|
|
103
131
|
Now we can duplicate our `RailsLambda` resource YAML (except for the `Events` property) to a new `JobsLambda` one. This gives us a distinct Lambda function to process jobs whose events, memory, timeout, and more can be independently tuned. However, both the `web` and `jobs` functions will use the same ECR container image!
|
|
104
132
|
|
|
105
133
|
```yaml
|
|
@@ -116,10 +144,12 @@ JobsLambda:
|
|
|
116
144
|
Properties:
|
|
117
145
|
Queue: !GetAtt JobsQueue.Arn
|
|
118
146
|
BatchSize: 1
|
|
147
|
+
FunctionResponseTypes:
|
|
148
|
+
- ReportBatchItemFailures
|
|
119
149
|
MemorySize: 1792
|
|
120
150
|
PackageType: Image
|
|
121
151
|
Policies:
|
|
122
|
-
- Version:
|
|
152
|
+
- Version: "2012-10-17"
|
|
123
153
|
Statement:
|
|
124
154
|
- Effect: Allow
|
|
125
155
|
Action:
|
|
@@ -131,10 +161,10 @@ JobsLambda:
|
|
|
131
161
|
|
|
132
162
|
Here are some key aspects of our `JobsLambda` resource above:
|
|
133
163
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
164
|
+
- The `Events` property uses the [SQS Type](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-sqs.html).
|
|
165
|
+
- The [BatchSize](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-sqs.html#sam-function-sqs-batchsize) can be any number you like. Less means more Lambda concurrency, more means some jobs could take longer. The jobs function `Timeout` must be lower than the `JobsQueue`'s `VisibilityTimeout` property. When the batch size is one, the queue's visibility is generally one second more.
|
|
166
|
+
- You must use `ReportBatchItemFailures` response types. Lambdakiq assumes we are [reporting batch item failures](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#services-sqs-batchfailurereporting). This is a new feature of SQS introduced in [November 2021](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#services-sqs-batchfailurereporting).
|
|
167
|
+
- The `Metadata`'s Docker properties must be the same as our web function except for the `DockerTag`. This is needed for the image to be shared. This works around a known [SAM issue](https://github.com/aws/aws-sam-cli/issues/2466) vs using the `ImageConfig` property.
|
|
138
168
|
|
|
139
169
|
🎉 Deploy your application and have fun with ActiveJob on SQS & Lambda.
|
|
140
170
|
|
|
@@ -148,9 +178,9 @@ Most general Lambdakiq configuration options are exposed via the Rails standard
|
|
|
148
178
|
config.lambdakiq
|
|
149
179
|
```
|
|
150
180
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
181
|
+
- `max_retries=` - Retries for all jobs. Default is the Lambdakiq maximum of `12`.
|
|
182
|
+
- `metrics_namespace=` - The CloudWatch Embedded Metrics namespace. Default is `Lambdakiq`.
|
|
183
|
+
- `metrics_logger=` - Set to the Rails logger which is STDOUT via Lamby/Lambda.
|
|
154
184
|
|
|
155
185
|
### ActiveJob Configs
|
|
156
186
|
|
|
@@ -162,13 +192,7 @@ class OrderProcessorJob < ApplicationJob
|
|
|
162
192
|
end
|
|
163
193
|
```
|
|
164
194
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
## Concurrency & Limits
|
|
168
|
-
|
|
169
|
-
AWS SQS is highly scalable with [few limits](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-quotas.html). As your jobs in SQS increases so should your concurrent functions to process that work. However, as this article, ["Why isn't my Lambda function with an Amazon SQS event source scaling optimally?"](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-sqs-scaling/) describes it is possible that errors will effect your concurrency.
|
|
170
|
-
|
|
171
|
-
To help keep your queue and workers scalable, reduce the errors raised by your jobs. You an also reduce the retry count.
|
|
195
|
+
- `retry` - Overrides the default Lambdakiq `max_retries` for this one job.
|
|
172
196
|
|
|
173
197
|
## Observability with CloudWatch
|
|
174
198
|
|
|
@@ -180,42 +204,43 @@ Metrics are published under the `Lambdakiq` namespace. This is configurable usin
|
|
|
180
204
|
|
|
181
205
|
### Metric Dimensions
|
|
182
206
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
207
|
+
- `AppName` - This is the name of your Rails application. Ex: `MyApp`
|
|
208
|
+
- `JobEvent` - Name of the ActiveSupport Notification. Ex: `*.active_job`.
|
|
209
|
+
- `JobName` - The class name of the ActiveSupport job. Ex: `NotificationJob`
|
|
186
210
|
|
|
187
211
|
### ActiveJob Event Names
|
|
212
|
+
|
|
188
213
|
For reference, here are the `JobEvent` names published by ActiveSupport. A few of these are instrumented by Lambdakiq since we use custom retry logic like Sidekiq. These event/metrics are found in the Rails application CloudWatch logs because they publish/enqueue jobs.
|
|
189
214
|
|
|
190
|
-
|
|
191
|
-
|
|
215
|
+
- `enqueue.active_job`
|
|
216
|
+
- `enqueue_at.active_job`
|
|
192
217
|
|
|
193
218
|
While these event/metrics can be found in the jobs function's log.
|
|
194
219
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
220
|
+
- `perform_start.active_job`
|
|
221
|
+
- `perform.active_job`
|
|
222
|
+
- `enqueue_retry.active_job`
|
|
223
|
+
- `retry_stopped.active_job`
|
|
199
224
|
|
|
200
225
|
### Metric Properties
|
|
201
226
|
|
|
202
227
|
These are the properties published with each metric. Remember, properties can not be used as metric data in charts but can be searched using [CloudWatch Logs Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html).
|
|
203
228
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
229
|
+
- `JobId` - ActiveJob Unique ID. Ex: `9f3b6977-6afc-4769-aed6-bab1ad9a0df5`
|
|
230
|
+
- `QueueName` - SQS Queue Name. Ex: `myapp-JobsQueue-14F18LG6XFUW5.fifo`
|
|
231
|
+
- `MessageId` - SQS Message ID. Ex: `5653246d-dc5e-4c95-9583-b6b83ec78602`
|
|
232
|
+
- `ExceptionName` - Class name of error raised. Present in perform and retry events.
|
|
233
|
+
- `EnqueuedAt` - When ActiveJob enqueued the message. Ex: `2021-01-14T01:43:38Z`
|
|
234
|
+
- `Executions` - The number of current executions. Counts from `1` and up.
|
|
235
|
+
- `JobArg#{n}` - Enumerated serialized arguments.
|
|
211
236
|
|
|
212
237
|
### Metric Data
|
|
213
238
|
|
|
214
239
|
And finally, here are the metrics which each dimension can chart using [CloudWatch Metrics & Dashboards](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Dashboards.html).
|
|
215
240
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
241
|
+
- `Duration` - Of the job event in milliseconds.
|
|
242
|
+
- `Count` - Of the event.
|
|
243
|
+
- `ExceptionCount` - Of the event. Useful with `ExceptionName`.
|
|
219
244
|
|
|
220
245
|
### CloudWatch Dashboard Examples
|
|
221
246
|
|
|
@@ -223,15 +248,14 @@ Please share how you are using CloudWatch to monitor and/or alert on your Active
|
|
|
223
248
|
|
|
224
249
|
💬 https://github.com/customink/lambdakiq/discussions/3
|
|
225
250
|
|
|
226
|
-
|
|
227
251
|
## Common Questions
|
|
228
252
|
|
|
229
253
|
**Are Scheduled Jobs Supported?** - No. If you need a scheduled job please use the [SAM Schedule](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-schedule.html) event source which invokes your function with an [Eventbridege AWS::Events::Rule](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-events-rule.html).
|
|
230
254
|
|
|
231
255
|
**Are FIFO Queues Supported?** - Yes. When you create your [AWS::SQS::Queue](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html) resources you can set the [FifoQueue](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html#aws-sqs-queue-fifoqueue) property to `true`. Remember that both your jobs queue and the redrive queue must be the same. When using FIFO we:
|
|
232
256
|
|
|
233
|
-
|
|
234
|
-
|
|
257
|
+
- Simulate `delay_seconds` for ActiveJob's wait by using visibility timeouts under the hood. We still cap it to non-FIFO's 15 minutes.
|
|
258
|
+
- Set both the messages `message_group_id` and `message_deduplication_id` to the unique job id provided by ActiveJob.
|
|
235
259
|
|
|
236
260
|
**Can I Use Multiple Queues?** - Yes. Nothing is stopping you from creating any number of queues and/or functions to process them. Your subclasses can use ActiveJob's `queue_as` method as needed. This is an easy way to handle job priorities too.
|
|
237
261
|
|
data/lib/lambdakiq/error.rb
CHANGED
|
@@ -2,16 +2,6 @@ module Lambdakiq
|
|
|
2
2
|
class Error < StandardError
|
|
3
3
|
end
|
|
4
4
|
|
|
5
|
-
class JobError < Error
|
|
6
|
-
attr_reader :original_exception, :job
|
|
7
|
-
|
|
8
|
-
def initialize(error)
|
|
9
|
-
@original_exception = error
|
|
10
|
-
super(error.message)
|
|
11
|
-
set_backtrace Rails.backtrace_cleaner.clean(error.backtrace)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
5
|
class FifoDelayError < Error
|
|
16
6
|
def initialize(error)
|
|
17
7
|
super
|
data/lib/lambdakiq/job.rb
CHANGED
|
@@ -9,9 +9,9 @@ module Lambdakiq
|
|
|
9
9
|
records = Event.records(event)
|
|
10
10
|
jobs = records.map { |record| new(record) }
|
|
11
11
|
jobs.each(&:perform)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
failed_jobs = jobs.select { |j| j.error }
|
|
13
|
+
item_failures = failed_jobs.map { |j| { itemIdentifier: j.provider_job_id } }
|
|
14
|
+
{ batchItemFailures: item_failures }
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
end
|
|
@@ -40,10 +40,14 @@ module Lambdakiq
|
|
|
40
40
|
active_job.executions
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
+
def provider_job_id
|
|
44
|
+
active_job.provider_job_id
|
|
45
|
+
end
|
|
46
|
+
|
|
43
47
|
def perform
|
|
44
48
|
if fifo_delay?
|
|
45
49
|
fifo_delay
|
|
46
|
-
|
|
50
|
+
return
|
|
47
51
|
end
|
|
48
52
|
execute
|
|
49
53
|
end
|
|
@@ -104,6 +108,7 @@ module Lambdakiq
|
|
|
104
108
|
end
|
|
105
109
|
|
|
106
110
|
def fifo_delay
|
|
111
|
+
@error = FifoDelayError.new(active_job.job_id)
|
|
107
112
|
params = client_params.merge visibility_timeout: record.fifo_delay_visibility_timeout
|
|
108
113
|
client.change_message_visibility(params)
|
|
109
114
|
end
|
data/lib/lambdakiq/metrics.rb
CHANGED
|
@@ -16,6 +16,7 @@ module Lambdakiq
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def log
|
|
19
|
+
return unless lambdakiq?
|
|
19
20
|
logger.info JSON.dump(message)
|
|
20
21
|
end
|
|
21
22
|
|
|
@@ -29,6 +30,16 @@ module Lambdakiq
|
|
|
29
30
|
job.class.name
|
|
30
31
|
end
|
|
31
32
|
|
|
33
|
+
def adapter_name
|
|
34
|
+
event.payload[:adapter].class.name
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def lambdakiq?
|
|
38
|
+
adapter_name.include?('Lambdakiq') &&
|
|
39
|
+
job.respond_to?(:lambdakiq?) &&
|
|
40
|
+
job.lambdakiq?
|
|
41
|
+
end
|
|
42
|
+
|
|
32
43
|
def logger
|
|
33
44
|
Lambdakiq.config.metrics_logger
|
|
34
45
|
end
|
|
@@ -51,6 +62,7 @@ module Lambdakiq
|
|
|
51
62
|
end
|
|
52
63
|
|
|
53
64
|
def instrument!
|
|
65
|
+
return unless lambdakiq?
|
|
54
66
|
put_metric 'Duration', event.duration.to_i, 'Milliseconds'
|
|
55
67
|
put_metric 'Count', 1, 'Count'
|
|
56
68
|
put_metric 'ExceptionCount', 1, 'Count' if exception_name
|
|
@@ -59,7 +71,7 @@ module Lambdakiq
|
|
|
59
71
|
set_property 'QueueName', job.queue_name
|
|
60
72
|
set_property 'MessageId', job.provider_job_id if job.provider_job_id
|
|
61
73
|
set_property 'ExceptionName', exception_name if exception_name
|
|
62
|
-
set_property 'EnqueuedAt', job.enqueued_at if job.enqueued_at
|
|
74
|
+
set_property 'EnqueuedAt', job.enqueued_at if job.respond_to?(:enqueued_at) && job.enqueued_at
|
|
63
75
|
set_property 'Executions', job.executions if job.executions
|
|
64
76
|
job.arguments.each_with_index do |argument, index|
|
|
65
77
|
set_property "JobArg#{index+1}", argument
|
|
@@ -107,4 +119,3 @@ module Lambdakiq
|
|
|
107
119
|
|
|
108
120
|
end
|
|
109
121
|
end
|
|
110
|
-
|
data/lib/lambdakiq/version.rb
CHANGED
data/lib/lambdakiq/worker.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lambdakiq
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ken Collins
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-11-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activejob
|