standard-procedure-plumbing 0.3.3 → 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/README.md +58 -88
- data/lib/plumbing/actor/async.rb +38 -0
- data/lib/plumbing/actor/inline.rb +22 -0
- data/lib/plumbing/actor/kernel.rb +9 -0
- data/lib/plumbing/{valve → actor}/rails.rb +1 -1
- data/lib/plumbing/{valve → actor}/threaded.rb +22 -27
- data/lib/plumbing/actor/transporter.rb +61 -0
- data/lib/plumbing/actor.rb +63 -0
- data/lib/plumbing/config.rb +8 -8
- data/lib/plumbing/pipe.rb +2 -3
- data/lib/plumbing/version.rb +1 -1
- data/lib/plumbing.rb +1 -1
- data/spec/examples/{valve_spec.rb → actor_spec.rb} +14 -14
- data/spec/examples/pipe_spec.rb +4 -4
- data/spec/plumbing/a_pipe.rb +11 -9
- data/spec/plumbing/actor/transporter_spec.rb +158 -0
- data/spec/plumbing/actor_spec.rb +208 -0
- metadata +27 -11
- data/lib/plumbing/valve/async.rb +0 -43
- data/lib/plumbing/valve/inline.rb +0 -20
- data/lib/plumbing/valve/message.rb +0 -5
- data/lib/plumbing/valve.rb +0 -71
- data/spec/plumbing/valve_spec.rb +0 -171
data/lib/plumbing/valve.rb
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
require_relative "valve/inline"
|
2
|
-
|
3
|
-
module Plumbing
|
4
|
-
module Valve
|
5
|
-
def self.included base
|
6
|
-
base.extend ClassMethods
|
7
|
-
end
|
8
|
-
|
9
|
-
module ClassMethods
|
10
|
-
# Create a new valve instance and build a proxy for it using the current mode
|
11
|
-
# @return [Plumbing::Valve::Base] the proxy for the valve instance
|
12
|
-
def start(*, **, &)
|
13
|
-
build_proxy_for(new(*, **, &))
|
14
|
-
end
|
15
|
-
|
16
|
-
# Define the queries that this valve can answer
|
17
|
-
# @param names [Array<Symbol>] the names of the queries
|
18
|
-
def query(*names) = queries.concat(names.map(&:to_sym))
|
19
|
-
|
20
|
-
# List the queries that this valve can answer
|
21
|
-
def queries = @queries ||= []
|
22
|
-
|
23
|
-
# Define the commands that this valve can execute
|
24
|
-
# @param names [Array<Symbol>] the names of the commands
|
25
|
-
def command(*names) = commands.concat(names.map(&:to_sym))
|
26
|
-
|
27
|
-
# List the commands that this valve can execute
|
28
|
-
def commands = @commands ||= []
|
29
|
-
|
30
|
-
def inherited subclass
|
31
|
-
subclass.commands.concat commands
|
32
|
-
subclass.queries.concat queries
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def build_proxy_for(target)
|
38
|
-
proxy_class_for(target.class).new(target)
|
39
|
-
end
|
40
|
-
|
41
|
-
def proxy_class_for target_class
|
42
|
-
Plumbing.config.valve_proxy_class_for(target_class) || register_valve_proxy_class_for(target_class)
|
43
|
-
end
|
44
|
-
|
45
|
-
def proxy_base_class = const_get "Plumbing::Valve::#{Plumbing.config.mode.to_s.capitalize}"
|
46
|
-
|
47
|
-
def register_valve_proxy_class_for target_class
|
48
|
-
Plumbing.config.register_valve_proxy_class_for(target_class, build_proxy_class)
|
49
|
-
end
|
50
|
-
|
51
|
-
def build_proxy_class
|
52
|
-
Class.new(proxy_base_class).tap do |proxy_class|
|
53
|
-
queries.each do |query|
|
54
|
-
proxy_class.define_method query do |*args, ignore_result: false, **params, &block|
|
55
|
-
ignore_result ? tell(query, *args, **params, &block) : ask(query, *args, **params, &block)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
commands.each do |command|
|
60
|
-
proxy_class.define_method command do |*args, **params, &block|
|
61
|
-
tell(command, *args, **params, &block)
|
62
|
-
nil
|
63
|
-
rescue
|
64
|
-
nil
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
data/spec/plumbing/valve_spec.rb
DELETED
@@ -1,171 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
require_relative "../../lib/plumbing/valve/async"
|
4
|
-
require_relative "../../lib/plumbing/valve/threaded"
|
5
|
-
require_relative "../../lib/plumbing/valve/rails"
|
6
|
-
|
7
|
-
RSpec.describe Plumbing::Valve do
|
8
|
-
# standard:disable Lint/ConstantDefinitionInBlock
|
9
|
-
class Counter
|
10
|
-
include Plumbing::Valve
|
11
|
-
query :name, :count, :am_i_failing?, :slow_query
|
12
|
-
command "slowly_increment", "raises_error"
|
13
|
-
attr_reader :name, :count
|
14
|
-
|
15
|
-
def initialize name, initial_value: 0
|
16
|
-
@name = name
|
17
|
-
@count = initial_value
|
18
|
-
end
|
19
|
-
|
20
|
-
def slowly_increment
|
21
|
-
sleep 0.5
|
22
|
-
@count += 1
|
23
|
-
end
|
24
|
-
|
25
|
-
def slow_query
|
26
|
-
sleep 0.5
|
27
|
-
@count
|
28
|
-
end
|
29
|
-
|
30
|
-
def am_i_failing? = raise "I'm a failure"
|
31
|
-
|
32
|
-
def raises_error = raise "I'm an error"
|
33
|
-
end
|
34
|
-
|
35
|
-
class StepCounter < Counter
|
36
|
-
query :step_value
|
37
|
-
attr_reader :step_value
|
38
|
-
|
39
|
-
def initialize name, initial_value: 0, step_value: 5
|
40
|
-
super(name, initial_value: initial_value)
|
41
|
-
@step_value = step_value
|
42
|
-
end
|
43
|
-
|
44
|
-
def slowly_increment
|
45
|
-
sleep 0.5
|
46
|
-
@count += @step_value
|
47
|
-
end
|
48
|
-
|
49
|
-
def failing_query
|
50
|
-
raise "I'm a failure"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
# standard:enable Lint/ConstantDefinitionInBlock
|
54
|
-
|
55
|
-
it "knows which queries are defined" do
|
56
|
-
expect(Counter.queries).to eq [:name, :count, :am_i_failing?, :slow_query]
|
57
|
-
end
|
58
|
-
|
59
|
-
it "knows which commands are defined" do
|
60
|
-
expect(Counter.commands).to eq [:slowly_increment, :raises_error]
|
61
|
-
end
|
62
|
-
|
63
|
-
it "raises exceptions from queries" do
|
64
|
-
@counter = Counter.start "failure"
|
65
|
-
|
66
|
-
expect { @counter.am_i_failing? }.to raise_error "I'm a failure"
|
67
|
-
end
|
68
|
-
|
69
|
-
it "does not raise exceptions from commands" do
|
70
|
-
@counter = Counter.start "failure"
|
71
|
-
|
72
|
-
expect { @counter.raises_error }.not_to raise_error
|
73
|
-
end
|
74
|
-
|
75
|
-
it "raises exceptions from queries" do
|
76
|
-
@counter = Counter.start "failure"
|
77
|
-
|
78
|
-
expect { @counter.am_i_failing? }.to raise_error "I'm a failure"
|
79
|
-
end
|
80
|
-
|
81
|
-
it "reuses existing proxy classes" do
|
82
|
-
@counter = Counter.start "inline counter", initial_value: 100
|
83
|
-
@proxy_class = @counter.class
|
84
|
-
|
85
|
-
@counter = Counter.start "another inline counter", initial_value: 200
|
86
|
-
expect(@counter.class).to eq @proxy_class
|
87
|
-
end
|
88
|
-
|
89
|
-
it "includes commands and queries from the superclass" do
|
90
|
-
expect(StepCounter.queries).to eq [:name, :count, :am_i_failing?, :slow_query, :step_value]
|
91
|
-
expect(StepCounter.commands).to eq [:slowly_increment, :raises_error]
|
92
|
-
|
93
|
-
@step_counter = StepCounter.start "step counter", initial_value: 100, step_value: 10
|
94
|
-
|
95
|
-
expect(@step_counter.count).to eq 100
|
96
|
-
expect(@step_counter.step_value).to eq 10
|
97
|
-
@step_counter.slowly_increment
|
98
|
-
expect(@step_counter.count).to eq 110
|
99
|
-
end
|
100
|
-
|
101
|
-
context "inline" do
|
102
|
-
around :example do |example|
|
103
|
-
Plumbing.configure mode: :inline, &example
|
104
|
-
end
|
105
|
-
|
106
|
-
it "sends all queries immediately" do
|
107
|
-
@counter = Counter.start "inline counter", initial_value: 100
|
108
|
-
@time = Time.now
|
109
|
-
|
110
|
-
expect(@counter.name).to eq "inline counter"
|
111
|
-
expect(@counter.count).to eq 100
|
112
|
-
expect(Time.now - @time).to be < 0.1
|
113
|
-
|
114
|
-
expect(@counter.slow_query).to eq 100
|
115
|
-
expect(Time.now - @time).to be > 0.4
|
116
|
-
end
|
117
|
-
|
118
|
-
it "sends all commands immediately" do
|
119
|
-
@counter = Counter.start "inline counter", initial_value: 100
|
120
|
-
@time = Time.now
|
121
|
-
|
122
|
-
@counter.slowly_increment
|
123
|
-
|
124
|
-
expect(@counter.count).to eq 101
|
125
|
-
expect(Time.now - @time).to be > 0.4
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
[:threaded, :async].each do |mode|
|
130
|
-
context mode.to_s do
|
131
|
-
around :example do |example|
|
132
|
-
Sync do
|
133
|
-
Plumbing.configure mode: mode, &example
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
it "performs queries in the background and waits for the response" do
|
138
|
-
@counter = Counter.start "async counter", initial_value: 100
|
139
|
-
@time = Time.now
|
140
|
-
|
141
|
-
expect(@counter.name).to eq "async counter"
|
142
|
-
expect(@counter.count).to eq 100
|
143
|
-
expect(Time.now - @time).to be < 0.1
|
144
|
-
|
145
|
-
expect(@counter.slow_query).to eq 100
|
146
|
-
expect(Time.now - @time).to be > 0.4
|
147
|
-
end
|
148
|
-
|
149
|
-
it "performs queries ignoring the response and returning immediately" do
|
150
|
-
@counter = Counter.start "threaded counter", initial_value: 100
|
151
|
-
@time = Time.now
|
152
|
-
|
153
|
-
expect(@counter.slow_query(ignore_result: true)).to be_nil
|
154
|
-
|
155
|
-
expect(Time.now - @time).to be < 0.1
|
156
|
-
end
|
157
|
-
|
158
|
-
it "performs commands in the background and returning immediately" do
|
159
|
-
@counter = Counter.start "threaded counter", initial_value: 100
|
160
|
-
@time = Time.now
|
161
|
-
|
162
|
-
@counter.slowly_increment
|
163
|
-
expect(Time.now - @time).to be < 0.1
|
164
|
-
|
165
|
-
# wait for the threaded task to complete
|
166
|
-
expect(101).to become_equal_to { @counter.count }
|
167
|
-
expect(Time.now - @time).to be > 0.4
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|