engineyard-serverside 1.5.21 → 1.5.23.ruby19

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.
Files changed (184) hide show
  1. data/lib/engineyard-serverside/cli.rb +39 -45
  2. data/lib/engineyard-serverside/configuration.rb +28 -4
  3. data/lib/engineyard-serverside/deploy.rb +5 -4
  4. data/lib/engineyard-serverside/logged_output.rb +3 -5
  5. data/lib/engineyard-serverside/server.rb +26 -2
  6. data/lib/engineyard-serverside/task.rb +2 -4
  7. data/lib/engineyard-serverside/version.rb +1 -1
  8. data/lib/engineyard-serverside.rb +8 -20
  9. data/spec/basic_deploy_spec.rb +1 -1
  10. data/spec/bundler_deploy_spec.rb +1 -1
  11. data/spec/nodejs_deploy_spec.rb +1 -1
  12. data/spec/rails31_deploy_spec.rb +1 -1
  13. data/spec/services_deploy_spec.rb +1 -1
  14. metadata +80 -233
  15. data/lib/vendor/dataflow/HISTORY +0 -52
  16. data/lib/vendor/dataflow/LICENSE +0 -19
  17. data/lib/vendor/dataflow/README.textile +0 -290
  18. data/lib/vendor/dataflow/Rakefile +0 -36
  19. data/lib/vendor/dataflow/dataflow/actor.rb +0 -22
  20. data/lib/vendor/dataflow/dataflow/equality.rb +0 -44
  21. data/lib/vendor/dataflow/dataflow/future_queue.rb +0 -24
  22. data/lib/vendor/dataflow/dataflow/port.rb +0 -54
  23. data/lib/vendor/dataflow/dataflow.rb +0 -124
  24. data/lib/vendor/dataflow/examples/barrier.rb +0 -9
  25. data/lib/vendor/dataflow/examples/data_driven.rb +0 -17
  26. data/lib/vendor/dataflow/examples/dataflow_http_gets.rb +0 -13
  27. data/lib/vendor/dataflow/examples/flow.rb +0 -20
  28. data/lib/vendor/dataflow/examples/future_http_gets.rb +0 -12
  29. data/lib/vendor/dataflow/examples/future_queue.rb +0 -11
  30. data/lib/vendor/dataflow/examples/instance_variables.rb +0 -15
  31. data/lib/vendor/dataflow/examples/laziness.rb +0 -9
  32. data/lib/vendor/dataflow/examples/local_variables.rb +0 -11
  33. data/lib/vendor/dataflow/examples/messages.rb +0 -26
  34. data/lib/vendor/dataflow/examples/port_http_gets.rb +0 -13
  35. data/lib/vendor/dataflow/examples/port_send.rb +0 -10
  36. data/lib/vendor/dataflow/examples/ring.rb +0 -21
  37. data/lib/vendor/dataflow/spec/actor_spec.rb +0 -28
  38. data/lib/vendor/dataflow/spec/anonymous_variables_spec.rb +0 -21
  39. data/lib/vendor/dataflow/spec/barrier_spec.rb +0 -25
  40. data/lib/vendor/dataflow/spec/by_need_spec.rb +0 -55
  41. data/lib/vendor/dataflow/spec/dataflow_spec.rb +0 -151
  42. data/lib/vendor/dataflow/spec/equality_spec.rb +0 -40
  43. data/lib/vendor/dataflow/spec/flow_spec.rb +0 -25
  44. data/lib/vendor/dataflow/spec/forker_spec.rb +0 -28
  45. data/lib/vendor/dataflow/spec/future_queue_spec.rb +0 -31
  46. data/lib/vendor/dataflow/spec/inspect_spec.rb +0 -19
  47. data/lib/vendor/dataflow/spec/need_later_spec.rb +0 -12
  48. data/lib/vendor/dataflow/spec/port_spec.rb +0 -26
  49. data/lib/vendor/dataflow/spec/spec.opts +0 -1
  50. data/lib/vendor/dataflow/spec/spec_helper.rb +0 -10
  51. data/lib/vendor/escape/Readme +0 -21
  52. data/lib/vendor/escape/doc_include/template/qualitysmith.rb +0 -631
  53. data/lib/vendor/json_pure/CHANGES +0 -166
  54. data/lib/vendor/json_pure/COPYING +0 -58
  55. data/lib/vendor/json_pure/GPL +0 -340
  56. data/lib/vendor/json_pure/README +0 -358
  57. data/lib/vendor/json_pure/Rakefile +0 -292
  58. data/lib/vendor/json_pure/TODO +0 -1
  59. data/lib/vendor/json_pure/VERSION +0 -1
  60. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkComparison.log +0 -52
  61. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast-autocorrelation.dat +0 -1000
  62. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast.dat +0 -1001
  63. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty-autocorrelation.dat +0 -900
  64. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty.dat +0 -901
  65. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe-autocorrelation.dat +0 -1000
  66. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe.dat +0 -1001
  67. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt.log +0 -261
  68. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast-autocorrelation.dat +0 -1000
  69. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast.dat +0 -1001
  70. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty-autocorrelation.dat +0 -1000
  71. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty.dat +0 -1001
  72. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe-autocorrelation.dat +0 -1000
  73. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe.dat +0 -1001
  74. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure.log +0 -262
  75. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator-autocorrelation.dat +0 -1000
  76. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator.dat +0 -1001
  77. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails.log +0 -82
  78. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkComparison.log +0 -34
  79. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser-autocorrelation.dat +0 -900
  80. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser.dat +0 -901
  81. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt.log +0 -81
  82. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser-autocorrelation.dat +0 -1000
  83. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser.dat +0 -1001
  84. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure.log +0 -82
  85. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser-autocorrelation.dat +0 -1000
  86. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser.dat +0 -1001
  87. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails.log +0 -82
  88. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser-autocorrelation.dat +0 -1000
  89. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser.dat +0 -1001
  90. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML.log +0 -82
  91. data/lib/vendor/json_pure/benchmarks/generator2_benchmark.rb +0 -222
  92. data/lib/vendor/json_pure/benchmarks/generator_benchmark.rb +0 -224
  93. data/lib/vendor/json_pure/benchmarks/ohai.json +0 -1216
  94. data/lib/vendor/json_pure/benchmarks/ohai.ruby +0 -1
  95. data/lib/vendor/json_pure/benchmarks/parser2_benchmark.rb +0 -251
  96. data/lib/vendor/json_pure/benchmarks/parser_benchmark.rb +0 -259
  97. data/lib/vendor/json_pure/bin/edit_json.rb +0 -9
  98. data/lib/vendor/json_pure/bin/prettify_json.rb +0 -75
  99. data/lib/vendor/json_pure/data/example.json +0 -1
  100. data/lib/vendor/json_pure/data/index.html +0 -38
  101. data/lib/vendor/json_pure/data/prototype.js +0 -4184
  102. data/lib/vendor/json_pure/ext/json/ext/generator/extconf.rb +0 -16
  103. data/lib/vendor/json_pure/ext/json/ext/generator/generator.c +0 -1323
  104. data/lib/vendor/json_pure/ext/json/ext/generator/generator.h +0 -170
  105. data/lib/vendor/json_pure/ext/json/ext/parser/extconf.rb +0 -15
  106. data/lib/vendor/json_pure/ext/json/ext/parser/parser.c +0 -1935
  107. data/lib/vendor/json_pure/ext/json/ext/parser/parser.h +0 -71
  108. data/lib/vendor/json_pure/ext/json/ext/parser/parser.rl +0 -792
  109. data/lib/vendor/json_pure/install.rb +0 -26
  110. data/lib/vendor/json_pure/tests/fixtures/fail1.json +0 -1
  111. data/lib/vendor/json_pure/tests/fixtures/fail10.json +0 -1
  112. data/lib/vendor/json_pure/tests/fixtures/fail11.json +0 -1
  113. data/lib/vendor/json_pure/tests/fixtures/fail12.json +0 -1
  114. data/lib/vendor/json_pure/tests/fixtures/fail13.json +0 -1
  115. data/lib/vendor/json_pure/tests/fixtures/fail14.json +0 -1
  116. data/lib/vendor/json_pure/tests/fixtures/fail18.json +0 -1
  117. data/lib/vendor/json_pure/tests/fixtures/fail19.json +0 -1
  118. data/lib/vendor/json_pure/tests/fixtures/fail2.json +0 -1
  119. data/lib/vendor/json_pure/tests/fixtures/fail20.json +0 -1
  120. data/lib/vendor/json_pure/tests/fixtures/fail21.json +0 -1
  121. data/lib/vendor/json_pure/tests/fixtures/fail22.json +0 -1
  122. data/lib/vendor/json_pure/tests/fixtures/fail23.json +0 -1
  123. data/lib/vendor/json_pure/tests/fixtures/fail24.json +0 -1
  124. data/lib/vendor/json_pure/tests/fixtures/fail25.json +0 -1
  125. data/lib/vendor/json_pure/tests/fixtures/fail27.json +0 -2
  126. data/lib/vendor/json_pure/tests/fixtures/fail28.json +0 -2
  127. data/lib/vendor/json_pure/tests/fixtures/fail3.json +0 -1
  128. data/lib/vendor/json_pure/tests/fixtures/fail4.json +0 -1
  129. data/lib/vendor/json_pure/tests/fixtures/fail5.json +0 -1
  130. data/lib/vendor/json_pure/tests/fixtures/fail6.json +0 -1
  131. data/lib/vendor/json_pure/tests/fixtures/fail7.json +0 -1
  132. data/lib/vendor/json_pure/tests/fixtures/fail8.json +0 -1
  133. data/lib/vendor/json_pure/tests/fixtures/fail9.json +0 -1
  134. data/lib/vendor/json_pure/tests/fixtures/pass1.json +0 -56
  135. data/lib/vendor/json_pure/tests/fixtures/pass15.json +0 -1
  136. data/lib/vendor/json_pure/tests/fixtures/pass16.json +0 -1
  137. data/lib/vendor/json_pure/tests/fixtures/pass17.json +0 -1
  138. data/lib/vendor/json_pure/tests/fixtures/pass2.json +0 -1
  139. data/lib/vendor/json_pure/tests/fixtures/pass26.json +0 -1
  140. data/lib/vendor/json_pure/tests/fixtures/pass3.json +0 -6
  141. data/lib/vendor/json_pure/tests/test_json.rb +0 -361
  142. data/lib/vendor/json_pure/tests/test_json_addition.rb +0 -162
  143. data/lib/vendor/json_pure/tests/test_json_encoding.rb +0 -68
  144. data/lib/vendor/json_pure/tests/test_json_fixtures.rb +0 -34
  145. data/lib/vendor/json_pure/tests/test_json_generate.rb +0 -122
  146. data/lib/vendor/json_pure/tests/test_json_rails.rb +0 -144
  147. data/lib/vendor/json_pure/tests/test_json_unicode.rb +0 -76
  148. data/lib/vendor/json_pure/tools/fuzz.rb +0 -139
  149. data/lib/vendor/json_pure/tools/server.rb +0 -61
  150. data/lib/vendor/open4/lib/open4.rb +0 -403
  151. data/lib/vendor/thor/CHANGELOG.rdoc +0 -89
  152. data/lib/vendor/thor/LICENSE +0 -20
  153. data/lib/vendor/thor/README.rdoc +0 -297
  154. data/lib/vendor/thor/Thorfile +0 -69
  155. data/lib/vendor/thor/bin/rake2thor +0 -86
  156. data/lib/vendor/thor/bin/thor +0 -6
  157. data/lib/vendor/thor/lib/thor/actions/create_file.rb +0 -103
  158. data/lib/vendor/thor/lib/thor/actions/directory.rb +0 -91
  159. data/lib/vendor/thor/lib/thor/actions/empty_directory.rb +0 -134
  160. data/lib/vendor/thor/lib/thor/actions/file_manipulation.rb +0 -223
  161. data/lib/vendor/thor/lib/thor/actions/inject_into_file.rb +0 -104
  162. data/lib/vendor/thor/lib/thor/actions.rb +0 -275
  163. data/lib/vendor/thor/lib/thor/base.rb +0 -540
  164. data/lib/vendor/thor/lib/thor/core_ext/file_binary_read.rb +0 -9
  165. data/lib/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +0 -75
  166. data/lib/vendor/thor/lib/thor/core_ext/ordered_hash.rb +0 -100
  167. data/lib/vendor/thor/lib/thor/error.rb +0 -30
  168. data/lib/vendor/thor/lib/thor/group.rb +0 -271
  169. data/lib/vendor/thor/lib/thor/invocation.rb +0 -180
  170. data/lib/vendor/thor/lib/thor/parser/argument.rb +0 -67
  171. data/lib/vendor/thor/lib/thor/parser/arguments.rb +0 -150
  172. data/lib/vendor/thor/lib/thor/parser/option.rb +0 -128
  173. data/lib/vendor/thor/lib/thor/parser/options.rb +0 -169
  174. data/lib/vendor/thor/lib/thor/parser.rb +0 -4
  175. data/lib/vendor/thor/lib/thor/rake_compat.rb +0 -66
  176. data/lib/vendor/thor/lib/thor/runner.rb +0 -314
  177. data/lib/vendor/thor/lib/thor/shell/basic.rb +0 -239
  178. data/lib/vendor/thor/lib/thor/shell/color.rb +0 -108
  179. data/lib/vendor/thor/lib/thor/shell.rb +0 -83
  180. data/lib/vendor/thor/lib/thor/task.rb +0 -102
  181. data/lib/vendor/thor/lib/thor/util.rb +0 -230
  182. data/lib/vendor/thor/lib/thor/version.rb +0 -3
  183. data/lib/vendor/thor/lib/thor.rb +0 -244
  184. data/lib/vendor/thor/thor.gemspec +0 -120
