pallets 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/LICENSE +1 -1
- data/README.md +6 -6
- data/examples/config_savvy.rb +0 -3
- data/lib/pallets.rb +5 -1
- data/lib/pallets/backends/base.rb +6 -1
- data/lib/pallets/backends/redis.rb +18 -5
- data/lib/pallets/backends/scripts/discard.lua +11 -0
- data/lib/pallets/backends/scripts/give_up.lua +6 -1
- data/lib/pallets/backends/scripts/save.lua +4 -4
- data/lib/pallets/cli.rb +4 -0
- data/lib/pallets/configuration.rb +5 -10
- data/lib/pallets/logger.rb +10 -2
- data/lib/pallets/middleware/job_logger.rb +19 -8
- data/lib/pallets/version.rb +1 -1
- data/lib/pallets/worker.rb +6 -6
- data/pallets.gemspec +3 -3
- metadata +12 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ede234db1dfe8c744cf11e6e2fde3eb2e982e7764738715acbbad35710422274
|
4
|
+
data.tar.gz: a55b3a714dcc5db2a294b27ca53724a1236111e08f63078bcef5007bda65532c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74e23087ba192aeffeb7e167d751bfb6f85de4018fb3c16e992ac6119d7670d60862f41a8e1624817a25944409602e41ee38f13adad7b14a38b185d51142b644
|
7
|
+
data.tar.gz: 96ae4f2aa4edf5d27d366e7a35f16527e9d390a45794d306acc109b1be335682c8b1e13e7d708d7eb3451eb8b6ed96db37ba724da08abb13d7b84f3468869826
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.9.0] - 2020-07-05
|
10
|
+
### Added
|
11
|
+
- limit number of jobs in given up set by number (#56)
|
12
|
+
- job duration and metadata to all task logs (#57)
|
13
|
+
|
14
|
+
### Changed
|
15
|
+
- remove all related workflow keys when giving up on a job (#55)
|
16
|
+
- support redis-rb ~> 4.2 (#58)
|
17
|
+
|
18
|
+
### Removed
|
19
|
+
- support for configuring custom loggers (#57)
|
20
|
+
|
9
21
|
## [0.8.0] - 2020-06-09
|
10
22
|
### Added
|
11
23
|
- sync output in CLI (#49)
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.com/linkyndy/pallets.svg?branch=master)](https://travis-ci.com/linkyndy/pallets)
|
4
4
|
|
5
|
-
|
5
|
+
Simple and reliable workflow engine, written in Ruby
|
6
6
|
|
7
7
|
## It is plain simple!
|
8
8
|
|
@@ -11,10 +11,10 @@ Toy workflow engine, written in Ruby
|
|
11
11
|
require 'pallets'
|
12
12
|
|
13
13
|
class MyWorkflow < Pallets::Workflow
|
14
|
-
task Foo
|
15
|
-
task Bar => Foo
|
16
|
-
task Baz => Foo
|
17
|
-
task Qux => [Bar, Baz]
|
14
|
+
task 'Foo'
|
15
|
+
task 'Bar' => 'Foo'
|
16
|
+
task 'Baz' => 'Foo'
|
17
|
+
task 'Qux' => ['Bar', 'Baz']
|
18
18
|
end
|
19
19
|
|
20
20
|
class Foo < Pallets::Task
|
@@ -120,7 +120,7 @@ end
|
|
120
120
|
|
121
121
|
## Motivation
|
122
122
|
|
123
|
-
The main reason for
|
123
|
+
The main reason for Pallets' existence was the need of a fast, simple and reliable workflow engine, one that is easily extensible with various backends and serializer, one that does not lose your data and one that is intelligent enough to concurrently schedule a workflow's tasks.
|
124
124
|
|
125
125
|
## Status
|
126
126
|
|
data/examples/config_savvy.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'logger'
|
2
1
|
require 'pallets'
|
3
2
|
|
4
3
|
class AnnounceProcessing
|
@@ -32,8 +31,6 @@ Pallets.configure do |c|
|
|
32
31
|
# given up. Retry times are exponential and happen after: 7, 22, 87, 262, ...
|
33
32
|
c.max_failures = 5
|
34
33
|
|
35
|
-
# Custom loggers can be used too
|
36
|
-
c.logger = Logger.new(STDOUT)
|
37
34
|
# Job execution can be wrapped with middleware to provide custom logic.
|
38
35
|
# Anything that responds to `call` would do
|
39
36
|
c.middleware << AnnounceProcessing
|
data/lib/pallets.rb
CHANGED
@@ -38,6 +38,7 @@ module Pallets
|
|
38
38
|
cls.new(
|
39
39
|
blocking_timeout: configuration.blocking_timeout,
|
40
40
|
failed_job_lifespan: configuration.failed_job_lifespan,
|
41
|
+
failed_job_max_count: configuration.failed_job_max_count,
|
41
42
|
job_timeout: configuration.job_timeout,
|
42
43
|
pool_size: configuration.pool_size,
|
43
44
|
**configuration.backend_args
|
@@ -57,6 +58,9 @@ module Pallets
|
|
57
58
|
end
|
58
59
|
|
59
60
|
def self.logger
|
60
|
-
@logger ||=
|
61
|
+
@logger ||= Pallets::Logger.new(STDOUT,
|
62
|
+
level: Pallets::Logger::INFO,
|
63
|
+
formatter: Pallets::Logger::Formatters::Pretty.new
|
64
|
+
)
|
61
65
|
end
|
62
66
|
end
|
@@ -20,8 +20,13 @@ module Pallets
|
|
20
20
|
raise NotImplementedError
|
21
21
|
end
|
22
22
|
|
23
|
+
# Discards malformed job
|
24
|
+
def discard(job)
|
25
|
+
raise NotImplementedError
|
26
|
+
end
|
27
|
+
|
23
28
|
# Gives up job after repeteadly failing to process it
|
24
|
-
def give_up(job, old_job)
|
29
|
+
def give_up(wfid, job, old_job)
|
25
30
|
raise NotImplementedError
|
26
31
|
end
|
27
32
|
|
@@ -9,13 +9,15 @@ module Pallets
|
|
9
9
|
RETRY_SET_KEY = 'retry-set'
|
10
10
|
GIVEN_UP_SET_KEY = 'given-up-set'
|
11
11
|
WORKFLOW_QUEUE_KEY = 'workflow-queue:%s'
|
12
|
+
JOBMASKS_KEY = 'jobmasks:%s'
|
12
13
|
JOBMASK_KEY = 'jobmask:%s'
|
13
14
|
CONTEXT_KEY = 'context:%s'
|
14
15
|
REMAINING_KEY = 'remaining:%s'
|
15
16
|
|
16
|
-
def initialize(blocking_timeout:, failed_job_lifespan:, job_timeout:, pool_size:, **options)
|
17
|
+
def initialize(blocking_timeout:, failed_job_lifespan:, failed_job_max_count:, job_timeout:, pool_size:, **options)
|
17
18
|
@blocking_timeout = blocking_timeout
|
18
19
|
@failed_job_lifespan = failed_job_lifespan
|
20
|
+
@failed_job_max_count = failed_job_max_count
|
19
21
|
@job_timeout = job_timeout
|
20
22
|
@pool = Pallets::Pool.new(pool_size) { ::Redis.new(options) }
|
21
23
|
|
@@ -46,7 +48,7 @@ module Pallets
|
|
46
48
|
@pool.execute do |client|
|
47
49
|
client.evalsha(
|
48
50
|
@scripts['save'],
|
49
|
-
[WORKFLOW_QUEUE_KEY % wfid, QUEUE_KEY, RELIABILITY_QUEUE_KEY, RELIABILITY_SET_KEY, CONTEXT_KEY % wfid, REMAINING_KEY % wfid, JOBMASK_KEY % jid],
|
51
|
+
[WORKFLOW_QUEUE_KEY % wfid, QUEUE_KEY, RELIABILITY_QUEUE_KEY, RELIABILITY_SET_KEY, CONTEXT_KEY % wfid, REMAINING_KEY % wfid, JOBMASK_KEY % jid, JOBMASKS_KEY % wfid],
|
50
52
|
context_buffer.to_a << job
|
51
53
|
)
|
52
54
|
end
|
@@ -62,12 +64,22 @@ module Pallets
|
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
65
|
-
def
|
67
|
+
def discard(job)
|
66
68
|
@pool.execute do |client|
|
67
69
|
client.evalsha(
|
68
|
-
@scripts['
|
70
|
+
@scripts['discard'],
|
69
71
|
[GIVEN_UP_SET_KEY, RELIABILITY_QUEUE_KEY, RELIABILITY_SET_KEY],
|
70
|
-
[Time.now.to_f, job,
|
72
|
+
[Time.now.to_f, job, Time.now.to_f - @failed_job_lifespan, @failed_job_max_count]
|
73
|
+
)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def give_up(wfid, job, old_job)
|
78
|
+
@pool.execute do |client|
|
79
|
+
client.evalsha(
|
80
|
+
@scripts['give_up'],
|
81
|
+
[GIVEN_UP_SET_KEY, RELIABILITY_QUEUE_KEY, RELIABILITY_SET_KEY, JOBMASKS_KEY % wfid, WORKFLOW_QUEUE_KEY % wfid, REMAINING_KEY % wfid, CONTEXT_KEY % wfid],
|
82
|
+
[Time.now.to_f, job, old_job, Time.now.to_f - @failed_job_lifespan, @failed_job_max_count]
|
71
83
|
)
|
72
84
|
end
|
73
85
|
end
|
@@ -86,6 +98,7 @@ module Pallets
|
|
86
98
|
@pool.execute do |client|
|
87
99
|
client.multi do
|
88
100
|
jobmasks.each { |jid, jobmask| client.zadd(JOBMASK_KEY % jid, jobmask) }
|
101
|
+
client.sadd(JOBMASKS_KEY % wfid, jobmasks.map { |jid, _| JOBMASK_KEY % jid }) unless jobmasks.empty?
|
89
102
|
client.evalsha(
|
90
103
|
@scripts['run_workflow'],
|
91
104
|
[WORKFLOW_QUEUE_KEY % wfid, QUEUE_KEY, REMAINING_KEY % wfid],
|
@@ -0,0 +1,11 @@
|
|
1
|
+
-- Remove job from reliability queue
|
2
|
+
redis.call("LREM", KEYS[2], 0, ARGV[2])
|
3
|
+
redis.call("ZREM", KEYS[3], ARGV[2])
|
4
|
+
|
5
|
+
-- Add job and its fail time (score) to failed sorted set
|
6
|
+
redis.call("ZADD", KEYS[1], ARGV[1], ARGV[2])
|
7
|
+
|
8
|
+
-- Remove any jobs that have been given up long enough ago (their score is
|
9
|
+
-- below given value) and make sure the number of jobs is capped
|
10
|
+
redis.call("ZREMRANGEBYSCORE", KEYS[1], "-inf", ARGV[3])
|
11
|
+
redis.call("ZREMRANGEBYRANK", KEYS[1], 0, -ARGV[4] - 1)
|
@@ -5,6 +5,11 @@ redis.call("ZREM", KEYS[3], ARGV[3])
|
|
5
5
|
-- Add job and its fail time (score) to failed sorted set
|
6
6
|
redis.call("ZADD", KEYS[1], ARGV[1], ARGV[2])
|
7
7
|
|
8
|
+
-- Remove all related workflow keys
|
9
|
+
local keys = redis.call("SMEMBERS", KEYS[4])
|
10
|
+
redis.call("DEL", KEYS[4], KEYS[5], KEYS[6], KEYS[7], unpack(keys))
|
11
|
+
|
8
12
|
-- Remove any jobs that have been given up long enough ago (their score is
|
9
|
-
-- below given value)
|
13
|
+
-- below given value) and make sure the number of jobs is capped
|
10
14
|
redis.call("ZREMRANGEBYSCORE", KEYS[1], "-inf", ARGV[4])
|
15
|
+
redis.call("ZREMRANGEBYRANK", KEYS[1], 0, -ARGV[5] - 1)
|
@@ -22,9 +22,9 @@ if #work > 0 then
|
|
22
22
|
redis.call("ZREM", KEYS[1], unpack(work))
|
23
23
|
end
|
24
24
|
|
25
|
-
-- Decrement ETA and remove it together with the context if all
|
26
|
-
-- been processed (ETA is 0)
|
25
|
+
-- Decrement ETA and remove it together with the context and jobmasks if all
|
26
|
+
-- tasks have been processed (ETA is 0) or if workflow has been given up (ETA is -1)
|
27
27
|
local remaining = redis.call("DECR", KEYS[6])
|
28
|
-
if remaining
|
29
|
-
redis.call("DEL", KEYS[5], KEYS[6])
|
28
|
+
if remaining <= 0 then
|
29
|
+
redis.call("DEL", KEYS[5], KEYS[6], KEYS[8])
|
30
30
|
end
|
data/lib/pallets/cli.rb
CHANGED
@@ -67,6 +67,10 @@ module Pallets
|
|
67
67
|
Pallets.configuration.failed_job_lifespan = failed_job_lifespan
|
68
68
|
end
|
69
69
|
|
70
|
+
opts.on('-m', '--failed-job-max-count NUM', Integer, 'Maximum number of jobs in the given up set') do |failed_job_max_count|
|
71
|
+
Pallets.configuration.failed_job_max_count = failed_job_max_count
|
72
|
+
end
|
73
|
+
|
70
74
|
opts.on('-p', '--pool-size NUM', Integer, 'Size of backend pool') do |pool_size|
|
71
75
|
Pallets.configuration.pool_size = pool_size
|
72
76
|
end
|
@@ -16,13 +16,14 @@ module Pallets
|
|
16
16
|
# this period, jobs will be permanently deleted
|
17
17
|
attr_accessor :failed_job_lifespan
|
18
18
|
|
19
|
+
# Maximum number of failed jobs that can be in the given up set. When this
|
20
|
+
# number is reached, the oldest jobs will be permanently deleted
|
21
|
+
attr_accessor :failed_job_max_count
|
22
|
+
|
19
23
|
# Number of seconds allowed for a job to be processed. If a job exceeds this
|
20
24
|
# period, it is considered failed, and scheduled to be processed again
|
21
25
|
attr_accessor :job_timeout
|
22
26
|
|
23
|
-
# Custom logger used throughout Pallets
|
24
|
-
attr_writer :logger
|
25
|
-
|
26
27
|
# Maximum number of failures allowed per job. Can also be configured on a
|
27
28
|
# per task basis
|
28
29
|
attr_accessor :max_failures
|
@@ -48,19 +49,13 @@ module Pallets
|
|
48
49
|
@blocking_timeout = 5
|
49
50
|
@concurrency = 2
|
50
51
|
@failed_job_lifespan = 7_776_000 # 3 months
|
52
|
+
@failed_job_max_count = 1_000
|
51
53
|
@job_timeout = 1_800 # 30 minutes
|
52
54
|
@max_failures = 3
|
53
55
|
@serializer = :json
|
54
56
|
@middleware = default_middleware
|
55
57
|
end
|
56
58
|
|
57
|
-
def logger
|
58
|
-
@logger || Pallets::Logger.new(STDOUT,
|
59
|
-
level: Pallets::Logger::INFO,
|
60
|
-
formatter: Pallets::Logger::Formatters::Pretty.new
|
61
|
-
)
|
62
|
-
end
|
63
|
-
|
64
59
|
def pool_size
|
65
60
|
@pool_size || @concurrency + 1
|
66
61
|
end
|
data/lib/pallets/logger.rb
CHANGED
@@ -5,14 +5,22 @@ module Pallets
|
|
5
5
|
class Logger < ::Logger
|
6
6
|
# Overwrite severity methods to add metadata capabilities
|
7
7
|
%i[debug info warn error fatal unknown].each do |severity|
|
8
|
-
define_method severity do |message
|
9
|
-
|
8
|
+
define_method severity do |message|
|
9
|
+
metadata = Thread.current[:pallets_log_metadata]
|
10
|
+
return super(message) if metadata.nil?
|
10
11
|
|
11
12
|
formatted_metadata = ' ' + metadata.map { |k, v| "#{k}=#{v}" }.join(' ')
|
12
13
|
super(formatted_metadata) { message }
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
17
|
+
def with_metadata(hash)
|
18
|
+
Thread.current[:pallets_log_metadata] = hash
|
19
|
+
yield
|
20
|
+
ensure
|
21
|
+
Thread.current[:pallets_log_metadata] = nil
|
22
|
+
end
|
23
|
+
|
16
24
|
module Formatters
|
17
25
|
class Pretty < ::Logger::Formatter
|
18
26
|
def call(severity, time, metadata, message)
|
@@ -2,14 +2,21 @@ module Pallets
|
|
2
2
|
module Middleware
|
3
3
|
class JobLogger
|
4
4
|
def self.call(worker, job, context)
|
5
|
-
|
6
|
-
|
7
|
-
Pallets.logger.
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
start_time = current_time
|
6
|
+
|
7
|
+
Pallets.logger.with_metadata(extract_metadata(worker.id, job)) do
|
8
|
+
begin
|
9
|
+
Pallets.logger.info 'Started'
|
10
|
+
result = yield
|
11
|
+
Pallets.logger.info "Done in #{(current_time - start_time).round(3)}s"
|
12
|
+
result
|
13
|
+
rescue => ex
|
14
|
+
Pallets.logger.warn "Failed after #{(current_time - start_time).round(3)}s"
|
15
|
+
Pallets.logger.warn "#{ex.class.name}: #{ex.message}"
|
16
|
+
Pallets.logger.warn ex.backtrace.join("\n") unless ex.backtrace.nil?
|
17
|
+
raise
|
18
|
+
end
|
19
|
+
end
|
13
20
|
end
|
14
21
|
|
15
22
|
def self.extract_metadata(wid, job)
|
@@ -21,6 +28,10 @@ module Pallets
|
|
21
28
|
tsk: job['task_class'],
|
22
29
|
}
|
23
30
|
end
|
31
|
+
|
32
|
+
def self.current_time
|
33
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
34
|
+
end
|
24
35
|
end
|
25
36
|
end
|
26
37
|
end
|
data/lib/pallets/version.rb
CHANGED
data/lib/pallets/worker.rb
CHANGED
@@ -53,8 +53,8 @@ module Pallets
|
|
53
53
|
rescue Pallets::Shutdown
|
54
54
|
@manager.remove_worker(self)
|
55
55
|
rescue => ex
|
56
|
-
Pallets.logger.error "#{ex.class.name}: #{ex.message}"
|
57
|
-
Pallets.logger.error ex.backtrace.join("\n")
|
56
|
+
Pallets.logger.error "#{ex.class.name}: #{ex.message}"
|
57
|
+
Pallets.logger.error ex.backtrace.join("\n") unless ex.backtrace.nil?
|
58
58
|
@manager.replace_worker(self)
|
59
59
|
end
|
60
60
|
|
@@ -64,8 +64,8 @@ module Pallets
|
|
64
64
|
rescue
|
65
65
|
# We ensure only valid jobs are created. If something fishy reaches this
|
66
66
|
# point, just give up on it
|
67
|
-
backend.
|
68
|
-
Pallets.logger.error "Could not deserialize #{job}. Gave up job"
|
67
|
+
backend.discard(job)
|
68
|
+
Pallets.logger.error "Could not deserialize #{job}. Gave up job"
|
69
69
|
return
|
70
70
|
end
|
71
71
|
|
@@ -103,7 +103,7 @@ module Pallets
|
|
103
103
|
retry_at = Time.now.to_f + backoff_in_seconds(failures)
|
104
104
|
backend.retry(new_job, job, retry_at)
|
105
105
|
else
|
106
|
-
backend.give_up(new_job, job)
|
106
|
+
backend.give_up(job_hash['wfid'], new_job, job)
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
@@ -112,7 +112,7 @@ module Pallets
|
|
112
112
|
'given_up_at' => Time.now.to_f,
|
113
113
|
'reason' => 'returned_false'
|
114
114
|
))
|
115
|
-
backend.give_up(new_job, job)
|
115
|
+
backend.give_up(job_hash['wfid'], new_job, job)
|
116
116
|
end
|
117
117
|
|
118
118
|
def handle_job_success(context, job, job_hash)
|
data/pallets.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ['Andrei Horak']
|
10
10
|
spec.email = ['linkyndy@gmail.com']
|
11
11
|
|
12
|
-
spec.summary = '
|
13
|
-
spec.description = '
|
12
|
+
spec.summary = 'Simple and reliable workflow engine, written in Ruby'
|
13
|
+
spec.description = 'Simple and reliable workflow engine, written in Ruby'
|
14
14
|
spec.homepage = 'https://github.com/linkyndy/pallets'
|
15
15
|
spec.license = 'MIT'
|
16
16
|
|
@@ -20,6 +20,6 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.required_ruby_version = '>= 2.4'
|
22
22
|
|
23
|
-
spec.add_dependency 'redis'
|
23
|
+
spec.add_dependency 'redis', '~> 4.2'
|
24
24
|
spec.add_dependency 'msgpack'
|
25
25
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pallets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrei Horak
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '4.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '4.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: msgpack
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,7 +38,7 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
-
description:
|
41
|
+
description: Simple and reliable workflow engine, written in Ruby
|
42
42
|
email:
|
43
43
|
- linkyndy@gmail.com
|
44
44
|
executables:
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- lib/pallets.rb
|
68
68
|
- lib/pallets/backends/base.rb
|
69
69
|
- lib/pallets/backends/redis.rb
|
70
|
+
- lib/pallets/backends/scripts/discard.lua
|
70
71
|
- lib/pallets/backends/scripts/give_up.lua
|
71
72
|
- lib/pallets/backends/scripts/reschedule_all.lua
|
72
73
|
- lib/pallets/backends/scripts/retry.lua
|
@@ -98,7 +99,7 @@ homepage: https://github.com/linkyndy/pallets
|
|
98
99
|
licenses:
|
99
100
|
- MIT
|
100
101
|
metadata: {}
|
101
|
-
post_install_message:
|
102
|
+
post_install_message:
|
102
103
|
rdoc_options: []
|
103
104
|
require_paths:
|
104
105
|
- lib
|
@@ -114,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
115
|
version: '0'
|
115
116
|
requirements: []
|
116
117
|
rubygems_version: 3.1.2
|
117
|
-
signing_key:
|
118
|
+
signing_key:
|
118
119
|
specification_version: 4
|
119
|
-
summary:
|
120
|
+
summary: Simple and reliable workflow engine, written in Ruby
|
120
121
|
test_files: []
|