simplekiq 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +125 -0
- data/.gitignore +10 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +16 -0
- data/CONTRIBUTING.md +31 -0
- data/CONTRIBUTORS.md +22 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +81 -0
- data/LICENSE.txt +13 -0
- data/README.md +131 -0
- data/Rakefile +9 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/simplekiq/batching_job.rb +163 -0
- data/lib/simplekiq/orchestration.rb +42 -0
- data/lib/simplekiq/orchestration_executor.rb +46 -0
- data/lib/simplekiq/orchestration_job.rb +28 -0
- data/lib/simplekiq/version.rb +3 -0
- data/lib/simplekiq.rb +14 -0
- data/simplekiq.gemspec +38 -0
- data/tasks/ci.rake +13 -0
- data/vendor/cache/ast-2.4.2.gem +0 -0
- data/vendor/cache/coderay-1.1.3.gem +0 -0
- data/vendor/cache/connection_pool-2.2.5.gem +0 -0
- data/vendor/cache/diff-lcs-1.5.0.gem +0 -0
- data/vendor/cache/method_source-1.0.0.gem +0 -0
- data/vendor/cache/parallel-1.22.1.gem +0 -0
- data/vendor/cache/parser-3.1.1.0.gem +0 -0
- data/vendor/cache/pry-0.13.1.gem +0 -0
- data/vendor/cache/rack-2.2.3.gem +0 -0
- data/vendor/cache/rack-protection-2.2.0.gem +0 -0
- data/vendor/cache/rainbow-3.1.1.gem +0 -0
- data/vendor/cache/rake-12.3.3.gem +0 -0
- data/vendor/cache/redis-4.5.1.gem +0 -0
- data/vendor/cache/regexp_parser-2.2.1.gem +0 -0
- data/vendor/cache/rexml-3.2.5.gem +0 -0
- data/vendor/cache/rspec-3.10.0.gem +0 -0
- data/vendor/cache/rspec-core-3.10.1.gem +0 -0
- data/vendor/cache/rspec-expectations-3.10.1.gem +0 -0
- data/vendor/cache/rspec-mocks-3.10.2.gem +0 -0
- data/vendor/cache/rspec-support-3.10.3.gem +0 -0
- data/vendor/cache/rspec_junit_formatter-0.5.1.gem +0 -0
- data/vendor/cache/rubocop-1.26.1.gem +0 -0
- data/vendor/cache/rubocop-ast-1.16.0.gem +0 -0
- data/vendor/cache/rubocop-performance-1.13.3.gem +0 -0
- data/vendor/cache/ruby-progressbar-1.11.0.gem +0 -0
- data/vendor/cache/sidekiq-5.2.10.gem +0 -0
- data/vendor/cache/standard-1.9.1.gem +0 -0
- data/vendor/cache/unicode-display_width-2.1.0.gem +0 -0
- metadata +180 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4caaf4c9bfc49507c627f025b8847b4cbfd36805897abc1c5d14117327cb0313
|
4
|
+
data.tar.gz: cdff30ac40b315e7e8dca636d013153631b710b8fb65c2bfffdf36632900b293
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 43789a7c661f3981035069935eecdefa4c03f8bfc2bd0eaeba8840018f54813f103475a5cd149752cbbef48e30f7c7363c98af548d85277995e0699df58b00dd
|
7
|
+
data.tar.gz: 9ab17b4b9d419d2551fd8cfe6070443015e35c1dc9c6adf195302a912aff52caf67fc7a5edea2c9f7733c43e0e799b790e00be07a4fbc4b6d0586501372be20d
|
@@ -0,0 +1,125 @@
|
|
1
|
+
version: 2.1
|
2
|
+
|
3
|
+
orbs:
|
4
|
+
gem: doximity/gem-publisher@0
|
5
|
+
|
6
|
+
executors:
|
7
|
+
ruby-2-6:
|
8
|
+
resource_class: small
|
9
|
+
docker:
|
10
|
+
- image: cimg/ruby:2.6
|
11
|
+
environment:
|
12
|
+
BUNDLE_VERSION: "~> 1.17"
|
13
|
+
|
14
|
+
# yaml anchor filters
|
15
|
+
master_only: &master_only
|
16
|
+
filters:
|
17
|
+
branches:
|
18
|
+
only: master
|
19
|
+
tags:
|
20
|
+
ignore: /.*/
|
21
|
+
pr_only: &pr_only
|
22
|
+
filters:
|
23
|
+
branches:
|
24
|
+
ignore: master
|
25
|
+
tags:
|
26
|
+
ignore: /.*/
|
27
|
+
version_tags_only: &version_tags_only
|
28
|
+
filters:
|
29
|
+
branches:
|
30
|
+
ignore: /.*/
|
31
|
+
tags:
|
32
|
+
only: /^v.*/
|
33
|
+
|
34
|
+
jobs:
|
35
|
+
build:
|
36
|
+
executor: ruby-2-6
|
37
|
+
steps:
|
38
|
+
- checkout
|
39
|
+
- run:
|
40
|
+
name: Install Bundler specific version
|
41
|
+
command: |
|
42
|
+
gem install bundler --version "${BUNDLE_VERSION}" --force
|
43
|
+
- restore_cache:
|
44
|
+
keys:
|
45
|
+
- v1-bundle-{{ checksum "Gemfile.lock" }}-
|
46
|
+
- run:
|
47
|
+
name: Install Ruby Dependencies
|
48
|
+
command: |
|
49
|
+
bundle config set --local path 'vendor/bundle'
|
50
|
+
bundle config set --local frozen 'true'
|
51
|
+
bundle install --local --jobs=4 --retry=3
|
52
|
+
- save_cache:
|
53
|
+
key: v1-bundle-{{ checksum "Gemfile.lock" }}-
|
54
|
+
paths:
|
55
|
+
- vendor/bundle
|
56
|
+
- run:
|
57
|
+
name: Run Tests
|
58
|
+
command: bundle exec rake ci:specs
|
59
|
+
- store_test_results:
|
60
|
+
name: Store test results
|
61
|
+
path: tmp/test-results
|
62
|
+
- run:
|
63
|
+
name: Run StandardRB
|
64
|
+
command: bundle exec standardrb
|
65
|
+
- persist_to_workspace:
|
66
|
+
root: .
|
67
|
+
paths:
|
68
|
+
- vendor/bundle
|
69
|
+
|
70
|
+
workflows:
|
71
|
+
version: 2
|
72
|
+
|
73
|
+
trunk:
|
74
|
+
jobs:
|
75
|
+
- build:
|
76
|
+
<<: *master_only
|
77
|
+
- gem/build:
|
78
|
+
<<: *master_only
|
79
|
+
executor: ruby-2-6
|
80
|
+
name: gem-build
|
81
|
+
requires:
|
82
|
+
- build
|
83
|
+
|
84
|
+
pull-requests:
|
85
|
+
jobs:
|
86
|
+
- build:
|
87
|
+
<<: *pr_only
|
88
|
+
- gem/build:
|
89
|
+
<<: *pr_only
|
90
|
+
executor: ruby-2-6
|
91
|
+
name: gem-build
|
92
|
+
requires:
|
93
|
+
- build
|
94
|
+
- pre-release-approval:
|
95
|
+
<<: *pr_only
|
96
|
+
type: approval
|
97
|
+
requires:
|
98
|
+
- gem-build
|
99
|
+
- gem/publish:
|
100
|
+
<<: *pr_only
|
101
|
+
name: gem-publish
|
102
|
+
to_rubygems: true
|
103
|
+
pre_release: true
|
104
|
+
requires:
|
105
|
+
- pre-release-approval
|
106
|
+
context: artifact_publishing
|
107
|
+
|
108
|
+
final-release:
|
109
|
+
jobs:
|
110
|
+
- build:
|
111
|
+
<<: *version_tags_only
|
112
|
+
- gem/build:
|
113
|
+
<<: *version_tags_only
|
114
|
+
executor: ruby-2-6
|
115
|
+
name: gem-build
|
116
|
+
requires:
|
117
|
+
- build
|
118
|
+
- gem/publish:
|
119
|
+
<<: *version_tags_only
|
120
|
+
name: gem-publish
|
121
|
+
to_rubygems: true
|
122
|
+
pre_release: false
|
123
|
+
requires:
|
124
|
+
- gem-build
|
125
|
+
context: artifact_publishing
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## [0.0.3]
|
8
|
+
* Misc minimal fixes to get the gem building and releasable
|
9
|
+
[#2](https://github.com/doximity/rake-ui/pull/3)
|
10
|
+
* Copy over library code from prior sources with maintained history
|
11
|
+
[#1](https://github.com/doximity/simplekiq/pull/1)
|
12
|
+
|
13
|
+
## [0.0.2]
|
14
|
+
* Scrubbed version from rubygems, do not use
|
15
|
+
## [0.0.1]
|
16
|
+
* Scrubbed version from rubygems, do not use
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
We welcome contributions to this repository. Feel free to submit issues for bugs you encounter and pull requests for code and documentation contributions.
|
4
|
+
|
5
|
+
In order to prevent licensing issues, we require all contributors to sign an individual contributor license agreement, which is reproduced below:
|
6
|
+
|
7
|
+
## Individual Contributor License Agreement
|
8
|
+
|
9
|
+
In order to clarify the intellectual property license granted with Contributions from any person or entity, Doximity Inc. ("Doximity") must have a Contributor License Agreement ("CLA") on file that has been signed by each Contributor, indicating agreement to the license terms below. This license is for your protection as a Contributor as well as the protection of Doximity; it does not change your rights to use your own Contributions for any other purpose.
|
10
|
+
|
11
|
+
You accept and agree to the following terms and conditions for Your present and future Contributions submitted to Doximity. Except for the license granted herein to Doximity and recipients of software distributed by Doximity, You reserve all right, title, and interest in and to Your Contributions.
|
12
|
+
|
13
|
+
### Definitions
|
14
|
+
|
15
|
+
"You" (or "Your") shall mean the copyright owner or legal entity authorized by the copyright owner that is making this Agreement with Doximity. For legal entities, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
16
|
+
|
17
|
+
1. "Contribution" shall mean any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to Doximity for inclusion in, or documentation of, any of the products owned or managed by Doximity (the "Work"). For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to Doximity or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, Doximity for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution."
|
18
|
+
|
19
|
+
2. Grant of Copyright License. Subject to the terms and conditions of this Agreement, You hereby grant to Doximity and to recipients of software distributed by Doximity a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such derivative works.
|
20
|
+
|
21
|
+
3. Grant of Patent License. Subject to the terms and conditions of this Agreement, You hereby grant to Doximity and to recipients of software distributed by Doximity a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) was submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that your Contribution, or the Work to which you have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed.
|
22
|
+
|
23
|
+
4. You represent that you are legally entitled to grant the above license. If your employer(s) has rights to intellectual property that you create that includes your Contributions, you represent that you have received permission to make Contributions on behalf of that employer, that your employer has waived such rights for your Contributions to Doximity, or that your employer has executed a separate Corporate CLA with Doximity.
|
24
|
+
|
25
|
+
5. You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of others). You represent that Your Contribution submissions include complete details of any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which you are personally aware and which are associated with any part of Your Contributions.
|
26
|
+
|
27
|
+
6. You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON- INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
|
28
|
+
|
29
|
+
7. Should You wish to submit work that is not Your original creation, You may submit it to Doximity separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: [[]named here]".
|
30
|
+
|
31
|
+
8. You agree to notify Doximity of any facts or circumstances of which you become aware that would make these representations inaccurate in any respect.
|
data/CONTRIBUTORS.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
## List of All Known Code Contributors to Simplekiq
|
2
|
+
|
3
|
+
### Jack Noble
|
4
|
+
* Collaborated on initial concept
|
5
|
+
* Wrote the majority of the code as of initial release
|
6
|
+
|
7
|
+
### John Wilkinson
|
8
|
+
* Collaborated on initial concept
|
9
|
+
* Conducted the gem extraction and release
|
10
|
+
|
11
|
+
### Brian Dillard
|
12
|
+
* Added additional comment documentation
|
13
|
+
* Added support for `on_complete` batch callback support in `Simplekiq::BatchingJob`
|
14
|
+
|
15
|
+
### Austin Madden
|
16
|
+
* Fixed bug with batch statuses in callbacks for empty batches
|
17
|
+
|
18
|
+
### Tiffany Troha
|
19
|
+
* Added support for specifying `sidekiq_options` for the child job in `Simplekiq::BatchingJob`
|
20
|
+
|
21
|
+
### [Daniel Pepper](https://github.com/dpep)
|
22
|
+
* On request, graciously took down his unused `simplekiq` placeholder from rubygems so we could continue using the name :raised_hands:
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
simplekiq (0.0.3)
|
5
|
+
sidekiq (~> 5.2.9)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ast (2.4.2)
|
11
|
+
coderay (1.1.3)
|
12
|
+
connection_pool (2.2.5)
|
13
|
+
diff-lcs (1.5.0)
|
14
|
+
method_source (1.0.0)
|
15
|
+
parallel (1.22.1)
|
16
|
+
parser (3.1.1.0)
|
17
|
+
ast (~> 2.4.1)
|
18
|
+
pry (0.13.1)
|
19
|
+
coderay (~> 1.1)
|
20
|
+
method_source (~> 1.0)
|
21
|
+
rack (2.2.3)
|
22
|
+
rack-protection (2.2.0)
|
23
|
+
rack
|
24
|
+
rainbow (3.1.1)
|
25
|
+
rake (12.3.3)
|
26
|
+
redis (4.5.1)
|
27
|
+
regexp_parser (2.2.1)
|
28
|
+
rexml (3.2.5)
|
29
|
+
rspec (3.10.0)
|
30
|
+
rspec-core (~> 3.10.0)
|
31
|
+
rspec-expectations (~> 3.10.0)
|
32
|
+
rspec-mocks (~> 3.10.0)
|
33
|
+
rspec-core (3.10.1)
|
34
|
+
rspec-support (~> 3.10.0)
|
35
|
+
rspec-expectations (3.10.1)
|
36
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
37
|
+
rspec-support (~> 3.10.0)
|
38
|
+
rspec-mocks (3.10.2)
|
39
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
40
|
+
rspec-support (~> 3.10.0)
|
41
|
+
rspec-support (3.10.3)
|
42
|
+
rspec_junit_formatter (0.5.1)
|
43
|
+
rspec-core (>= 2, < 4, != 2.12.0)
|
44
|
+
rubocop (1.26.1)
|
45
|
+
parallel (~> 1.10)
|
46
|
+
parser (>= 3.1.0.0)
|
47
|
+
rainbow (>= 2.2.2, < 4.0)
|
48
|
+
regexp_parser (>= 1.8, < 3.0)
|
49
|
+
rexml
|
50
|
+
rubocop-ast (>= 1.16.0, < 2.0)
|
51
|
+
ruby-progressbar (~> 1.7)
|
52
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
53
|
+
rubocop-ast (1.16.0)
|
54
|
+
parser (>= 3.1.1.0)
|
55
|
+
rubocop-performance (1.13.3)
|
56
|
+
rubocop (>= 1.7.0, < 2.0)
|
57
|
+
rubocop-ast (>= 0.4.0)
|
58
|
+
ruby-progressbar (1.11.0)
|
59
|
+
sidekiq (5.2.10)
|
60
|
+
connection_pool (~> 2.2, >= 2.2.2)
|
61
|
+
rack (~> 2.0)
|
62
|
+
rack-protection (>= 1.5.0)
|
63
|
+
redis (~> 4.5, < 4.6.0)
|
64
|
+
standard (1.9.1)
|
65
|
+
rubocop (= 1.26.1)
|
66
|
+
rubocop-performance (= 1.13.3)
|
67
|
+
unicode-display_width (2.1.0)
|
68
|
+
|
69
|
+
PLATFORMS
|
70
|
+
ruby
|
71
|
+
|
72
|
+
DEPENDENCIES
|
73
|
+
pry
|
74
|
+
rake (~> 12.0)
|
75
|
+
rspec (~> 3.2)
|
76
|
+
rspec_junit_formatter
|
77
|
+
simplekiq!
|
78
|
+
standard
|
79
|
+
|
80
|
+
BUNDLED WITH
|
81
|
+
2.1.4
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2022 Doximity, Inc.
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
# Simplekiq
|
2
|
+
|
3
|
+
Any time that you find yourself needing to string together a long chain of jobs, particularly when there are multiple stages of Sidekiq-pro batches and callbacks involved, come home instead to the simple flavor of orchestrated job flow with Simplekiq.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem "simplekiq"
|
11
|
+
```
|
12
|
+
|
13
|
+
Note that this gem requires you be a Sidekiq Pro paid subscriber to be able to use it, so after following the installation docs for getting the private gem configured with your system, ensure you have `sidekiq-pro` at version `~> 5.0.0` or higher and that it's being required:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem "sidekiq-pro", "~> 5.0.0"
|
17
|
+
```
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle install
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install simplekiq
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
There are currently two primary components of the system which were designed to work in harmony:
|
30
|
+
|
31
|
+
* [Simplekiq::OrchestrationJob](./lib/simplekiq/orchestration_job.rb) - A mixin for a Sidekiq jobs to be able to orchestrate a flow of jobs in one place. It makes long complicated flows between jobs easier to understand, iterate on, and test. It eliminates the need to hop between dozens of files to determine when, where, and why a particular job gets called.
|
32
|
+
* [Simplekiq::BatchingJob](./lib/simplekiq/batching_job.rb) - A mixin designed to make breaking a large job into a batched process dead simple and contained within a single class while still being trivially composable in orchestrations.
|
33
|
+
|
34
|
+
## Tool Drilldown
|
35
|
+
|
36
|
+
### Simplekiq::OrchestrationJob
|
37
|
+
|
38
|
+
Mixing in the [Simplekiq::Orchestration](./lib/simplekiq/orchestration_job.rb) module lets you define a human-readable workflow of jobs in a single file with almost* no special requirements or restrictions on how the child jobs are designed. In most cases, Sidekiq jobs not designed for use in orchestrations should be compatible for use in orchestrations. A job implementing `OrchestrationJob` might look like:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
class SomeOrchestrationJob < BaseJob
|
42
|
+
include Sidekiq::Worker
|
43
|
+
include Simplekiq::OrchestrationJob
|
44
|
+
|
45
|
+
def perform_orchestration(some_id)
|
46
|
+
@some_model = SomeModel.find(some_id) # 1.
|
47
|
+
|
48
|
+
run SomeInitialSetupJob, some_model.id # 2.
|
49
|
+
|
50
|
+
in_parallel do
|
51
|
+
some_related_models.each do |related_model|
|
52
|
+
run SomeParallelizableJob, related_model.id # 3.
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
run SomeFinalizationJob, some_model.id # 4.
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
attr_reader :some_model
|
62
|
+
|
63
|
+
def some_related_models
|
64
|
+
@some_related_models ||= some_model.some_relation
|
65
|
+
end
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
Let's use the above example to describe some specifics of how the flow works.
|
70
|
+
|
71
|
+
1. `SomeOrchestrationJob` pulls up some instance of parent model `SomeModel`.
|
72
|
+
2. It does some initial work in `SomeInitialSetupJob`, which blocks the rest of the workflow until it completes successfully.
|
73
|
+
3. Then it will run a `SomeParallelizableJob` for each of some number of associated models `some_related_models`. These jobs will all run parallel to each other independently.
|
74
|
+
4. Finally, after all of the parallel jobs from #3 complete successfully, `SomeFinalizationJob` will run and then after it finishes the orchestration will be complete.
|
75
|
+
|
76
|
+
**Note** - it's fine to add utility methods and `attr_accessor`s to keep the code tidy and maintainable.
|
77
|
+
|
78
|
+
When `SomeOrchestrationJob` itself gets called though, the first thing it does it turn these directives into a big serialized structure indicating which job will be called under what conditions (eg, serial or in parallel) and with what arguments, and then keeps passing that between the simplekiq-internal jobs that actually conduct the flow.
|
79
|
+
|
80
|
+
This means when you want to deploy a change to this flow all previous in-flight workflows will continue undisturbed because the workflow is frozen in sidekiq job arguments and will remain frozen until the workflow completes. This is generally a boon, but note that if you remove a job from a workflow you'll need to remember to either keep the job itself (eg, the `SomeFinalizationJob` class file from our above example) in the codebase or replace it with a stub so that any in-flight workflows won't crash due to not being able to pull up the prior-specified workflow.
|
81
|
+
|
82
|
+
"almost* no special requirements or restrictions on how the child jobs are designed" - The one thing you'll want to keep in mind when feeding arbitrary jobs into orchestrations is that if the job creates any new sidekiq batches then those new sidekiq batches should be added as child sidekiq batches of the parent sidekiq batch of the job. The parent sidekiq batch of the job is the sidekiq batch that drives the orchestration from step to step, so if you don't do this it will move onto the next step in the orchestration once your job finishes even if the new sidekiq batches it started didn't finish. This sounds more complicated than it is, you can see an example of code that does this in [`BatchingJob#perform`](./lib/simplekiq/batching_job.rb):
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
if batch # is there a parent batch?
|
86
|
+
batch.jobs do # open the parent batch back up
|
87
|
+
create_a_new_batch_and_add_jobs_to_it_to_run # make our new batch as a child batch of the parent batch
|
88
|
+
end # close the parent batch again
|
89
|
+
else # there's no parent batches, this job was run directly outside of an orchestration
|
90
|
+
create_a_new_batch_and_add_jobs_to_it_to_run # make our new batch without a parent batch
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
### Simplekiq::BatchingJob
|
95
|
+
|
96
|
+
See the [Simplekiq::BatchingJob](./lib/simplekiq/batching_job.rb) module itself for a description and example usage in the header comments. Nutshell is that you should use this if you're planning on making a batched asynchronous process as it shaves off a lot of ceremony and unexpressive structure. eg - Instead of having `BeerBottlerJob` which queues some number of `BeerBottlerBatchJob`s to handle the broken down sub-tasks you can just have `BeerBottlerJob` with a method for batching, executing individual batches, and a callback that gets run after all batches have completed successfully.
|
97
|
+
|
98
|
+
## History
|
99
|
+
|
100
|
+
Simplekiq was initially released for private use within Doximity applications in Oct 2020 where it continued to be iterated on towards stability and general use until Jan 2022 when it was deemed settled enough for public release.
|
101
|
+
|
102
|
+
The primary driving factor that inspired this work was a series of over a dozen differently defined and structured jobs part of a single workflow of which the logical flow was extraordinarily difficult to cognitively trace. This led to exteme difficulty in debugging and following problematic instances of the workflow in production as well as needlessly high cost to refactoring and iterative adjustments.
|
103
|
+
|
104
|
+
The crux of the problem was that each job was highly coupled to its position in the overall flow as well as the absence of any central mechanism to indicate what the overall flow was. After building Simplekiq and implementing it into the flow, significant changes to the flow became quick adjustments requiring only a couple lines of code to change and folks unfamiliar with the system could quickly get up to speed by reading through the orchestration job.
|
105
|
+
|
106
|
+
## Versioning
|
107
|
+
|
108
|
+
This project follows semantic versioning. At time of writing it is sitting at 0.0.1 until its integration with the application it was extracted from is confirmed to be stable. Once confirmed it will be started off at 1.0.0 as it has otherwise been used in a production system already for some time.
|
109
|
+
|
110
|
+
## Development
|
111
|
+
|
112
|
+
After checking out the repo, run `bin/setup` to install dependencies. Note that this depends on `sidekiq-pro` which requires a [commercial license](https://sidekiq.org/products/pro.html) to install and use.
|
113
|
+
|
114
|
+
Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
115
|
+
|
116
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
117
|
+
|
118
|
+
TODO: Update this section with more specific/appropriate instructions once this is a public repository.
|
119
|
+
|
120
|
+
## Contributing
|
121
|
+
|
122
|
+
1. Fork it
|
123
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
124
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
125
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
126
|
+
5. Create a new Pull Request
|
127
|
+
6. Sign the CLA if you haven't yet. See CONTRIBUTING.md
|
128
|
+
|
129
|
+
## License
|
130
|
+
|
131
|
+
The gem is licensed under an Apache 2 license. Contributors are required to sign an contributor license agreement. See LICENSE.txt and CONTRIBUTING.md for more information.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "simplekiq"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This module enables you to break up your work into batches and run those
|
4
|
+
# batches as background jobs while keeping all your code in the same file.
|
5
|
+
# Including this module *implements perform* you should not override it.
|
6
|
+
# It expects you to implement two methods: #perform_batching and
|
7
|
+
# #perform_batch.
|
8
|
+
#
|
9
|
+
# Optionally you may also implement any combination of Sidekiq::Batch
|
10
|
+
# callbacks.
|
11
|
+
# - #on_complete
|
12
|
+
# - #on_success
|
13
|
+
# - #on_death
|
14
|
+
#
|
15
|
+
# #perform_batching should contain your code for breaking up your work into
|
16
|
+
# smaller jobs. It handles all the Sidekiq::Batch boilerplate for you. Where
|
17
|
+
# you would normally call ExampleBatchJob.perform_async you should use
|
18
|
+
# #queue_batch. If you'd like to custommize the sidekiq batch object, you can
|
19
|
+
# access it in perform_batching through the `sidekiq_batch` method.
|
20
|
+
#
|
21
|
+
# #perform_batch should contain the code that would be in your batch job. Under
|
22
|
+
# the hood, #queue_batch queues a job which will run #perform_batch.
|
23
|
+
#
|
24
|
+
# [Sidekiq::Batch documentation](https://github.com/mperham/sidekiq/wiki/Batches)
|
25
|
+
# explains batches, their lifecycle, callbacks, etc.
|
26
|
+
#
|
27
|
+
# class ExampleJob
|
28
|
+
# include Simplekiq::BatchingJob
|
29
|
+
#
|
30
|
+
# def perform_batching(some_id)
|
31
|
+
# sidekiq_batch.description = "My custom batch description" # optional
|
32
|
+
#
|
33
|
+
# Record.find(some_id).other_records.in_batches do |other_records|
|
34
|
+
# queue_batch(other_records.ids)
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# def perform_batch(other_record_ids)
|
39
|
+
# OtherRecord.where(id: other_record_ids).do_work
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# def on_death(_status, options)
|
43
|
+
# same_id_as_before = options["args"].first
|
44
|
+
# Record.find(same_id_as_before).death!
|
45
|
+
# end
|
46
|
+
|
47
|
+
# def on_complete(_status, options)
|
48
|
+
# same_id_as_before = options["args"].first
|
49
|
+
# Record.find(same_id_as_before).complete!
|
50
|
+
# end
|
51
|
+
|
52
|
+
# def on_success(_status, options)
|
53
|
+
# same_id_as_before = options["args"].first
|
54
|
+
# Record.find(same_id_as_before).success!
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# ExampleJob.perform_async(some_id)
|
59
|
+
#
|
60
|
+
# Come home to the impossible flavor of batch creation
|
61
|
+
|
62
|
+
module Simplekiq
|
63
|
+
module BatchingJob
|
64
|
+
include Sidekiq::Worker
|
65
|
+
|
66
|
+
BATCH_CLASS_NAME = "SimplekiqBatch"
|
67
|
+
|
68
|
+
class << self
|
69
|
+
def included(klass)
|
70
|
+
batch_job_class = Class.new(BaseBatch)
|
71
|
+
klass.const_set(BATCH_CLASS_NAME, batch_job_class)
|
72
|
+
|
73
|
+
klass.extend ClassMethods
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
module ClassMethods
|
78
|
+
def batch_sidekiq_options(options)
|
79
|
+
batch_class = const_get(BATCH_CLASS_NAME)
|
80
|
+
batch_class.instance_eval do
|
81
|
+
sidekiq_options(options)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def perform(*args)
|
87
|
+
self.batches = []
|
88
|
+
|
89
|
+
perform_batching(*args)
|
90
|
+
|
91
|
+
# If we're part of an existing sidekiq batch make this a child batch
|
92
|
+
# This is necessary for it work with orchestration; we could add an option
|
93
|
+
# to toggle the behavior on and off.
|
94
|
+
if batch
|
95
|
+
batch.jobs do
|
96
|
+
handle_batches(args)
|
97
|
+
end
|
98
|
+
else
|
99
|
+
handle_batches(args)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
protected # TODO: should this be private?
|
104
|
+
|
105
|
+
attr_accessor :batches
|
106
|
+
|
107
|
+
def handle_batches(args)
|
108
|
+
if !batches.empty?
|
109
|
+
flush_batches(args)
|
110
|
+
else
|
111
|
+
# Empty batches with no jobs will never invoke callbacks, so handle
|
112
|
+
# that case by immediately manually invoking :complete & :success.
|
113
|
+
on_complete(nil, {"args" => args}) if respond_to?(:on_complete)
|
114
|
+
on_success(nil, {"args" => args}) if respond_to?(:on_success)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def flush_batches(args)
|
119
|
+
batch_job_class = self.class.const_get(BATCH_CLASS_NAME)
|
120
|
+
sidekiq_batch.description ||= "Simplekiq Batch Jobs for #{self.class.name}, args: #{args}"
|
121
|
+
|
122
|
+
sidekiq_batch.on("death", self.class, "args" => args) if respond_to?(:on_death)
|
123
|
+
sidekiq_batch.on("complete", self.class, "args" => args) if respond_to?(:on_complete)
|
124
|
+
sidekiq_batch.on("success", self.class, "args" => args) if respond_to?(:on_success)
|
125
|
+
|
126
|
+
sidekiq_batch.jobs do
|
127
|
+
batches.each do |job_args|
|
128
|
+
batch_job_class.perform_async(*job_args)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def queue_batch(*args)
|
134
|
+
batches << args
|
135
|
+
end
|
136
|
+
|
137
|
+
def batch_description=(description)
|
138
|
+
sidekiq_batch.description = description
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def sidekiq_batch
|
144
|
+
@sidekiq_batch ||= Sidekiq::Batch.new
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class BaseBatch
|
149
|
+
include Sidekiq::Worker
|
150
|
+
|
151
|
+
def perform(*args)
|
152
|
+
module_parent_of_class.new.perform_batch(*args)
|
153
|
+
end
|
154
|
+
|
155
|
+
private
|
156
|
+
|
157
|
+
def module_parent_of_class
|
158
|
+
# Borrowed from https://apidock.com/rails/Module/module_parent_name
|
159
|
+
parent_name = self.class.name =~ /::[^:]+\Z/ ? $`.freeze : nil
|
160
|
+
parent_name ? Object.const_get(parent_name) : Object
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Simplekiq
|
4
|
+
class Orchestration
|
5
|
+
attr_accessor :serial_workflow, :parallel_workflow
|
6
|
+
def initialize
|
7
|
+
@serial_workflow = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def run(*step)
|
11
|
+
workflow = parallel_workflow || serial_workflow
|
12
|
+
workflow << step
|
13
|
+
end
|
14
|
+
|
15
|
+
def in_parallel
|
16
|
+
@parallel_workflow = []
|
17
|
+
yield
|
18
|
+
serial_workflow << @parallel_workflow if @parallel_workflow.any?
|
19
|
+
ensure
|
20
|
+
@parallel_workflow = nil
|
21
|
+
serial_workflow
|
22
|
+
end
|
23
|
+
|
24
|
+
def execute(parent_batch)
|
25
|
+
OrchestrationExecutor.execute(workflow: serialized_workflow, parent_batch: parent_batch)
|
26
|
+
end
|
27
|
+
|
28
|
+
def serialized_workflow
|
29
|
+
@serialized_workflow ||= serial_workflow.map do |step|
|
30
|
+
case step[0]
|
31
|
+
when Array
|
32
|
+
step.map do |(job, *args)|
|
33
|
+
{"klass" => job.name, "args" => args}
|
34
|
+
end
|
35
|
+
when Class
|
36
|
+
job, *args = step
|
37
|
+
{"klass" => job.name, "args" => args}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Simplekiq
|
4
|
+
class OrchestrationExecutor
|
5
|
+
def self.execute(workflow:, parent_batch:)
|
6
|
+
new.run_step(parent_batch, workflow, 0)
|
7
|
+
end
|
8
|
+
|
9
|
+
def run_step(parent_batch, workflow, step)
|
10
|
+
return if workflow.empty?
|
11
|
+
|
12
|
+
nest_under(parent_batch) do
|
13
|
+
*jobs = workflow.at(step)
|
14
|
+
sidekiq_batch = Sidekiq::Batch.new
|
15
|
+
sidekiq_batch.on(
|
16
|
+
:success,
|
17
|
+
self.class,
|
18
|
+
"orchestration_workflow" => workflow, "step" => step + 1
|
19
|
+
)
|
20
|
+
|
21
|
+
sidekiq_batch.jobs do
|
22
|
+
jobs.each do |job|
|
23
|
+
Object.const_get(job["klass"]).perform_async(*job["args"])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def nest_under(parent_batch)
|
30
|
+
if parent_batch
|
31
|
+
parent_batch.jobs do
|
32
|
+
yield
|
33
|
+
end
|
34
|
+
else
|
35
|
+
yield
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def on_success(status, options)
|
40
|
+
return if options["step"] == options["orchestration_workflow"].length
|
41
|
+
|
42
|
+
parent_batch = Sidekiq::Batch.new(status.parent_bid)
|
43
|
+
run_step(parent_batch, options["orchestration_workflow"], options["step"])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "forwardable"
|
4
|
+
|
5
|
+
module Simplekiq
|
6
|
+
module OrchestrationJob
|
7
|
+
include Sidekiq::Worker
|
8
|
+
|
9
|
+
extend Forwardable
|
10
|
+
def_delegators :orchestration, :run, :in_parallel
|
11
|
+
|
12
|
+
def perform(*args)
|
13
|
+
perform_orchestration(*args)
|
14
|
+
orchestration.execute(batch)
|
15
|
+
end
|
16
|
+
|
17
|
+
def workflow_plan(*args)
|
18
|
+
perform_orchestration(*args)
|
19
|
+
orchestration.serialized_workflow
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def orchestration
|
25
|
+
@orchestration ||= Orchestration.new
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/simplekiq.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sidekiq"
|
4
|
+
|
5
|
+
# NB: You must explicitly require sidekiq-ent in your app!
|
6
|
+
# require "sidekiq-ent"
|
7
|
+
|
8
|
+
require "simplekiq/orchestration_executor"
|
9
|
+
require "simplekiq/orchestration"
|
10
|
+
require "simplekiq/orchestration_job"
|
11
|
+
require "simplekiq/batching_job"
|
12
|
+
|
13
|
+
module Simplekiq
|
14
|
+
end
|
data/simplekiq.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative "lib/simplekiq/version"
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "simplekiq"
|
5
|
+
spec.version = Simplekiq::VERSION
|
6
|
+
spec.authors = ["Jack Noble", "John Wilkinson"]
|
7
|
+
spec.email = ["jcwilkinson@doximity.com"]
|
8
|
+
spec.summary = "Sidekiq-based workflow orchestration library"
|
9
|
+
spec.description = "Provides tools for representing long chains of parallel and serial jobs in a flat, simple way."
|
10
|
+
spec.homepage = "https://github.com/doximity/simplekiq"
|
11
|
+
spec.license = "APACHE-2.0"
|
12
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
|
13
|
+
|
14
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
15
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
16
|
+
# TODO: spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
17
|
+
|
18
|
+
# Specify which files should be added to the gem when it is released.
|
19
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
20
|
+
spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
|
21
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
22
|
+
end
|
23
|
+
spec.executables = []
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.2"
|
27
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
28
|
+
spec.add_development_dependency "rspec_junit_formatter"
|
29
|
+
spec.add_development_dependency "pry"
|
30
|
+
spec.add_development_dependency "standard"
|
31
|
+
|
32
|
+
spec.add_dependency "sidekiq", "~> 5.2.9"
|
33
|
+
|
34
|
+
# Can't define this explicitly because it would be inappropriate to vendor this
|
35
|
+
# pay-to-use library into the gem and it is not available on rubygems and
|
36
|
+
# this otherwise interferes with our publishing process.
|
37
|
+
# spec.add_dependency "sidekiq-pro", "~> 5.0.0"
|
38
|
+
end
|
data/tasks/ci.rake
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :ci do
|
4
|
+
desc "Run specs"
|
5
|
+
task :specs do
|
6
|
+
reports = "tmp/test-results/rspec"
|
7
|
+
sh "mkdir -p #{reports}"
|
8
|
+
sh "bundle exec rspec ./spec " \
|
9
|
+
"--format progress "\
|
10
|
+
"--format RspecJunitFormatter " \
|
11
|
+
"-o #{reports}/results.xml"
|
12
|
+
end
|
13
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simplekiq
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jack Noble
|
8
|
+
- John Wilkinson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2022-04-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '3.2'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '3.2'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '12.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '12.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec_junit_formatter
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: pry
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: standard
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: sidekiq
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 5.2.9
|
91
|
+
type: :runtime
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 5.2.9
|
98
|
+
description: Provides tools for representing long chains of parallel and serial jobs
|
99
|
+
in a flat, simple way.
|
100
|
+
email:
|
101
|
+
- jcwilkinson@doximity.com
|
102
|
+
executables: []
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files: []
|
105
|
+
files:
|
106
|
+
- ".circleci/config.yml"
|
107
|
+
- ".gitignore"
|
108
|
+
- ".rspec"
|
109
|
+
- CHANGELOG.md
|
110
|
+
- CONTRIBUTING.md
|
111
|
+
- CONTRIBUTORS.md
|
112
|
+
- Gemfile
|
113
|
+
- Gemfile.lock
|
114
|
+
- LICENSE.txt
|
115
|
+
- README.md
|
116
|
+
- Rakefile
|
117
|
+
- bin/console
|
118
|
+
- bin/setup
|
119
|
+
- lib/simplekiq.rb
|
120
|
+
- lib/simplekiq/batching_job.rb
|
121
|
+
- lib/simplekiq/orchestration.rb
|
122
|
+
- lib/simplekiq/orchestration_executor.rb
|
123
|
+
- lib/simplekiq/orchestration_job.rb
|
124
|
+
- lib/simplekiq/version.rb
|
125
|
+
- simplekiq.gemspec
|
126
|
+
- tasks/ci.rake
|
127
|
+
- vendor/cache/ast-2.4.2.gem
|
128
|
+
- vendor/cache/coderay-1.1.3.gem
|
129
|
+
- vendor/cache/connection_pool-2.2.5.gem
|
130
|
+
- vendor/cache/diff-lcs-1.5.0.gem
|
131
|
+
- vendor/cache/method_source-1.0.0.gem
|
132
|
+
- vendor/cache/parallel-1.22.1.gem
|
133
|
+
- vendor/cache/parser-3.1.1.0.gem
|
134
|
+
- vendor/cache/pry-0.13.1.gem
|
135
|
+
- vendor/cache/rack-2.2.3.gem
|
136
|
+
- vendor/cache/rack-protection-2.2.0.gem
|
137
|
+
- vendor/cache/rainbow-3.1.1.gem
|
138
|
+
- vendor/cache/rake-12.3.3.gem
|
139
|
+
- vendor/cache/redis-4.5.1.gem
|
140
|
+
- vendor/cache/regexp_parser-2.2.1.gem
|
141
|
+
- vendor/cache/rexml-3.2.5.gem
|
142
|
+
- vendor/cache/rspec-3.10.0.gem
|
143
|
+
- vendor/cache/rspec-core-3.10.1.gem
|
144
|
+
- vendor/cache/rspec-expectations-3.10.1.gem
|
145
|
+
- vendor/cache/rspec-mocks-3.10.2.gem
|
146
|
+
- vendor/cache/rspec-support-3.10.3.gem
|
147
|
+
- vendor/cache/rspec_junit_formatter-0.5.1.gem
|
148
|
+
- vendor/cache/rubocop-1.26.1.gem
|
149
|
+
- vendor/cache/rubocop-ast-1.16.0.gem
|
150
|
+
- vendor/cache/rubocop-performance-1.13.3.gem
|
151
|
+
- vendor/cache/ruby-progressbar-1.11.0.gem
|
152
|
+
- vendor/cache/sidekiq-5.2.10.gem
|
153
|
+
- vendor/cache/standard-1.9.1.gem
|
154
|
+
- vendor/cache/unicode-display_width-2.1.0.gem
|
155
|
+
homepage: https://github.com/doximity/simplekiq
|
156
|
+
licenses:
|
157
|
+
- APACHE-2.0
|
158
|
+
metadata:
|
159
|
+
homepage_uri: https://github.com/doximity/simplekiq
|
160
|
+
source_code_uri: https://github.com/doximity/simplekiq
|
161
|
+
post_install_message:
|
162
|
+
rdoc_options: []
|
163
|
+
require_paths:
|
164
|
+
- lib
|
165
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: 2.5.0
|
170
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '0'
|
175
|
+
requirements: []
|
176
|
+
rubygems_version: 3.3.11
|
177
|
+
signing_key:
|
178
|
+
specification_version: 4
|
179
|
+
summary: Sidekiq-based workflow orchestration library
|
180
|
+
test_files: []
|