shifty 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/codeql-analysis.yml +74 -0
- data/.github/workflows/ruby.yml +36 -0
- data/.gitignore +3 -0
- data/.standard.yml +3 -0
- data/Gemfile +5 -2
- data/Guardfile +42 -0
- data/README.md +3 -3
- data/Rakefile +4 -3
- data/_config.yml +1 -0
- data/lib/shifty/dsl.rb +25 -30
- data/lib/shifty/gang.rb +27 -21
- data/lib/shifty/roster.rb +14 -17
- data/lib/shifty/taggable.rb +21 -0
- data/lib/shifty/version.rb +1 -1
- data/lib/shifty/worker.rb +27 -24
- data/lib/shifty.rb +5 -5
- data/shifty.gemspec +19 -19
- metadata +34 -29
- data/.travis.yml +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60586c4caa01e362be844ef009bc5b90419524de80de66a18286bbc71de40b8e
|
4
|
+
data.tar.gz: fc3d174365d07ed8d202630db19ab316749f42a24947ab549bc503e460fd5478
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c8d7e4c9acec961c018ead8f69b422d25fae27ae69f78fe482eff067153d5c7937a5932e98ac9f941d753c281c221c0ef8e75ca68e70b44904e586909a34cf3
|
7
|
+
data.tar.gz: a8f3a744fd32368969a609fb64326fc0c60c73efa4e45eb9adaea773efcbb103049ef6dd04dda6fd36bdf1a2c2d2f80e1af4354adacb66ebdfa33a9347e9cd0b
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# For most projects, this workflow file will not need changing; you simply need
|
2
|
+
# to commit it to your repository.
|
3
|
+
#
|
4
|
+
# You may wish to alter this file to override the set of languages analyzed,
|
5
|
+
# or to provide custom queries or build logic.
|
6
|
+
#
|
7
|
+
# ******** NOTE ********
|
8
|
+
# We have attempted to detect the languages in your repository. Please check
|
9
|
+
# the `language` matrix defined below to confirm you have the correct set of
|
10
|
+
# supported CodeQL languages.
|
11
|
+
#
|
12
|
+
name: "CodeQL"
|
13
|
+
|
14
|
+
on:
|
15
|
+
push:
|
16
|
+
branches: [ "main" ]
|
17
|
+
pull_request:
|
18
|
+
# The branches below must be a subset of the branches above
|
19
|
+
branches: [ "main" ]
|
20
|
+
schedule:
|
21
|
+
- cron: '29 13 * * 5'
|
22
|
+
|
23
|
+
jobs:
|
24
|
+
analyze:
|
25
|
+
name: Analyze
|
26
|
+
runs-on: ubuntu-latest
|
27
|
+
permissions:
|
28
|
+
actions: read
|
29
|
+
contents: read
|
30
|
+
security-events: write
|
31
|
+
|
32
|
+
strategy:
|
33
|
+
fail-fast: false
|
34
|
+
matrix:
|
35
|
+
language: [ 'ruby' ]
|
36
|
+
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
37
|
+
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
38
|
+
|
39
|
+
steps:
|
40
|
+
- name: Checkout repository
|
41
|
+
uses: actions/checkout@v3
|
42
|
+
|
43
|
+
# Initializes the CodeQL tools for scanning.
|
44
|
+
- name: Initialize CodeQL
|
45
|
+
uses: github/codeql-action/init@v2
|
46
|
+
with:
|
47
|
+
languages: ${{ matrix.language }}
|
48
|
+
# If you wish to specify custom queries, you can do so here or in a config file.
|
49
|
+
# By default, queries listed here will override any specified in a config file.
|
50
|
+
# Prefix the list here with "+" to use these queries and those in the config file.
|
51
|
+
|
52
|
+
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
53
|
+
# queries: security-extended,security-and-quality
|
54
|
+
|
55
|
+
|
56
|
+
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
57
|
+
# If this step fails, then you should remove it and run the build manually (see below)
|
58
|
+
- name: Autobuild
|
59
|
+
uses: github/codeql-action/autobuild@v2
|
60
|
+
|
61
|
+
# ℹ️ Command-line programs to run using the OS shell.
|
62
|
+
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
63
|
+
|
64
|
+
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
65
|
+
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
66
|
+
|
67
|
+
# - run: |
|
68
|
+
# echo "Run, Build Application using script"
|
69
|
+
# ./location_of_script_within_repo/buildscript.sh
|
70
|
+
|
71
|
+
- name: Perform CodeQL Analysis
|
72
|
+
uses: github/codeql-action/analyze@v2
|
73
|
+
with:
|
74
|
+
category: "/language:${{matrix.language}}"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: tests
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ main ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ main ]
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
test:
|
18
|
+
runs-on: ubuntu-latest
|
19
|
+
strategy:
|
20
|
+
matrix:
|
21
|
+
ruby-version: ['2.6', '2.7', '3.0']
|
22
|
+
|
23
|
+
steps:
|
24
|
+
- uses: actions/checkout@v2
|
25
|
+
- name: Set up Ruby
|
26
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
27
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
28
|
+
# uses: ruby/setup-ruby@v1
|
29
|
+
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
30
|
+
with:
|
31
|
+
ruby-version: ${{ matrix.ruby-version }}
|
32
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
33
|
+
- name: Check code style
|
34
|
+
run: bundle exec standardrb
|
35
|
+
- name: Run tests
|
36
|
+
run: bundle exec rake
|
data/.gitignore
CHANGED
data/.standard.yml
ADDED
data/Gemfile
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
|
-
git_source(:github) {|repo_name|
|
3
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
|
+
|
5
|
+
gem "guard"
|
6
|
+
gem "guard-rspec", require: false
|
4
7
|
|
5
8
|
# Specify your gem's dependencies in shifty.gemspec
|
6
9
|
gemspec
|
data/Guardfile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(app lib config test spec features) \
|
6
|
+
# .select{|d| Dir.exist?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
7
|
+
|
8
|
+
## Note: if you are using the `directories` clause above and you are not
|
9
|
+
## watching the project directory ('.'), then you will want to move
|
10
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
11
|
+
#
|
12
|
+
# $ mkdir config
|
13
|
+
# $ mv Guardfile config/
|
14
|
+
# $ ln -s config/Guardfile .
|
15
|
+
#
|
16
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
17
|
+
|
18
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
19
|
+
# rspec may be run, below are examples of the most common uses.
|
20
|
+
# * bundler: 'bundle exec rspec'
|
21
|
+
# * bundler binstubs: 'bin/rspec'
|
22
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
23
|
+
# installed the spring binstubs per the docs)
|
24
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
25
|
+
# * 'just' rspec: 'rspec'
|
26
|
+
|
27
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
28
|
+
require "guard/rspec/dsl"
|
29
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
30
|
+
|
31
|
+
# Feel free to open issues for suggestions and improvements
|
32
|
+
|
33
|
+
# RSpec files
|
34
|
+
rspec = dsl.rspec
|
35
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
36
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
37
|
+
watch(rspec.spec_files)
|
38
|
+
|
39
|
+
# Ruby files
|
40
|
+
ruby = dsl.ruby
|
41
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
42
|
+
end
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
[](https://badge.fury.io/rb/shifty)
|
2
|
-
[](https://github.com/joelhelbling/shifty/actions/workflows/ruby.yml)
|
3
3
|
[](https://codeclimate.com/github/joelhelbling/shifty/maintainability)
|
4
4
|
[](https://codeclimate.com/github/joelhelbling/shifty/test_coverage)
|
5
5
|
|
@@ -21,7 +21,7 @@ And then execute:
|
|
21
21
|
|
22
22
|
Or install it yourself:
|
23
23
|
|
24
|
-
$ gem install
|
24
|
+
$ gem install shifty
|
25
25
|
|
26
26
|
And then use it:
|
27
27
|
|
@@ -344,7 +344,7 @@ worker simply provides a nil.
|
|
344
344
|
|
345
345
|
## Origins of Shifty
|
346
346
|
|
347
|
-
Shifty was
|
347
|
+
Shifty was [Stepladder](https://github.com/joelhelbling/stepladder), which grew out of experimentation with Ruby fibers, after reading
|
348
348
|
[Dave Thomas' demo of Ruby fibers](http://pragdave.me/blog/2007/12/30/pipelines-using-fibers-in-ruby-19/),
|
349
349
|
wherein he created a pipeline of fiber processes, emulating the style and syntax of the
|
350
350
|
\*nix command line. I noticed that, courtesy of fibers' extremely low surface area,
|
data/Rakefile
CHANGED
data/_config.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
theme: jekyll-theme-dinky
|
data/lib/shifty/dsl.rb
CHANGED
@@ -2,7 +2,7 @@ module Shifty
|
|
2
2
|
class WorkerInitializationError < StandardError; end
|
3
3
|
|
4
4
|
module DSL
|
5
|
-
def source_worker(argument=nil, &block)
|
5
|
+
def source_worker(argument = nil, &block)
|
6
6
|
ensure_correct_arity_for!(argument, block)
|
7
7
|
|
8
8
|
series = series_from(argument)
|
@@ -13,11 +13,10 @@ module Shifty
|
|
13
13
|
Worker.new do
|
14
14
|
series.each(&callable)
|
15
15
|
|
16
|
-
|
16
|
+
loop do
|
17
17
|
handoff nil
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
21
20
|
end
|
22
21
|
|
23
22
|
def relay_worker(&block)
|
@@ -28,10 +27,10 @@ module Shifty
|
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
31
|
-
def side_worker(mode
|
30
|
+
def side_worker(mode = :normal, &block)
|
32
31
|
ensure_regular_arity(block)
|
33
32
|
|
34
|
-
Worker.new do |value|
|
33
|
+
Worker.new(tags: [:side_effect]) do |value|
|
35
34
|
value.tap do |v|
|
36
35
|
used_value = mode == :hardened ?
|
37
36
|
Marshal.load(Marshal.dump(v)) : v
|
@@ -41,15 +40,15 @@ module Shifty
|
|
41
40
|
end
|
42
41
|
end
|
43
42
|
|
44
|
-
def filter_worker(argument=nil, &block)
|
45
|
-
if
|
46
|
-
throw_with
|
43
|
+
def filter_worker(argument = nil, &block)
|
44
|
+
if block && argument.respond_to?(:call)
|
45
|
+
throw_with "You cannot supply two callables"
|
47
46
|
end
|
48
47
|
callable = argument.respond_to?(:call) ? argument : block
|
49
48
|
ensure_callable(callable)
|
50
49
|
|
51
50
|
Worker.new do |value, supply|
|
52
|
-
while value && !callable.call(value)
|
51
|
+
while value && !callable.call(value)
|
53
52
|
value = supply.shift
|
54
53
|
end
|
55
54
|
value
|
@@ -59,23 +58,23 @@ module Shifty
|
|
59
58
|
class BatchContext < OpenStruct
|
60
59
|
def batch_complete?(value, collection)
|
61
60
|
value.nil? ||
|
62
|
-
!!
|
61
|
+
!!batch_full.call(value, collection)
|
63
62
|
end
|
64
63
|
end
|
65
64
|
|
66
65
|
def batch_worker(options = {gathering: 1}, &block)
|
67
66
|
ensure_regular_arity(block) if block
|
68
67
|
batch_full = block ||
|
69
|
-
|
68
|
+
proc { |_, batch| batch.size >= options[:gathering] }
|
70
69
|
|
71
|
-
batch_context = BatchContext.new({
|
70
|
+
batch_context = BatchContext.new({batch_full: batch_full})
|
72
71
|
|
73
72
|
Worker.new(context: batch_context) do |value, supply, context|
|
74
73
|
if value
|
75
74
|
context.collection = [value]
|
76
75
|
until context.batch_complete?(
|
77
|
-
|
78
|
-
|
76
|
+
context.collection.last,
|
77
|
+
context.collection
|
79
78
|
)
|
80
79
|
context.collection << supply.shift
|
81
80
|
end
|
@@ -92,7 +91,7 @@ module Shifty
|
|
92
91
|
value
|
93
92
|
else
|
94
93
|
parts = [block.call(value)].flatten
|
95
|
-
while parts.size > 1
|
94
|
+
while parts.size > 1
|
96
95
|
handoff parts.shift
|
97
96
|
end
|
98
97
|
parts.shift
|
@@ -100,7 +99,7 @@ module Shifty
|
|
100
99
|
end
|
101
100
|
end
|
102
101
|
|
103
|
-
def trailing_worker(trail_length=2)
|
102
|
+
def trailing_worker(trail_length = 2)
|
104
103
|
trail = []
|
105
104
|
Worker.new do |value, supply|
|
106
105
|
if value
|
@@ -126,12 +125,12 @@ module Shifty
|
|
126
125
|
private
|
127
126
|
|
128
127
|
def throw_with(*msg)
|
129
|
-
raise WorkerInitializationError.new([msg].flatten.join(
|
128
|
+
raise WorkerInitializationError.new([msg].flatten.join(" "))
|
130
129
|
end
|
131
130
|
|
132
131
|
def ensure_callable(callable)
|
133
|
-
unless callable
|
134
|
-
throw_with
|
132
|
+
unless callable&.respond_to?(:call)
|
133
|
+
throw_with "You must supply a callable"
|
135
134
|
end
|
136
135
|
end
|
137
136
|
|
@@ -147,20 +146,17 @@ module Shifty
|
|
147
146
|
return unless block
|
148
147
|
if argument
|
149
148
|
ensure_regular_arity(block)
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
'Source worker cannot accept any arguments (arity == 0)'
|
154
|
-
end
|
149
|
+
elsif block.arity > 0
|
150
|
+
throw_with \
|
151
|
+
"Source worker cannot accept any arguments (arity == 0)"
|
155
152
|
end
|
156
153
|
end
|
157
154
|
|
158
155
|
def series_from(series)
|
159
156
|
return if series.nil?
|
160
|
-
|
161
|
-
when series.respond_to?(:to_a)
|
157
|
+
if series.respond_to?(:to_a)
|
162
158
|
series.to_a
|
163
|
-
|
159
|
+
elsif series.respond_to?(:scan)
|
164
160
|
series.scan(/./)
|
165
161
|
else
|
166
162
|
[series]
|
@@ -170,11 +166,10 @@ module Shifty
|
|
170
166
|
def setup_callable_for(block, series)
|
171
167
|
return block unless series
|
172
168
|
if block
|
173
|
-
|
169
|
+
proc { |value| handoff block.call(value) }
|
174
170
|
else
|
175
|
-
|
171
|
+
proc { |value| handoff value }
|
176
172
|
end
|
177
173
|
end
|
178
|
-
|
179
174
|
end
|
180
175
|
end
|
data/lib/shifty/gang.rb
CHANGED
@@ -1,46 +1,52 @@
|
|
1
|
-
require
|
1
|
+
require "shifty/roster"
|
2
|
+
require "shifty/taggable"
|
2
3
|
|
3
4
|
module Shifty
|
4
5
|
class Gang
|
5
|
-
|
6
|
+
attr_reader :roster, :tags
|
6
7
|
|
7
|
-
|
8
|
-
link(workers + [])
|
9
|
-
end
|
8
|
+
include Taggable
|
10
9
|
|
11
|
-
def
|
12
|
-
workers
|
10
|
+
def initialize(workers = [], p = {})
|
11
|
+
@roster = Roster.new(workers)
|
12
|
+
self.criteria = p[:criteria]
|
13
|
+
self.tags = p[:tags]
|
13
14
|
end
|
14
15
|
|
15
16
|
def shift
|
16
|
-
|
17
|
+
if criteria_passes?
|
18
|
+
roster.last.shift
|
19
|
+
else
|
20
|
+
roster.first.supply.shift
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
19
24
|
def ready_to_work?
|
20
|
-
|
25
|
+
roster.first.ready_to_work?
|
21
26
|
end
|
22
27
|
|
23
28
|
def supply
|
24
|
-
|
29
|
+
roster.first.supply
|
25
30
|
end
|
26
31
|
|
27
|
-
def supply=(
|
28
|
-
|
32
|
+
def supply=(supplier)
|
33
|
+
roster.first.supply = supplier
|
29
34
|
end
|
30
35
|
|
31
|
-
def supplies(
|
32
|
-
|
36
|
+
def supplies(subscribing_worker)
|
37
|
+
subscribing_worker.supply = self
|
38
|
+
subscribing_worker
|
33
39
|
end
|
34
|
-
alias_method
|
40
|
+
alias_method :|, :supplies
|
35
41
|
|
36
|
-
|
42
|
+
def append(worker)
|
43
|
+
roster << worker
|
44
|
+
end
|
37
45
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
Roster[self] << worker
|
46
|
+
class << self
|
47
|
+
def [](*workers)
|
48
|
+
new workers
|
42
49
|
end
|
43
50
|
end
|
44
|
-
|
45
51
|
end
|
46
52
|
end
|
data/lib/shifty/roster.rb
CHANGED
@@ -1,33 +1,30 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
1
3
|
module Shifty
|
2
|
-
|
3
|
-
|
4
|
-
def [](gang)
|
5
|
-
RosterizedGang.new(gang)
|
6
|
-
end
|
7
|
-
end
|
8
|
-
end
|
4
|
+
class Roster
|
5
|
+
extend Forwardable
|
9
6
|
|
10
|
-
|
11
|
-
attr_reader :gang
|
7
|
+
attr_reader :workers
|
12
8
|
|
13
|
-
def initialize(
|
14
|
-
@
|
9
|
+
def initialize(workers = [])
|
10
|
+
@workers = []
|
11
|
+
workers.each do |worker|
|
12
|
+
push worker
|
13
|
+
end
|
15
14
|
end
|
16
15
|
|
17
|
-
|
18
|
-
gang.workers
|
19
|
-
end
|
16
|
+
def_delegators :workers, :first, :last
|
20
17
|
|
21
18
|
def push(worker)
|
22
19
|
if worker
|
23
|
-
worker.supply = workers.last
|
20
|
+
worker.supply = workers.last unless workers.empty?
|
24
21
|
workers << worker
|
25
22
|
end
|
26
23
|
end
|
27
|
-
alias_method
|
24
|
+
alias_method :<<, :push
|
28
25
|
|
29
26
|
def pop
|
30
|
-
|
27
|
+
workers.pop.tap do |popped|
|
31
28
|
popped.supply = nil
|
32
29
|
end
|
33
30
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Shifty
|
2
|
+
module Taggable
|
3
|
+
def tags=(tag_arg)
|
4
|
+
@tags = [tag_arg].flatten.compact
|
5
|
+
end
|
6
|
+
|
7
|
+
def criteria=(criteria_arg)
|
8
|
+
@criteria = [criteria_arg].flatten.compact
|
9
|
+
end
|
10
|
+
|
11
|
+
def has_tag?(tag)
|
12
|
+
@tags.include? tag
|
13
|
+
end
|
14
|
+
|
15
|
+
def criteria_passes?
|
16
|
+
return true if @criteria.empty?
|
17
|
+
|
18
|
+
@criteria.all? { |c| c.call(self) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/shifty/version.rb
CHANGED
data/lib/shifty/worker.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
require
|
1
|
+
require "ostruct"
|
2
|
+
require "shifty/taggable"
|
2
3
|
|
3
4
|
module Shifty
|
4
5
|
class Worker
|
5
|
-
attr_reader :supply
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
# method-based tasks.
|
6
|
+
attr_reader :supply, :tags
|
7
|
+
|
8
|
+
include Shifty::Taggable
|
9
|
+
|
10
|
+
def initialize(p = {}, &block)
|
11
|
+
@supply = p[:supply]
|
12
|
+
@task = block || p[:task]
|
13
|
+
@context = p[:context] || OpenStruct.new
|
14
|
+
self.criteria = p[:criteria]
|
15
|
+
self.tags = p[:tags]
|
16
16
|
end
|
17
17
|
|
18
18
|
def shift
|
@@ -24,11 +24,11 @@ module Shifty
|
|
24
24
|
@task && (supply || !task_accepts_a_value?)
|
25
25
|
end
|
26
26
|
|
27
|
-
def supplies(
|
28
|
-
|
29
|
-
|
27
|
+
def supplies(subscribing_worker)
|
28
|
+
subscribing_worker.supply = self
|
29
|
+
subscribing_worker
|
30
30
|
end
|
31
|
-
alias_method
|
31
|
+
alias_method :|, :supplies
|
32
32
|
|
33
33
|
def supply=(supplier)
|
34
34
|
raise WorkerError.new("Worker is a source, and cannot accept a supply") unless suppliable?
|
@@ -50,16 +50,20 @@ module Shifty
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def workflow
|
53
|
-
@my_little_machine ||= Fiber.new
|
53
|
+
@my_little_machine ||= Fiber.new {
|
54
54
|
loop do
|
55
|
-
value = supply
|
56
|
-
|
55
|
+
value = supply&.shift
|
56
|
+
if criteria_passes?
|
57
|
+
Fiber.yield @task.call(value, supply, @context)
|
58
|
+
else
|
59
|
+
Fiber.yield value
|
60
|
+
end
|
57
61
|
end
|
58
|
-
|
62
|
+
}
|
59
63
|
end
|
60
64
|
|
61
65
|
def default_task
|
62
|
-
|
66
|
+
proc { |value| value }
|
63
67
|
end
|
64
68
|
|
65
69
|
def task_accepts_a_value?
|
@@ -67,13 +71,12 @@ module Shifty
|
|
67
71
|
end
|
68
72
|
|
69
73
|
def task_method_exists?
|
70
|
-
|
74
|
+
methods.include? :task
|
71
75
|
end
|
72
76
|
|
73
77
|
def task_method_accepts_a_value?
|
74
|
-
|
78
|
+
method(:task).arity > 0
|
75
79
|
end
|
76
|
-
|
77
80
|
end
|
78
81
|
|
79
82
|
class WorkerError < StandardError; end
|
data/lib/shifty.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require_relative
|
2
|
-
require_relative
|
3
|
-
require_relative
|
4
|
-
require_relative
|
5
|
-
require_relative
|
1
|
+
require_relative "shifty/version"
|
2
|
+
require_relative "shifty/worker"
|
3
|
+
require_relative "shifty/gang"
|
4
|
+
require_relative "shifty/roster"
|
5
|
+
require_relative "shifty/dsl"
|
data/shifty.gemspec
CHANGED
@@ -1,29 +1,29 @@
|
|
1
|
-
lib = File.expand_path(
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require
|
3
|
+
require "shifty/version"
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name
|
7
|
-
spec.version
|
8
|
-
spec.authors
|
9
|
-
spec.email
|
6
|
+
spec.name = "shifty"
|
7
|
+
spec.version = Shifty::VERSION
|
8
|
+
spec.authors = ["Joel Helbling"]
|
9
|
+
spec.email = ["joel@joelhelbling.com"]
|
10
10
|
|
11
|
-
spec.summary
|
12
|
-
spec.description
|
13
|
-
spec.homepage
|
14
|
-
spec.license
|
11
|
+
spec.summary = "A functional framework aimed at extremely low coupling"
|
12
|
+
spec.description = "Shifty provides tools for coordinating simple workers which consume a supplying queue and emit corresponding work products, valuing pure functions, carefully isolated side effects, and extremely low coupling."
|
13
|
+
spec.homepage = "https://github.com/joelhelbling/shifty"
|
14
|
+
spec.license = "MIT"
|
15
15
|
|
16
|
-
spec.files
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
17
|
f.match(%r{^(test|spec|features)/})
|
18
18
|
end
|
19
|
-
spec.bindir
|
20
|
-
spec.executables
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.9"
|
25
|
+
spec.add_development_dependency "rspec-given", "~> 3.8"
|
26
|
+
spec.add_development_dependency "pry"
|
27
|
+
spec.add_development_dependency "standard", "~> 1.1"
|
28
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
29
29
|
end
|
metadata
CHANGED
@@ -1,57 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shifty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Helbling
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.16'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.16'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: rake
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
|
-
- - "
|
17
|
+
- - ">="
|
32
18
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
19
|
+
version: '0'
|
34
20
|
type: :development
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
38
|
-
- - "
|
24
|
+
- - ">="
|
39
25
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
26
|
+
version: '0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: rspec
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
31
|
- - "~>"
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
33
|
+
version: '3.9'
|
48
34
|
type: :development
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
38
|
- - "~>"
|
53
39
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3.
|
40
|
+
version: '3.9'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: rspec-given
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,7 +67,21 @@ dependencies:
|
|
81
67
|
- !ruby/object:Gem::Version
|
82
68
|
version: '0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
70
|
+
name: standard
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.1'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.1'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: codeclimate-test-reporter
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -103,13 +103,18 @@ executables: []
|
|
103
103
|
extensions: []
|
104
104
|
extra_rdoc_files: []
|
105
105
|
files:
|
106
|
+
- ".github/dependabot.yml"
|
107
|
+
- ".github/workflows/codeql-analysis.yml"
|
108
|
+
- ".github/workflows/ruby.yml"
|
106
109
|
- ".gitignore"
|
107
110
|
- ".rspec"
|
108
|
-
- ".
|
111
|
+
- ".standard.yml"
|
109
112
|
- Gemfile
|
113
|
+
- Guardfile
|
110
114
|
- LICENSE.txt
|
111
115
|
- README.md
|
112
116
|
- Rakefile
|
117
|
+
- _config.yml
|
113
118
|
- bin/console
|
114
119
|
- bin/setup
|
115
120
|
- docs/shifty/worker.md
|
@@ -117,6 +122,7 @@ files:
|
|
117
122
|
- lib/shifty/dsl.rb
|
118
123
|
- lib/shifty/gang.rb
|
119
124
|
- lib/shifty/roster.rb
|
125
|
+
- lib/shifty/taggable.rb
|
120
126
|
- lib/shifty/version.rb
|
121
127
|
- lib/shifty/worker.rb
|
122
128
|
- pkg/.gitkeep
|
@@ -125,7 +131,7 @@ homepage: https://github.com/joelhelbling/shifty
|
|
125
131
|
licenses:
|
126
132
|
- MIT
|
127
133
|
metadata: {}
|
128
|
-
post_install_message:
|
134
|
+
post_install_message:
|
129
135
|
rdoc_options: []
|
130
136
|
require_paths:
|
131
137
|
- lib
|
@@ -140,9 +146,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
146
|
- !ruby/object:Gem::Version
|
141
147
|
version: '0'
|
142
148
|
requirements: []
|
143
|
-
|
144
|
-
|
145
|
-
signing_key:
|
149
|
+
rubygems_version: 3.3.3
|
150
|
+
signing_key:
|
146
151
|
specification_version: 4
|
147
152
|
summary: A functional framework aimed at extremely low coupling
|
148
153
|
test_files: []
|
data/.travis.yml
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
env:
|
2
|
-
global:
|
3
|
-
- CC_TEST_REPORTER_ID=de10d77685b449162f3f3d568e1ab75d94c0f281afceee218502cf0995e49aa6
|
4
|
-
sudo: false
|
5
|
-
language: ruby
|
6
|
-
rvm:
|
7
|
-
- 2.5.0
|
8
|
-
- jruby-19mode
|
9
|
-
before_install: gem install bundler -v 1.16.1
|
10
|
-
before_script:
|
11
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
12
|
-
- chmod +x ./cc-test-reporter
|
13
|
-
- ./cc-test-reporter before-build
|
14
|
-
script:
|
15
|
-
- bundle exec rspec
|
16
|
-
after_script:
|
17
|
-
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|