normandy 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dfc72d3679cf96efa105ddbb59286e2adec616f3
4
+ data.tar.gz: 9d6358833bbb0d8ae0316f21abc282c5f7e3874c
5
+ SHA512:
6
+ metadata.gz: 55bd93f35b6dd626873bf18c4978975fa1c405a48f3b77619486a8344e744b611bcc8768c98228bbfc87057fea9bc2401d9b08e9d67279b48194b6fce3e48c48
7
+ data.tar.gz: c0e4a3235b16b9bed94801bf635702da18b6b2b489baca71881092ce849f8188df8a0ba451997cb7df8f2c4f57833868434183f08b11049cf88962a1e4fc0856
@@ -0,0 +1,189 @@
1
+ class Channel
2
+ class Closed < StandardError; end
3
+
4
+ def initialize(size = nil)
5
+ @q = size ? SizedQueue.new(size) : Queue.new
6
+ @closed = false
7
+ @mutex = Mutex.new
8
+ @waiting = []
9
+ end
10
+
11
+ private def lock!(&block)
12
+ @mutex.synchronize(&block)
13
+ end
14
+
15
+ private def wait!
16
+ @waiting << Thread.current
17
+ @mutex.sleep
18
+ end
19
+
20
+ private def next!
21
+ loop do
22
+ thr = @waiting.shift
23
+ break if thr.nil?
24
+ next unless thr.alive?
25
+ break thr.wakeup
26
+ end
27
+ end
28
+
29
+ private def all!
30
+ @waiting.dup.each { next! }
31
+ end
32
+
33
+ def recv
34
+ lock! do
35
+ loop do
36
+ closed! if closed? && @q.empty?
37
+ wait! && next if @q.empty?
38
+ break @q.pop
39
+ end
40
+ end
41
+ end
42
+ alias_method :pop, :recv
43
+
44
+ def send(val)
45
+ lock! do
46
+ fail Closed if closed?
47
+ @q << val
48
+ next!
49
+ end
50
+ end
51
+ alias_method :push, :send
52
+ alias_method :<<, :push
53
+
54
+ def close
55
+ lock! do
56
+ return if closed?
57
+ @closed = true
58
+ all!
59
+ end
60
+ end
61
+
62
+ def closed?
63
+ @closed
64
+ end
65
+
66
+ private def closed!
67
+ fail Closed
68
+ end
69
+
70
+ def each
71
+ return enum_for(:each) unless block_given?
72
+
73
+ loop do
74
+ begin
75
+ e = recv
76
+ rescue Channel::Closed
77
+ return
78
+ else
79
+ yield e
80
+ end
81
+ end
82
+ end
83
+
84
+ def receive_only!
85
+ ReceiveOnly.new(self)
86
+ end
87
+ alias_method :r!, :receive_only!
88
+
89
+ def send_only!
90
+ SendOnly.new(self)
91
+ end
92
+ alias_method :s!, :send_only!
93
+
94
+ class << self
95
+ def select(*channels)
96
+ selector = new
97
+ threads = channels.map do |c|
98
+ Thread.new { selector << [c.recv, c] }
99
+ end
100
+ yield selector.recv
101
+ ensure
102
+ selector.close
103
+ threads.each(&:kill).each(&:join)
104
+ end
105
+ end
106
+
107
+ class Direction < StandardError; end
108
+ class Conversion < StandardError; end
109
+
110
+ class ReceiveOnly
111
+ def initialize(channel)
112
+ @channel = channel
113
+ end
114
+
115
+ def recv
116
+ @channel.recv
117
+ end
118
+ alias_method :pop, :recv
119
+
120
+ def send(_)
121
+ fail Direction, 'receive only'
122
+ end
123
+ alias_method :push, :send
124
+ alias_method :<<, :push
125
+
126
+ def close
127
+ @channel.close
128
+ end
129
+
130
+ def closed?
131
+ @channel.closed?
132
+ end
133
+
134
+ def receive_only!
135
+ self
136
+ end
137
+ alias_method :r!, :receive_only!
138
+
139
+ def send_only!
140
+ fail Conversion, 'receive only'
141
+ end
142
+ alias_method :s!, :send_only!
143
+
144
+ def hash
145
+ @channel.hash
146
+ end
147
+ end
148
+
149
+ class SendOnly
150
+ def initialize(channel)
151
+ @channel = channel
152
+ end
153
+
154
+ def recv
155
+ fail Direction, 'send only'
156
+ end
157
+ alias_method :pop, :recv
158
+
159
+ def send(val)
160
+ @channel.send(val)
161
+ end
162
+ alias_method :push, :send
163
+ alias_method :<<, :push
164
+
165
+ def close
166
+ @channel.close
167
+ end
168
+
169
+ def closed?
170
+ @channel.closed?
171
+ end
172
+
173
+ def receive_only!
174
+ fail Conversion, 'send only'
175
+ end
176
+ alias_method :r!, :receive_only!
177
+
178
+ def send_only!
179
+ self
180
+ end
181
+ alias_method :s!, :send_only!
182
+
183
+ def hash
184
+ @channel.hash
185
+ end
186
+ end
187
+ end
188
+
189
+ require 'channel/runtime'
@@ -0,0 +1,15 @@
1
+ require 'thread'
2
+
3
+ module Channel::Runtime
4
+ module_function
5
+
6
+ def go(prc, *args)
7
+ Thread.new { prc.call(*args) }
8
+ end
9
+ end
10
+
11
+ module Kernel
12
+ def go(prc, *args)
13
+ Channel::Runtime.go(prc, *args)
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ class Channel::Timer
2
+ attr_reader :channel
3
+
4
+ def initialize(delay)
5
+ @channel = Channel.new(1)
6
+ @prc = -> { sleep delay; channel << Time.now }
7
+ start
8
+ end
9
+
10
+ def start
11
+ Channel::Runtime.go @prc
12
+ end
13
+
14
+ def self.after(delay)
15
+ new(delay).channel
16
+ end
17
+ end
@@ -0,0 +1,41 @@
1
+ class WaitGroup
2
+ def initialize
3
+ @mutex = Mutex.new
4
+ @count = 0
5
+ @waiting = []
6
+ end
7
+
8
+ def add(delta)
9
+ sync! do
10
+ @count += delta
11
+ fail 'negative WaitGroup counter' if @count < 0
12
+ if @waiting.any? && delta > 0 && @count == delta
13
+ fail 'misuse: add called concurrently with wait'
14
+ end
15
+ wake!
16
+ end
17
+ end
18
+
19
+ def done
20
+ add(-1)
21
+ end
22
+
23
+ private def done?
24
+ @count == 0
25
+ end
26
+
27
+ def wait
28
+ sync! do
29
+ @waiting << Thread.current
30
+ @mutex.sleep until done?
31
+ end
32
+ end
33
+
34
+ private def wake!
35
+ @waiting.each { |t| t.wakeup if t.alive? }
36
+ end
37
+
38
+ private def sync!(&block)
39
+ @mutex.synchronize(&block)
40
+ end
41
+ end
@@ -0,0 +1 @@
1
+ require 'channel'
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: normandy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Loic Nageleisen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: test-unit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Share memory by communicating
70
+ email: loic.nageleisen@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/channel.rb
76
+ - lib/channel/runtime.rb
77
+ - lib/channel/timer.rb
78
+ - lib/channel/waitgroup.rb
79
+ - lib/normandy.rb
80
+ homepage: https://github.com/lloeki/normandy
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.5.1
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Channels, CSP style
104
+ test_files: []