emit 0.1.0 → 0.2.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/.gitignore +1 -0
- data/README.md +1 -0
- data/benchmarks/choice.rb +22 -0
- data/benchmarks/commstime.rb +1 -1
- data/benchmarks/deadlock.rb +14 -0
- data/benchmarks/starvation.rb +2 -4
- data/lib/emit.rb +7 -6
- data/lib/emit/alternation.rb +19 -27
- data/lib/emit/input_guard.rb +14 -5
- data/lib/emit/output_guard.rb +15 -6
- data/lib/emit/version.rb +1 -1
- metadata +4 -4
- data/benchmarks/select.rb +0 -30
- data/lib/emit/choice.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a43400e02ac71c9a0c9568be319833e69c9e0b18
|
4
|
+
data.tar.gz: b28b6b8e6a01ef1b84e6e5fa797e5c404e387012
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0597efaa0e69f35a94244698b5b038788e5210c780166af65068e254c04e47c3fa6717d215e680dde058167f63b7b264d2ab0de00a6b9b344974d0109023609
|
7
|
+
data.tar.gz: 68af9bef63afdce8f990890fd4a55dae5e3fe6cf0df86449d17a4c17bd8c603d962b5b0cb922d6851de3f84f36ea8b62cc5f40ee4602459b2754e720a391b0f8
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "emit"
|
2
|
+
|
3
|
+
$result = []
|
4
|
+
|
5
|
+
def selector(cin1, cin2, n)
|
6
|
+
n.times do
|
7
|
+
_, msg = Emit.choice(cin1, cin2)
|
8
|
+
$result << msg
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
ch1 = Emit.channel
|
13
|
+
ch2 = Emit.channel
|
14
|
+
|
15
|
+
n = 100
|
16
|
+
Emit.parallel(
|
17
|
+
Emit.process { n.times { -ch1 << 0 } },
|
18
|
+
Emit.process { n.times { -ch2 << 1 } },
|
19
|
+
Emit.selector(+ch1, +ch2, 2*n)
|
20
|
+
)
|
21
|
+
|
22
|
+
puts $result.inspect
|
data/benchmarks/commstime.rb
CHANGED
data/benchmarks/starvation.rb
CHANGED
data/lib/emit.rb
CHANGED
@@ -16,11 +16,10 @@ require "emit/input_guard"
|
|
16
16
|
require "emit/output_guard"
|
17
17
|
|
18
18
|
require "emit/alternation"
|
19
|
-
require "emit/choice"
|
20
19
|
|
21
20
|
module Emit
|
22
21
|
class << self
|
23
|
-
def parallel(*processes)
|
22
|
+
def parallel(*processes, run: true)
|
24
23
|
processes.flatten!
|
25
24
|
|
26
25
|
processes.each do |process|
|
@@ -28,8 +27,10 @@ module Emit
|
|
28
27
|
Scheduler.enqueue(process)
|
29
28
|
end
|
30
29
|
|
31
|
-
|
32
|
-
|
30
|
+
if run
|
31
|
+
Scheduler.join(processes)
|
32
|
+
processes.map(&:return_value)
|
33
|
+
end
|
33
34
|
end
|
34
35
|
|
35
36
|
def sequence(*processes)
|
@@ -52,8 +53,8 @@ module Emit
|
|
52
53
|
channel_ends.each(&:retire)
|
53
54
|
end
|
54
55
|
|
55
|
-
def
|
56
|
-
Alternation.new(guards
|
56
|
+
def choice(*guards)
|
57
|
+
Alternation.new(guards).execute
|
57
58
|
end
|
58
59
|
|
59
60
|
def method_missing(name, *args, **kwargs)
|
data/lib/emit/alternation.rb
CHANGED
@@ -1,30 +1,26 @@
|
|
1
1
|
module Emit
|
2
2
|
class Alternation
|
3
3
|
def initialize(guards)
|
4
|
-
@guards = guards
|
4
|
+
@guards = guards.map do |guard|
|
5
|
+
case guard
|
6
|
+
when InputGuard then guard
|
7
|
+
when OutputGuard then guard
|
8
|
+
else
|
9
|
+
InputGuard.new(guard)
|
10
|
+
end
|
11
|
+
end
|
5
12
|
end
|
6
13
|
|
7
14
|
def execute
|
8
15
|
idx, request, channel, operation = choose
|
9
16
|
|
10
17
|
if @guards[idx]
|
11
|
-
action = @guards[idx].
|
18
|
+
action = @guards[idx].action
|
19
|
+
fail "Failed executing action in alternation." unless [Proc, Method].include?(action.class)
|
12
20
|
|
13
|
-
case
|
14
|
-
when
|
15
|
-
|
16
|
-
when :write then action.invoke_on_output
|
17
|
-
when :read then action.invoke_on_input(request.message)
|
18
|
-
end
|
19
|
-
when Proc, Method
|
20
|
-
case operation
|
21
|
-
when :write then action.()
|
22
|
-
when :read then action.(message: request.message)
|
23
|
-
end
|
24
|
-
when nil
|
25
|
-
# no-op
|
26
|
-
else
|
27
|
-
fail "Failed executing action: #{action}."
|
21
|
+
case operation
|
22
|
+
when :write then action.()
|
23
|
+
when :read then action.(request.message)
|
28
24
|
end
|
29
25
|
end
|
30
26
|
|
@@ -36,29 +32,25 @@ module Emit
|
|
36
32
|
def choose
|
37
33
|
requests = {}
|
38
34
|
act = nil
|
39
|
-
poison = false
|
40
|
-
retire = false
|
41
35
|
|
42
36
|
Scheduler.current.state = :active
|
43
37
|
|
44
38
|
begin
|
45
39
|
idx = 0
|
46
40
|
@guards.each do |guard|
|
47
|
-
if
|
41
|
+
if OutputGuard === guard
|
48
42
|
operation = :write
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
elsif guard.size == 2 # read
|
43
|
+
request = ChannelRequest.new(Scheduler.current, guard.message)
|
44
|
+
guard.channel_end.send(:post_write, request)
|
45
|
+
elsif InputGuard === guard
|
53
46
|
operation = :read
|
54
|
-
channel, action = guard
|
55
47
|
request = ChannelRequest.new(Scheduler.current)
|
56
|
-
|
48
|
+
guard.channel_end.send(:post_read, request)
|
57
49
|
else
|
58
50
|
fail "Guard was neither write or read."
|
59
51
|
end
|
60
52
|
|
61
|
-
requests[request] = [idx,
|
53
|
+
requests[request] = [idx, guard.channel_end, operation]
|
62
54
|
idx += 1
|
63
55
|
end
|
64
56
|
rescue ChannelPoisonedException, ChannelRetiredException
|
data/lib/emit/input_guard.rb
CHANGED
@@ -1,13 +1,22 @@
|
|
1
1
|
module Emit
|
2
2
|
class InputGuard
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :channel_end, :action
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
|
7
|
-
|
5
|
+
def initialize(argument, action=->(msg) {msg})
|
6
|
+
case argument
|
7
|
+
when InputGuard
|
8
|
+
@channel_end, @action = argument.channel_end, argument.action
|
9
|
+
when ChannelEndRead
|
10
|
+
@channel_end, @action = argument, action
|
11
|
+
when Array
|
12
|
+
fail "Wrong number of arguments" unless argument.size == 2
|
13
|
+
@channel_end, @action = argument
|
8
14
|
else
|
9
|
-
fail "
|
15
|
+
fail "Unknown input guard type"
|
10
16
|
end
|
17
|
+
|
18
|
+
fail "InputGuard must have a reading channel end." unless ChannelEndRead === @channel_end
|
19
|
+
fail "InputGuard action cannot be nil" if @action.nil?
|
11
20
|
end
|
12
21
|
end
|
13
22
|
end
|
data/lib/emit/output_guard.rb
CHANGED
@@ -1,13 +1,22 @@
|
|
1
1
|
module Emit
|
2
|
-
class
|
3
|
-
attr_reader :
|
2
|
+
class OutputGuard
|
3
|
+
attr_reader :channel_end, :message, :action
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
|
7
|
-
|
5
|
+
def initialize(argument, message, action=nil)
|
6
|
+
case argument
|
7
|
+
when OutputGuard
|
8
|
+
@channel_end, @message, @action = argument.channel_end, argument.message, argument.action
|
9
|
+
when ChannelEndWrite
|
10
|
+
@channel_end, @message, @action = argument, message, action
|
11
|
+
when Array
|
12
|
+
fail "Wrong number of arguments" unless argument.size == 3
|
13
|
+
@channel_end, @message, @action = argument
|
8
14
|
else
|
9
|
-
fail "
|
15
|
+
fail "Unknown output guard type"
|
10
16
|
end
|
17
|
+
|
18
|
+
fail "OutputGuard must have a writing channel end." unless ChannelEndWrite === channel_end
|
19
|
+
fail "OutputGuard action cannot be nil" if @action.nil?
|
11
20
|
end
|
12
21
|
end
|
13
22
|
end
|
data/lib/emit/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: emit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mads Ohm Larsen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05
|
11
|
+
date: 2018-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,10 +66,11 @@ files:
|
|
66
66
|
- LICENSE.txt
|
67
67
|
- README.md
|
68
68
|
- Rakefile
|
69
|
+
- benchmarks/choice.rb
|
69
70
|
- benchmarks/commstime.rb
|
71
|
+
- benchmarks/deadlock.rb
|
70
72
|
- benchmarks/many_processes.rb
|
71
73
|
- benchmarks/montecarlopi.rb
|
72
|
-
- benchmarks/select.rb
|
73
74
|
- benchmarks/starvation.rb
|
74
75
|
- bin/console
|
75
76
|
- bin/setup
|
@@ -81,7 +82,6 @@ files:
|
|
81
82
|
- lib/emit/channel_end_read.rb
|
82
83
|
- lib/emit/channel_end_write.rb
|
83
84
|
- lib/emit/channel_request.rb
|
84
|
-
- lib/emit/choice.rb
|
85
85
|
- lib/emit/exceptions.rb
|
86
86
|
- lib/emit/input_guard.rb
|
87
87
|
- lib/emit/output_guard.rb
|
data/benchmarks/select.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
require "emit"
|
2
|
-
|
3
|
-
@result = []
|
4
|
-
def action(message: nil)
|
5
|
-
@result << message
|
6
|
-
end
|
7
|
-
|
8
|
-
def p1(cout, n)
|
9
|
-
n.times { |i| cout << i }
|
10
|
-
end
|
11
|
-
|
12
|
-
def p2(cin1, cin2, n)
|
13
|
-
n.times do
|
14
|
-
Emit.select(
|
15
|
-
Emit::InputGuard.new(cin1, action: method(:action)),
|
16
|
-
Emit::InputGuard.new(cin2, action: method(:action))
|
17
|
-
)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
ch1 = Emit.channel
|
22
|
-
ch2 = Emit.channel
|
23
|
-
|
24
|
-
Emit.parallel(
|
25
|
-
Emit.process(-ch1, 50, &method(:p1)),
|
26
|
-
Emit.process(-ch2, 50, &method(:p1)),
|
27
|
-
Emit.process(+ch1, +ch2, 100, &method(:p2))
|
28
|
-
)
|
29
|
-
|
30
|
-
puts @result.inspect
|
data/lib/emit/choice.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
module Emit
|
2
|
-
class Choice
|
3
|
-
def initialize(*args, **kwargs, &block)
|
4
|
-
@block = block
|
5
|
-
@args = args
|
6
|
-
@kwargs = kwargs
|
7
|
-
end
|
8
|
-
|
9
|
-
def invoke_on_output
|
10
|
-
@block.call(*@args, **@kwargs)
|
11
|
-
end
|
12
|
-
|
13
|
-
def invoke_on_input(message)
|
14
|
-
@kwargs[:message] = message
|
15
|
-
@block.call(*@args, **@kwargs)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|