rbsim 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/.hgignore +6 -0
- data/.rspec +2 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +66 -0
- data/LICENSE.txt +674 -0
- data/README.md +960 -0
- data/TODO +28 -0
- data/basic_sim.rb +62 -0
- data/fast-tcpn.rb +3 -0
- data/lib/rbsim.rb +14 -0
- data/lib/rbsim/dsl.rb +30 -0
- data/lib/rbsim/dsl/infrastructure.rb +48 -0
- data/lib/rbsim/dsl/mapping.rb +32 -0
- data/lib/rbsim/dsl/process.rb +129 -0
- data/lib/rbsim/dsl/program.rb +10 -0
- data/lib/rbsim/experiment.rb +110 -0
- data/lib/rbsim/hlmodel.rb +25 -0
- data/lib/rbsim/hlmodel/infrastructure.rb +116 -0
- data/lib/rbsim/hlmodel/mapping.rb +5 -0
- data/lib/rbsim/hlmodel/process.rb +152 -0
- data/lib/rbsim/numeric_units.rb +107 -0
- data/lib/rbsim/simulator.rb +184 -0
- data/lib/rbsim/statistics.rb +77 -0
- data/lib/rbsim/tokens.rb +146 -0
- data/lib/rbsim/version.rb +3 -0
- data/new_process.rb +49 -0
- data/rbsim.gemspec +42 -0
- data/show_readme.rb +15 -0
- data/sim.rb +142 -0
- data/sim_bamboo.rb +251 -0
- data/sim_process.rb +83 -0
- data/sim_process_dsl.rb +58 -0
- data/spec/dsl/infrastructure_nets_spec.rb +39 -0
- data/spec/dsl/infrastructure_nodes_spec.rb +72 -0
- data/spec/dsl/infrastructure_routes_spec.rb +44 -0
- data/spec/dsl/mapping_spec.rb +70 -0
- data/spec/dsl/process_spec.rb +56 -0
- data/spec/dsl/program_spec.rb +36 -0
- data/spec/dsl_and_hlmodel/new_process_spec.rb +235 -0
- data/spec/hlmodel/net_spec.rb +112 -0
- data/spec/hlmodel/process_spec.rb +242 -0
- data/spec/hlmodel/route_spec.rb +47 -0
- data/spec/hlmodel/routes_spec.rb +44 -0
- data/spec/integration/basic_simulation_spec.rb +104 -0
- data/spec/integration/net_spec.rb +44 -0
- data/spec/integration/process_spec.rb +117 -0
- data/spec/integration/rbsim_spec.rb +40 -0
- data/spec/simulator/logger_spec.rb +35 -0
- data/spec/simulator/stats_spec.rb +93 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/statistics_spec.rb +300 -0
- data/spec/tcpn/add_route_spec.rb +55 -0
- data/spec/tcpn/cpu_spec.rb +53 -0
- data/spec/tcpn/map_data_spec.rb +37 -0
- data/spec/tcpn/network_spec.rb +163 -0
- data/spec/tcpn/register_event_spec.rb +48 -0
- data/spec/tcpn/route_to_self_spec.rb +53 -0
- data/spec/tcpn/stats_spec.rb +77 -0
- data/spec/tokens/data_queue_obsolete.rb +121 -0
- data/spec/tokens/data_queue_spec.rb +111 -0
- data/spec/units_spec.rb +48 -0
- data/tcpn/model.rb +6 -0
- data/tcpn/model/add_route.rb +78 -0
- data/tcpn/model/application.rb +250 -0
- data/tcpn/model/cpu.rb +75 -0
- data/tcpn/model/map_data.rb +42 -0
- data/tcpn/model/network.rb +108 -0
- data/tcpn/model/register_event.rb +89 -0
- data/tcpn/model/stats.rb +46 -0
- metadata +221 -0
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RBSim::Tokens::DataQueue do
|
4
|
+
|
5
|
+
let(:apache1_first) { RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache1') }
|
6
|
+
let(:apache1_second) { RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache1') }
|
7
|
+
let(:apache1_third) { RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache1') }
|
8
|
+
let(:apache5_first) { RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache5') }
|
9
|
+
let(:apache3_first) { RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache3') }
|
10
|
+
|
11
|
+
describe "enqueues data for each process separatelly" do
|
12
|
+
subject do
|
13
|
+
queue = RBSim::Tokens::DataQueueToken.new
|
14
|
+
queue.put apache1_first
|
15
|
+
queue.put apache5_first
|
16
|
+
queue.put apache1_second
|
17
|
+
queue.put apache3_first
|
18
|
+
queue.put apache1_third
|
19
|
+
queue
|
20
|
+
end
|
21
|
+
|
22
|
+
it "has 3 data packages for apache1" do
|
23
|
+
expect(subject.get 'apache1').to eq apache1_first
|
24
|
+
expect(subject.get 'apache1').to eq apache1_second
|
25
|
+
expect(subject.get 'apache1').to eq apache1_third
|
26
|
+
expect(subject.get 'apache1').to be nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it "has 1 data package for apache5" do
|
30
|
+
expect(subject.get 'apache5').to eq apache5_first
|
31
|
+
expect(subject.get 'apache5').to be nil
|
32
|
+
end
|
33
|
+
|
34
|
+
it "has 1 data package for apache3" do
|
35
|
+
expect(subject.get 'apache3').to eq apache3_first
|
36
|
+
expect(subject.get 'apache3').to be nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it "has no data packages for apache0" do
|
40
|
+
expect(subject.get 'apache0').to be nil
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "collects queue lengths for processes" do
|
46
|
+
context "when putting something to the queue" do
|
47
|
+
subject do
|
48
|
+
queue = RBSim::Tokens::DataQueueToken.new
|
49
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache1')
|
50
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache5')
|
51
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache1')
|
52
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache3')
|
53
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache1')
|
54
|
+
queue
|
55
|
+
end
|
56
|
+
it "has 3 packages for apache1" do
|
57
|
+
expect(subject.length_for('apache1')).to eq 3
|
58
|
+
end
|
59
|
+
|
60
|
+
it "has 1 package for apache5" do
|
61
|
+
expect(subject.length_for('apache5')).to eq 1
|
62
|
+
end
|
63
|
+
|
64
|
+
it "has 1 package for apache3" do
|
65
|
+
expect(subject.length_for('apache3')).to eq 1
|
66
|
+
end
|
67
|
+
|
68
|
+
it "has no packages for apache333" do
|
69
|
+
expect(subject.length_for('apache333')).to eq 0
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when putting and getting from the queue" do
|
75
|
+
subject do
|
76
|
+
queue = RBSim::Tokens::DataQueueToken.new
|
77
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache0')
|
78
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache2')
|
79
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache2')
|
80
|
+
queue.get 'apache0'
|
81
|
+
queue.get 'apache2'
|
82
|
+
queue
|
83
|
+
end
|
84
|
+
|
85
|
+
it "has 1 package for apache2" do
|
86
|
+
expect(subject.length_for('apache2')).to eq 1
|
87
|
+
end
|
88
|
+
|
89
|
+
it "has no packages for apache0" do
|
90
|
+
expect(subject.length_for('apache0')).to eq 0
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "remembers last involved process" do
|
97
|
+
context "when putting" do
|
98
|
+
subject do
|
99
|
+
queue = RBSim::Tokens::DataQueueToken.new
|
100
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache0')
|
101
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache2')
|
102
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache1')
|
103
|
+
queue
|
104
|
+
end
|
105
|
+
its(:last_involved_queue) { should eq 'apache1' }
|
106
|
+
end
|
107
|
+
|
108
|
+
context "when getting" do
|
109
|
+
subject do
|
110
|
+
queue = RBSim::Tokens::DataQueueToken.new
|
111
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache0')
|
112
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache2')
|
113
|
+
queue.put RBSim::Tokens::DataToken.new(:node01, 'wget', size: 1024, to: 'apache1')
|
114
|
+
queue.get 'apache0'
|
115
|
+
queue
|
116
|
+
end
|
117
|
+
its(:last_involved_queue) { should eq 'apache0' }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RBSim::Tokens::DataQueue do
|
4
|
+
subject { RBSim::Tokens::DataQueue.new(:apache) }
|
5
|
+
|
6
|
+
let(:data_id) { 12332432 }
|
7
|
+
let(:other_data_id) { 23634657 }
|
8
|
+
|
9
|
+
let(:data1) do
|
10
|
+
data = RBSim::Tokens::Data.new(data_id, :node01, :apache1, to: :apache, size: 1024)
|
11
|
+
data.fragments = 3
|
12
|
+
data
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:data2) do
|
16
|
+
data = RBSim::Tokens::Data.new(data_id, :node01, :apache1, to: :apache, size: 1024)
|
17
|
+
data.fragments = 3
|
18
|
+
data
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:data3) do
|
22
|
+
data = RBSim::Tokens::Data.new(data_id, :node01, :apache1, to: :apache, size: 1024)
|
23
|
+
data.fragments = 3
|
24
|
+
data
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:other_data1) do
|
28
|
+
data = RBSim::Tokens::Data.new(other_data_id, :node01, :apache1, to: :apache, size: 1024)
|
29
|
+
data.fragments = 2
|
30
|
+
data
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:other_data2) do
|
34
|
+
data = RBSim::Tokens::Data.new(other_data_id, :node01, :apache1, to: :apache, size: 1024)
|
35
|
+
data.fragments = 2
|
36
|
+
data
|
37
|
+
end
|
38
|
+
|
39
|
+
shared_examples_for "empty queue" do
|
40
|
+
it "is empty" do
|
41
|
+
expect(subject.empty?).to be true
|
42
|
+
end
|
43
|
+
|
44
|
+
it "has length 0" do
|
45
|
+
expect(subject.length).to eq 0
|
46
|
+
end
|
47
|
+
|
48
|
+
it "dequeues nil" do
|
49
|
+
expect(subject.get).to be_nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "raises error when fragment count is not set" do
|
54
|
+
data = RBSim::Tokens::Data.new(other_data_id, :node01, :apache1, to: :apache, size: 1024)
|
55
|
+
expect { subject.put data }.to raise_error
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "until all fragments arrive" do
|
59
|
+
before :each do
|
60
|
+
subject.put data1
|
61
|
+
subject.put data2
|
62
|
+
subject.put other_data1
|
63
|
+
end
|
64
|
+
|
65
|
+
it_behaves_like "empty queue"
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "when all fragments arrive" do
|
70
|
+
before :each do
|
71
|
+
subject.put data1
|
72
|
+
subject.put data2
|
73
|
+
subject.put other_data1
|
74
|
+
subject.put data3
|
75
|
+
end
|
76
|
+
|
77
|
+
it "is not empty" do
|
78
|
+
expect(subject.empty?).to be false
|
79
|
+
end
|
80
|
+
|
81
|
+
it "has length 1" do
|
82
|
+
expect(subject.length).to eq 1
|
83
|
+
end
|
84
|
+
|
85
|
+
it "dequeues data" do
|
86
|
+
expect(subject.get.data_id).to eq data_id
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "when data is dequeued" do
|
90
|
+
before :each do
|
91
|
+
subject.get
|
92
|
+
end
|
93
|
+
|
94
|
+
it_behaves_like "empty queue"
|
95
|
+
|
96
|
+
|
97
|
+
describe "when another data arrives" do
|
98
|
+
before :each do
|
99
|
+
subject.put other_data2
|
100
|
+
end
|
101
|
+
|
102
|
+
it "dequeues data" do
|
103
|
+
expect(subject.get.data_id).to eq other_data_id
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
data/spec/units_spec.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Numeric units" do
|
4
|
+
|
5
|
+
let(:jiffies) { Numeric::RBSIM_JIFFIES_PER_SECOND }
|
6
|
+
|
7
|
+
shared_examples "has correct units" do
|
8
|
+
# volume units
|
9
|
+
its(:bits) { should eq subject }
|
10
|
+
its(:bytes) { should eq subject * 8 }
|
11
|
+
its(:in_bits) { should eq subject }
|
12
|
+
its(:in_bytes) { should eq subject / 8 }
|
13
|
+
|
14
|
+
# network units
|
15
|
+
its(:bps) { should eq subject.to_f / jiffies}
|
16
|
+
its(:Bps) { should eq subject.to_f * 8 / jiffies }
|
17
|
+
its(:in_bps) { should eq subject * jiffies }
|
18
|
+
its(:in_Bps) { should eq subject / 8 * jiffies }
|
19
|
+
|
20
|
+
# time units
|
21
|
+
its(:seconds) { should eq subject * jiffies }
|
22
|
+
its(:miliseconds) { should eq subject * jiffies / 1000 }
|
23
|
+
its(:microseconds) { should eq subject * jiffies / 1000000 }
|
24
|
+
its(:minutes) { should eq subject * jiffies * 60 }
|
25
|
+
its(:hours) { should eq subject * jiffies * 60 * 60 }
|
26
|
+
its(:days) { should eq subject * jiffies * 60 * 60 * 24 }
|
27
|
+
|
28
|
+
its(:in_seconds) { should eq subject / jiffies }
|
29
|
+
its(:in_miliseconds) { should eq subject * 1000 / jiffies }
|
30
|
+
its(:in_microseconds) { should eq subject * 1000 * 1000 / jiffies }
|
31
|
+
its(:in_minutes) { should be_within(1.0/jiffies).of( subject / (jiffies * 60) ) }
|
32
|
+
its(:in_hours) { should be_within(1.0/jiffies).of( subject / (jiffies * 60 * 60) ) }
|
33
|
+
its(:in_days) { should be_within(1.0/jiffies).of( subject / (jiffies * 60 * 60 * 24) ) }
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 128 do
|
37
|
+
include_examples 'has correct units'
|
38
|
+
end
|
39
|
+
|
40
|
+
describe 1.5 do
|
41
|
+
include_examples 'has correct units'
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 50000 do
|
45
|
+
include_examples 'has correct units'
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
data/tcpn/model.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# add route to data
|
2
|
+
# before network transmission
|
3
|
+
page 'add route' do
|
4
|
+
RouteNotFound = Class.new RuntimeError
|
5
|
+
|
6
|
+
data_for_network = place 'data for network'
|
7
|
+
routes = place 'routes'
|
8
|
+
data_with_route = place 'data with route'
|
9
|
+
data_to_receive = place 'data to receive', process_name: :process_name
|
10
|
+
|
11
|
+
class TCPNAddRouteToData
|
12
|
+
def initialize(binding)
|
13
|
+
@data = binding['data for network'].value
|
14
|
+
@queue = binding['data to receive'].value
|
15
|
+
@routes = binding['routes'].value
|
16
|
+
end
|
17
|
+
|
18
|
+
def with_route_token(clock)
|
19
|
+
if to_self?
|
20
|
+
nil
|
21
|
+
else
|
22
|
+
@data.route = route
|
23
|
+
{ ts: clock, val: @data }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_self_token(clock)
|
28
|
+
if to_self?
|
29
|
+
@queue.put @data
|
30
|
+
end
|
31
|
+
{ ts: clock, val: @queue }
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def to_self?
|
37
|
+
@data.src_node == @data.dst_node
|
38
|
+
end
|
39
|
+
|
40
|
+
def route
|
41
|
+
r = @routes.find @data.src_node, @data.dst_node
|
42
|
+
if r.nil?
|
43
|
+
raise RouteNotFound.new("from #{@data.src_node} to #{@data.dst_node}")
|
44
|
+
end
|
45
|
+
r
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
transition 'add_route' do
|
50
|
+
input data_for_network
|
51
|
+
input routes
|
52
|
+
input data_to_receive
|
53
|
+
|
54
|
+
output routes do |binding, clock|
|
55
|
+
binding['routes']
|
56
|
+
end
|
57
|
+
|
58
|
+
output data_with_route do |binding, clock|
|
59
|
+
TCPNAddRouteToData.new(binding).with_route_token(clock)
|
60
|
+
end
|
61
|
+
|
62
|
+
output data_to_receive do |binding, clock|
|
63
|
+
TCPNAddRouteToData.new(binding).to_self_token(clock)
|
64
|
+
end
|
65
|
+
|
66
|
+
sentry do |marking_for, clock, result|
|
67
|
+
marking_for['data for network'].each do |data|
|
68
|
+
marking_for['data to receive'].each(:process_name, data.value.dst) do |queue|
|
69
|
+
routes = marking_for['routes'].first
|
70
|
+
result << { 'data for network' => data,
|
71
|
+
'data to receive' => queue,
|
72
|
+
'routes' => routes }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
@@ -0,0 +1,250 @@
|
|
1
|
+
page 'application' do
|
2
|
+
process = timed_place 'process', { first_event: :first_event, user_event: :has_user_event?, name: :name }
|
3
|
+
data_to_send = place 'data to send'
|
4
|
+
mapping = place 'mapping'
|
5
|
+
data_to_receive = place 'data to receive', empty: :empty?
|
6
|
+
|
7
|
+
# model of CPU load by application logic
|
8
|
+
sub_page "cpu.rb"
|
9
|
+
|
10
|
+
# statistics
|
11
|
+
sub_page "stats.rb"
|
12
|
+
|
13
|
+
# new event from user (register_event statement)
|
14
|
+
sub_page "register_event.rb"
|
15
|
+
|
16
|
+
# Delay process execution for specified time.
|
17
|
+
# args: { time: time for which we should wait }
|
18
|
+
class EventDelayFor
|
19
|
+
def initialize(binding)
|
20
|
+
@process = binding['process'].value
|
21
|
+
@event = @process.serve_system_event :delay_for
|
22
|
+
end
|
23
|
+
|
24
|
+
def process_token(clock)
|
25
|
+
ts = clock + @event[:args][:time].to_i
|
26
|
+
{ val: @process, ts: ts }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
transition 'event::delay_for' do
|
31
|
+
input process
|
32
|
+
output process do |binding, clock|
|
33
|
+
EventDelayFor.new(binding).process_token(clock)
|
34
|
+
end
|
35
|
+
|
36
|
+
sentry do |marking_for, clock, result|
|
37
|
+
marking_for['process'].each(:first_event, :delay_for) do |p|
|
38
|
+
result << { 'process' => p }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
=begin
|
42
|
+
guard do |binding, clock|
|
43
|
+
binding[:process][:val].has_event? :delay_for
|
44
|
+
end
|
45
|
+
=end
|
46
|
+
end
|
47
|
+
|
48
|
+
transition 'event::serve_user' do
|
49
|
+
input process
|
50
|
+
|
51
|
+
output process do |binding, clock|
|
52
|
+
process = binding['process'].value
|
53
|
+
process.serve_user_event
|
54
|
+
process
|
55
|
+
end
|
56
|
+
|
57
|
+
sentry do |marking_for, clock, result|
|
58
|
+
marking_for['process'].each(:user_event, true) do |p|
|
59
|
+
result << { 'process' => p }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
=begin
|
64
|
+
guard do |binding, clock|
|
65
|
+
binding[:process][:val].has_user_event?
|
66
|
+
end
|
67
|
+
=end
|
68
|
+
end
|
69
|
+
|
70
|
+
transition 'event::send_data' do
|
71
|
+
input process
|
72
|
+
|
73
|
+
# Sending data to anothe node.
|
74
|
+
# args: { to: destination process name,
|
75
|
+
# size: volume of send data,
|
76
|
+
# type: type of send data (to use in HLModel),
|
77
|
+
# content: content of send data (to use in HLModel) }
|
78
|
+
class EventSendData
|
79
|
+
def initialize(bndng)
|
80
|
+
@process = bndng['process'].value
|
81
|
+
@event = @process.serve_system_event :send_data
|
82
|
+
fragments = [
|
83
|
+
@process.data_fragmentation,
|
84
|
+
@event[:args][:size].to_i / 1500.bytes
|
85
|
+
].min
|
86
|
+
fragments = 1 if fragments == 0
|
87
|
+
@data = fragments.times.map do
|
88
|
+
d = RBSim::Tokens::DataToken.new(self.object_id, @process.node, @process.name, @event[:args])
|
89
|
+
d.fragments = fragments
|
90
|
+
d
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def data_token(clock)
|
95
|
+
@data.map { |d| { val: d, ts: clock } }
|
96
|
+
end
|
97
|
+
|
98
|
+
def process_token(clock)
|
99
|
+
{ val: @process, ts: clock }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
output process do |binding, clock|
|
104
|
+
EventSendData.new(binding).process_token clock
|
105
|
+
end
|
106
|
+
|
107
|
+
output data_to_send do |binding, clock|
|
108
|
+
EventSendData.new(binding).data_token clock
|
109
|
+
end
|
110
|
+
|
111
|
+
sentry do |marking_for, clock, result|
|
112
|
+
marking_for['process'].each(:first_event, :send_data) do |p|
|
113
|
+
result << { 'process' => p }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
=begin
|
118
|
+
guard do |binding, clock|
|
119
|
+
binding[:process][:val].has_event? :send_data
|
120
|
+
end
|
121
|
+
=end
|
122
|
+
end
|
123
|
+
|
124
|
+
transition 'event::new_process' do
|
125
|
+
input process
|
126
|
+
input mapping
|
127
|
+
|
128
|
+
# Creating new process on the same node
|
129
|
+
# args: { program: program name for new process (optional),
|
130
|
+
# constructor: block called as constructor of new process (adds initial events),
|
131
|
+
# constructor_args: args passed to the constructor }
|
132
|
+
class EventNewProcess
|
133
|
+
def initialize(binding)
|
134
|
+
@process = binding['process'].value
|
135
|
+
@event = @process.serve_system_event :new_process
|
136
|
+
@new_process = @event[:args][:constructor].call @event[:args][:constructor_args]
|
137
|
+
@mapping = binding['mapping'].value
|
138
|
+
@mapping[@new_process.name] = @new_process.node
|
139
|
+
end
|
140
|
+
|
141
|
+
def process_tokens(clock)
|
142
|
+
[ { ts: clock, val: @process }, { ts: clock, val: @new_process } ]
|
143
|
+
end
|
144
|
+
|
145
|
+
def mapping_token(clock)
|
146
|
+
{ ts: clock, val: @mapping }
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
output process do |binding, clock|
|
151
|
+
EventNewProcess.new(binding).process_tokens(clock)
|
152
|
+
end
|
153
|
+
|
154
|
+
output mapping do |binding, clock|
|
155
|
+
EventNewProcess.new(binding).mapping_token(clock)
|
156
|
+
end
|
157
|
+
|
158
|
+
sentry do |marking_for, clock, result|
|
159
|
+
marking_for['process'].each(:first_event, :new_process) do |p|
|
160
|
+
mapping = marking_for['mapping'].first
|
161
|
+
result << { 'process' => p , 'mapping' => mapping}
|
162
|
+
end
|
163
|
+
end
|
164
|
+
=begin
|
165
|
+
guard do |binding, clock|
|
166
|
+
binding[:process][:val].has_event? :new_process
|
167
|
+
end
|
168
|
+
=end
|
169
|
+
end
|
170
|
+
|
171
|
+
transition 'event::data_received' do
|
172
|
+
input process
|
173
|
+
input data_to_receive
|
174
|
+
|
175
|
+
class EventDataReceived
|
176
|
+
def initialize(binding)
|
177
|
+
@process = binding['process'].value
|
178
|
+
@queue = binding['data to receive'].value
|
179
|
+
@data = @queue.get
|
180
|
+
@process.enqueue_event :data_received, @data
|
181
|
+
end
|
182
|
+
|
183
|
+
def process_token(clock)
|
184
|
+
{ ts: clock, val: @process }
|
185
|
+
end
|
186
|
+
|
187
|
+
def queue_token(clock)
|
188
|
+
{ ts: clock, val: @queue }
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
output process do |binding, clock|
|
193
|
+
EventDataReceived.new(binding).process_token(clock)
|
194
|
+
end
|
195
|
+
|
196
|
+
output data_to_receive do |binding, clock|
|
197
|
+
EventDataReceived.new(binding).queue_token(clock)
|
198
|
+
end
|
199
|
+
|
200
|
+
sentry do |marking_for, clock, result|
|
201
|
+
marking_for['data to receive'].each(:empty, false) do |queue|
|
202
|
+
marking_for['process'].each(:name, queue.value.process_name) do |process|
|
203
|
+
result << { 'process' => process, 'data to receive' => queue }
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
=begin
|
209
|
+
guard do |binding, clock|
|
210
|
+
process = binding[:process][:val]
|
211
|
+
data = binding[:queue][:val].get process.name
|
212
|
+
!data.nil?
|
213
|
+
end
|
214
|
+
=end
|
215
|
+
end
|
216
|
+
|
217
|
+
transition 'event::log' do
|
218
|
+
input process
|
219
|
+
|
220
|
+
# Log message from process
|
221
|
+
# args: log message
|
222
|
+
class EventLog
|
223
|
+
def initialize(binding)
|
224
|
+
@process = binding['process'].value
|
225
|
+
@event = @process.serve_system_event :log
|
226
|
+
end
|
227
|
+
|
228
|
+
def process_token(clock)
|
229
|
+
{ val: @process, ts: clock }
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
output process do |binding, clock|
|
234
|
+
EventLog.new(binding).process_token(clock)
|
235
|
+
end
|
236
|
+
|
237
|
+
sentry do |marking_for, clock, result|
|
238
|
+
marking_for['process'].each(:first_event, :log) do |p|
|
239
|
+
result << { 'process' => p }
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
=begin
|
244
|
+
guard do |binding, clock|
|
245
|
+
binding[:process][:val].has_event? :log
|
246
|
+
end
|
247
|
+
=end
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|