@@ -1,290 +0,0 @@
1
- h1. What's this?
2
-
3
- A Ruby library that adds Dataflow variables (inspired by the Oz
4
- language). Dataflow variables have the property that they can only
5
- be bound/assigned to once, or have an equivalent value as an existing
6
- assignment (see "unification").
7
-
8
- Dataflow variables must be declared before they are used, and can be
9
- passed around as data without actually being bound. If the variable
10
- gets used (in this library this means a method call) while being
11
- unbound then the currently executing thread will suspend.
12
-
13
- h1. What's the point?
14
-
15
- Ruby is Object Oriented (with the ability to mutate local, instance,
16
- class, and global variables, and even constants), and on top of that
17
- it has powerful reflection and meta-programming abilities. While these
18
- features are useful for certain problems, they are not within the
19
- declarative model. Staying in the declarative model gives one 2 advantages:
20
- # It is easy to reason about what the program does
21
- # Simple but powerful concurrency is possible
22
-
23
- Ruby, like many other OO languages, is facing the hurdles of taking
24
- advantage of the increase of processor cores within a simple parallel
25
- programming model. This library lets you program Ruby in the
26
- declarative concurrent model when you need to take advantage of multiple cores
27
- (assuming a Ruby implementation that uses native threads in one way or
28
- another).
29
-
30
- The trick to this kind of programming is binding variables from other
31
- threads. The nice thing is that many existing
32
- libraries/classes/methods can still be used, just avoid
33
- side-effects. Use regular Ruby threading to create threads, use
34
- "local" or "declare" to create new variables, and use "unify" to bind
35
- variables.
36
-
37
- h1. Install
38
-
39
- To install the latest release as a gem:
40
- <pre>sudo gem install dataflow</pre>
41
-
42
- h1. IRC
43
-
44
- <pre>#dataflow-gem @ freenode.net</pre>
45
-
46
- h1. Examples
47
-
48
- <pre>
49
- # Local variables
50
- include Dataflow
51
-
52
- local do |x, y, z|
53
- # notice how the order automatically gets resolved
54
- Thread.new { unify y, x + 2 }
55
- Thread.new { unify z, y + 3 }
56
- Thread.new { unify x, 1 }
57
- z #=> 6
58
- end
59
- </pre>
60
-
61
- <pre>
62
- # Module methods version
63
-
64
- Dataflow.local do |x, y, z|
65
- # notice how the order automatically gets resolved
66
- Thread.new { Dataflow.unify y, x + 2 }
67
- Thread.new { Dataflow.unify z, y + 3 }
68
- Thread.new { Dataflow.unify x, 1 }
69
- z #=> 6
70
- end
71
-
72
- # Note that a gobal Dataflow.declare is not supported
73
- </pre>
74
-
75
- <pre>
76
- # Instance variables
77
- class AnimalHouse
78
- include Dataflow
79
- declare :small_cat, :big_cat
80
-
81
- def fetch_big_cat
82
- Thread.new { unify big_cat, small_cat.upcase }
83
- unify small_cat, 'cat'
84
- big_cat
85
- end
86
- end
87
-
88
- AnimalHouse.new.fetch_big_cat #=> 'CAT'
89
- </pre>
90
-
91
- <pre>
92
- # Data-driven concurrency
93
- include Dataflow
94
-
95
- local do |stream, doubles, triples, squares|
96
- unify stream, Array.new(5) { Dataflow::Variable.new }
97
-
98
- Thread.new { unify doubles, stream.map {|n| n*2 } }
99
- Thread.new { unify triples, stream.map {|n| n*3 } }
100
- Thread.new { unify squares, stream.map {|n| n**2 } }
101
-
102
- Thread.new { stream.each {|x| unify x, rand(100) } }
103
-
104
- puts "original: #{stream.inspect}"
105
- puts "doubles: #{doubles.inspect}"
106
- puts "triples: #{triples.inspect}"
107
- puts "squares: #{squares.inspect}"
108
- end
109
- </pre>
110
-
111
- <pre>
112
- # By-need trigger laziness
113
- include Dataflow
114
-
115
- local do |x, y, z|
116
- Thread.new { unify y, by_need { 4 } }
117
- Thread.new { unify z, x + y }
118
- Thread.new { unify x, by_need { 3 } }
119
- z #=> 7
120
- end
121
- </pre>
122
-
123
- <pre>
124
- # Need-later future expressions
125
- include Dataflow
126
-
127
- local do |x, y, z|
128
- unify y, need_later { 4 }
129
- unify z, need_later { x + y }
130
- unify x, need_later { 3 }
131
- z #=> 7
132
- end
133
- </pre>
134
-
135
- <pre>
136
- include Dataflow
137
-
138
- # flow without parameters
139
- local do |x|
140
- flow do
141
- # other stuff
142
- unify x, 1337
143
- end
144
- x #=> 1337
145
- end
146
-
147
- # flow with an output parameter
148
- local do |x|
149
- flow(x) do
150
- # other stuff
151
- 1337
152
- end
153
- x #=> 1337
154
- end
155
- </pre>
156
-
157
- <pre>
158
- # barrier
159
- include Dataflow
160
-
161
- local do |lock1, lock2|
162
- flow { unify lock1, :unlocked }
163
- flow { unify lock2, :unlocked }
164
- barrier lock1, lock2
165
- puts "Barrier broken!"
166
- end
167
- </pre>
168
-
169
- <pre>
170
- # FutureQueue
171
- include Dataflow
172
-
173
- local do |queue, first, second|
174
- unify queue, Dataflow::FutureQueue.new
175
- queue.pop first
176
- queue.push 1
177
- queue.push 2
178
- queue.pop second
179
- first #=> 1
180
- second #=> 2
181
- end
182
- </pre>
183
-
184
- h1. Anonymous variables
185
-
186
- Sometimes you may want to pack a data structure with variables that do not need to be referenced with labels. For those cases anonymous variables are a good choice, here are some options:
187
-
188
- <pre>
189
- include Dataflow
190
- Array.new(3) { Dataflow::Variable.new }
191
- Array.new(3) { Dataflow.local }
192
- Array.new(3) { local }
193
- # and technically not anonymous
194
- Array.new(3) { local {|v| v } }
195
- </pre>
196
-
197
- h1. Debugging
198
-
199
- If you are having trouble and need to debug dataflow variables, simply call #inspect.
200
-
201
- If the variable has already been bound, it call inspect on its bound value like normal.However, if the variable is not bound yet then you will get a special string that contains the proxies #__id__ that you can use to track down which proxy objects are being passed around to which parts of your program:
202
- <pre>
203
- include Dataflow
204
- local do |my_var|
205
- my_var.inspect # => #<Dataflow::Variable:2637860 unbound>
206
- end
207
- </pre>
208
-
209
- h1. Fork method customization
210
-
211
- By default both #flow and #need_later use Thread.fork as their fork method. Youc an access the fork method via Dataflow.forker.
212
-
213
- If you would like to use a custom forker, simple set it to an object that responds to #call and internally calls a block passed to it (for an example of a synchronous forker, see spec/forker_spec.rb):
214
- <pre>
215
- Dataflow.forker = MyClass.method(:fork_with_threadpool)
216
- </pre>
217
-
218
- Also note that #flow is used interally by #need_later, in case you want to override that specifically.
219
-
220
- h1. Ports using Dataflow
221
-
222
- Ports are an extension of the declarative concurrent model to support nondeterministic behavior. They accomplish this through the use of a single state variable. Ports are also inspired by the Oz language.
223
-
224
- An Actor class in the style of Erlang message-passing processes is also provided. It makes use of the asynchronous behavior of ports, but otherwise uses no state variables.
225
-
226
- h1. Examples using Ports
227
-
228
- <pre>
229
- include Dataflow
230
-
231
- local do |port, stream|
232
- unify port, Dataflow::Port.new(stream)
233
- Thread.new {port.send 2}
234
- Thread.new {port.send 8}
235
- Thread.new {port.send 1024}
236
- stream.take(3).sort #=> [2, 8, 1024]
237
- end
238
- </pre>
239
-
240
- h1. Examples using Actors
241
-
242
- <pre>
243
- include Dataflow
244
-
245
- Ping = Actor.new {
246
- 3.times {
247
- case receive
248
- when "Ping"
249
- puts "Ping"
250
- Pong.send "Pong"
251
- end
252
- }
253
- }
254
-
255
- Pong = Actor.new {
256
- 3.times {
257
- case receive
258
- when "Pong"
259
- puts "Pong"
260
- Ping.send "Ping"
261
- end
262
- }
263
- }
264
-
265
- Actor.new { Ping.send "Ping" }
266
-
267
- Ping.join
268
- Pong.join
269
- </pre>
270
-
271
- h1. Equality
272
-
273
- Most Ruby implmentations will not use method calls for equality
274
- operations in base types/classes. This means equality between dataflow
275
- variables and those base types will not behave as expected. Require
276
- the following to get equality on base types that uses method calls,
277
- while still passing rubyspec:
278
-
279
- <pre>require "dataflow/equality"</pre>
280
-
281
- h1. References
282
-
283
- The basis of dataflow variables around a language is not common among
284
- popular languages and may be confusing to some. For an in-depth
285
- introduction to the Oz language and the techniques used in this
286
- library (including by_need triggers, port objects, and comparisons to Erlang message passing) see the book "Concepts, Techniques, and Models of Computer Programming":http://en.wikipedia.org/wiki/Concepts,_Techniques,_and_Models_of_Computer_Programming
287
-
288
- h1. Contributors
289
-
290
- larrytheliquid, amiller
@@ -1,36 +0,0 @@
1
- require "rubygems"
2
- require "rake/gempackagetask"
3
- require "rake/clean"
4
- require "spec/rake/spectask"
5
- require File.expand_path("./dataflow")
6
-
7
- Spec::Rake::SpecTask.new do |t|
8
- t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
9
- end
10
-
11
- desc "Run the specs"
12
- task :default => :spec
13
-
14
- spec = Gem::Specification.new do |s|
15
- s.name = "dataflow"
16
- s.rubyforge_project = s.name
17
- s.version = Dataflow::VERSION
18
- s.author = "Larry Diehl"
19
- s.email = "larrytheliquid" + "@" + "gmail.com"
20
- s.homepage = "http://github.com/larrytheliquid/dataflow"
21
- s.summary = "Dataflow concurrency for Ruby (inspired by the Oz language)"
22
- s.description = s.summary
23
- s.files = %w[LICENSE HISTORY Rakefile README.textile dataflow.rb] + Dir["dataflow/**/*"] + Dir["examples/**/*"]
24
- s.require_path = '.'
25
- s.test_files = Dir["spec/**/*"]
26
- end
27
-
28
- Rake::GemPackageTask.new(spec) do |package|
29
- package.gem_spec = spec
30
- end
31
-
32
- desc 'Install the package as a gem.'
33
- task :install => [:clean, :package] do
34
- gem = Dir['pkg/*.gem'].first
35
- sh "sudo gem install --no-rdoc --no-ri --local #{gem}"
36
- end
@@ -1,22 +0,0 @@
1
- module Dataflow
2
- class Actor < Thread
3
- def initialize(&block)
4
- @stream = Variable.new
5
- @port = Port.new(@stream)
6
- # Run this block in a new thread
7
- super { instance_eval &block }
8
- end
9
-
10
- def send message
11
- @port.send message
12
- end
13
-
14
- private
15
-
16
- def receive
17
- result = @stream.head
18
- @stream = @stream.tail
19
- result
20
- end
21
- end
22
- end
@@ -1,44 +0,0 @@
1
- # The purpose of this file is to make equality use method calls in as
2
- # many Ruby implementations as possible. If method calls are used,
3
- # then equality operations using dataflow variaables becomes seemless
4
- # I realize overriding core classes is a pretty nasty hack, but if you
5
- # have a better idea that also passes the equality_specs then I'm all
6
- # ears. Please run the rubyspec before committing changes to this file.
7
-
8
- class Object
9
- alias original_equality ==
10
-
11
- def ==(other)
12
- object_id == other.object_id
13
- end
14
- end
15
-
16
- class Symbol
17
- alias original_equality ==
18
-
19
- def ==(other)
20
- object_id == other.object_id
21
- end
22
- end
23
-
24
- class Regexp
25
- alias original_equality ==
26
-
27
- if /lol/.respond_to?(:encoding)
28
- def ==(other)
29
- other.is_a?(Regexp) &&
30
- casefold? == other.casefold? &&
31
- encoding == other.encoding &&
32
- options == other.options &&
33
- source == other.source
34
- end
35
- else
36
- def ==(other)
37
- other.is_a?(Regexp) &&
38
- casefold? == other.casefold? &&
39
- kcode == other.kcode &&
40
- options == other.options &&
41
- source == other.source
42
- end
43
- end
44
- end
@@ -1,24 +0,0 @@
1
- module Dataflow
2
- class FutureQueue
3
- include Dataflow
4
- declare :push_port, :pop_port
5
-
6
- def initialize
7
- local do |pushed, popped|
8
- unify push_port, Dataflow::Port.new(pushed)
9
- unify pop_port, Dataflow::Port.new(popped)
10
-
11
- Thread.new {
12
- loop do
13
- barrier pushed.head, popped.head
14
- unify popped.head, pushed.head
15
- pushed, popped = pushed.tail, popped.tail
16
- end
17
- }
18
- end
19
- end
20
-
21
- def push(x) push_port.send x end
22
- def pop(x) pop_port.send x end
23
- end
24
- end
@@ -1,54 +0,0 @@
1
- require 'thread'
2
-
3
- module Dataflow
4
- class Port
5
- include Dataflow
6
- LOCK = Mutex.new
7
-
8
- class Stream
9
- include Dataflow
10
- declare :head, :tail
11
-
12
- # Defining each allows us to use the enumerable mixin
13
- # None of the list can be garbage collected less the head is
14
- # garbage collected, so it will grow indefinitely even though
15
- # the function isn't recursive.
16
- include Enumerable
17
- def each
18
- s = self
19
- loop do
20
- yield s.head
21
- s = s.tail
22
- end
23
- end
24
-
25
- # Backported Enumerable#take for any 1.8.6 compatible Ruby
26
- unless method_defined?(:take)
27
- def take(num)
28
- result = []
29
- each_with_index do |x, i|
30
- return result if num == i
31
- result << x
32
- end
33
- end
34
- end
35
- end
36
-
37
- # Create a stream object, bind it to the input variable
38
- # Instance variables are necessary because @end is state
39
- def initialize(x)
40
- @end = Stream.new
41
- unify x, @end
42
- end
43
-
44
- # This needs to be synchronized because it uses @end as state
45
- def send value
46
- LOCK.synchronize do
47
- unify @end.head, value
48
- unify @end.tail, Stream.new
49
- @end = @end.tail
50
- end
51
- end
52
- end
53
- end
54
-
@@ -1,124 +0,0 @@
1
- require 'monitor'
2
-
3
- module Dataflow
4
- VERSION = "0.3.1"
5
- class << self
6
- attr_accessor :forker
7
- end
8
- self.forker = Thread.method(:fork)
9
-
10
- def self.included(cls)
11
- class << cls
12
- def declare(*readers)
13
- readers.each do |name|
14
- class_eval <<-RUBY
15
- def #{name}
16
- return @__dataflow_#{name}__ if defined? @__dataflow_#{name}__
17
- Variable::LOCK.synchronize { @__dataflow_#{name}__ ||= Variable.new }
18
- end
19
- RUBY
20
- end
21
- end
22
- end
23
- end
24
-
25
- def local(&block)
26
- return Variable.new unless block_given?
27
- vars = Array.new(block.arity) { Variable.new }
28
- block.call *vars
29
- end
30
-
31
- def unify(variable, value)
32
- variable.__unify__ value
33
- end
34
-
35
- def by_need(&block)
36
- Variable.new &block
37
- end
38
-
39
- def barrier(*variables)
40
- variables.each{|v| v.__wait__ }
41
- end
42
-
43
- def flow(output=nil, &block)
44
- Dataflow.forker.call do
45
- result = block.call
46
- unify output, result if output
47
- end
48
- end
49
-
50
- def need_later(&block)
51
- local do |future|
52
- flow(future) { block.call }
53
- future
54
- end
55
- end
56
-
57
- extend self
58
-
59
- # Note that this class uses instance variables directly rather than nicely
60
- # initialized instance variables in get/set methods for memory and
61
- # performance reasons
62
- class Variable
63
- # Briefly disable the warning we would get when undefining object_id.
64
- # We actually rely on the ability to do that, so...
65
- v = $VERBOSE; $VERBOSE = nil
66
- instance_methods.each { |m| undef_method(m) unless m =~ /^__|instance_eval/ }
67
- $VERBOSE = v # back to sanity
68
- LOCK = Monitor.new
69
- def initialize(&block) @__trigger__ = block if block_given? end
70
-
71
- # Lazy-load conditions to be nice on memory usage
72
- def __binding_condition__() @__binding_condition__ ||= LOCK.new_cond end
73
-
74
- def __unify__(value)
75
- LOCK.synchronize do
76
- __activate_trigger__ if @__trigger__
77
- if @__bound__
78
- return @__value__.__unify__(value) if @__value__.__dataflow__? rescue nil
79
- raise UnificationError, "#{@__value__.inspect} != #{value.inspect}" if self != value
80
- else
81
- @__value__ = value
82
- @__bound__ = true
83
- __binding_condition__.broadcast # wakeup all method callers
84
- @__binding_condition__ = nil # GC
85
- end
86
- end
87
- @__value__
88
- end
89
-
90
- def __activate_trigger__
91
- @__value__ = @__trigger__.call
92
- @__bound__ = true
93
- @__trigger__ = nil # GC
94
- end
95
-
96
- def __wait__
97
- LOCK.synchronize do
98
- unless @__bound__
99
- if @__trigger__
100
- __activate_trigger__
101
- else
102
- __binding_condition__.wait
103
- end
104
- end
105
- end unless @__bound__
106
- end
107
-
108
- def method_missing(name, *args, &block)
109
- return "#<Dataflow::Variable:#{__id__} unbound>" if !@__bound__ && name == :inspect
110
- __wait__
111
- @__value__.__send__(name, *args, &block)
112
- end
113
-
114
- def __dataflow__?
115
- true
116
- end
117
- end
118
-
119
- UnificationError = Class.new StandardError
120
- end
121
-
122
- require "#{File.dirname(__FILE__)}/dataflow/port"
123
- require "#{File.dirname(__FILE__)}/dataflow/actor"
124
- require "#{File.dirname(__FILE__)}/dataflow/future_queue"
@@ -1,9 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../dataflow"
2
- include Dataflow
3
-
4
- local do |lock1, lock2|
5
- flow { unify lock1, :unlocked }
6
- flow { unify lock2, :unlocked }
7
- barrier lock1, lock2
8
- puts "Barrier broken!"
9
- end
@@ -1,17 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../dataflow"
2
- include Dataflow
3
-
4
- local do |stream, doubles, triples, squares|
5
- unify stream, Array.new(5) { Dataflow::Variable.new }
6
-
7
- Thread.new { unify doubles, stream.map {|n| n*2 } }
8
- Thread.new { unify triples, stream.map {|n| n*3 } }
9
- Thread.new { unify squares, stream.map {|n| n**2 } }
10
-
11
- Thread.new { stream.each {|x| unify x, rand(100) } }
12
-
13
- puts "original: #{stream.inspect}"
14
- puts "doubles: #{doubles.inspect}"
15
- puts "triples: #{triples.inspect}"
16
- puts "squares: #{squares.inspect}"
17
- end
@@ -1,13 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../dataflow"
2
- require 'net/http'
3
- include Dataflow
4
-
5
- # Be gentle running this one
6
- Thread.abort_on_exception = true
7
- local do |stream, branding_occurences, number_of_mentions|
8
- unify stream, Array.new(10) { Dataflow::Variable.new }
9
- stream.each {|s| Thread.new(s) {|v| unify v, Net::HTTP.get_response(URI.parse("http://www.cuil.com/search?q=#{rand(1000)}")).body } }
10
- Thread.new { unify branding_occurences, stream.map {|http_body| http_body.scan /cuil/ } }
11
- Thread.new { unify number_of_mentions, branding_occurences.map {|occurences| occurences.length } }
12
- puts number_of_mentions.inspect
13
- end
@@ -1,20 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../dataflow"
2
- include Dataflow
3
-
4
- # flow without parameters
5
- local do |x|
6
- flow do
7
- # other stuff
8
- unify x, 1337
9
- end
10
- puts x
11
- end
12
-
13
- # flow with an output parameter
14
- local do |x|
15
- flow(x) do
16
- # other stuff
17
- 1337
18
- end
19
- puts x
20
- end
@@ -1,12 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../dataflow"
2
- require 'net/http'
3
- include Dataflow
4
-
5
- # Be gentle running this one
6
- Thread.abort_on_exception = true
7
- local do |stream, branding_occurences, number_of_mentions|
8
- unify stream, Array.new(10) { need_later { Net::HTTP.get_response(URI.parse("http://www.cuil.com/search?q=#{rand(1000)}")).body } }
9
- unify branding_occurences, need_later { stream.map {|http_body| http_body.scan /cuil/ } }
10
- unify number_of_mentions, need_later { branding_occurences.map {|occurences| occurences.length } }
11
- puts number_of_mentions.inspect
12
- end
@@ -1,11 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../dataflow"
2
- include Dataflow
3
-
4
- local do |queue, first, second|
5
- unify queue, Dataflow::FutureQueue.new
6
- queue.pop first
7
- queue.push 1
8
- queue.push 2
9
- queue.pop second
10
- puts "first: #{first}, second: #{second}"
11
- end
@@ -1,15 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../dataflow"
2
-
3
- class AnimalHouse
4
- include Dataflow
5
- declare :small_cat, :big_cat
6
-
7
- def fetch_big_cat
8
- Thread.new { unify big_cat, small_cat.upcase }
9
- unify small_cat, 'cat'
10
- big_cat
11
- end
12
- end
13
-
14
- puts AnimalHouse.new.fetch_big_cat
15
-