andromeda 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -29
- data/Gemfile.lock +27 -71
- data/README.md +4 -4
- data/ROADMAP.md +7 -8
- data/andromeda.gemspec +17 -1
- data/lib/andromeda.rb +34 -34
- data/lib/andromeda/atom.rb +76 -76
- data/lib/andromeda/cmd.rb +239 -239
- data/lib/andromeda/error.rb +1 -1
- data/lib/andromeda/guide.rb +2 -2
- data/lib/andromeda/guide_track.rb +2 -3
- data/lib/andromeda/id.rb +13 -13
- data/lib/andromeda/impl/class_attr.rb +2 -2
- data/lib/andromeda/impl/id.rb +89 -0
- data/lib/andromeda/impl/proto_plan.rb +34 -25
- data/lib/andromeda/impl_base.rb +48 -0
- data/lib/andromeda/kit.rb +169 -169
- data/lib/andromeda/map_reduce.rb +1 -1
- data/lib/andromeda/patch/array_bin_search.rb +83 -0
- data/lib/andromeda/plan.rb +4 -4
- data/lib/andromeda/spot.rb +3 -3
- data/lib/andromeda/sugar.rb +13 -13
- data/lib/andromeda/sync.rb +5 -3
- data/lib/andromeda/version.rb +1 -1
- data/yard_extensions/andromeda.rb +2 -2
- metadata +119 -6
data/Gemfile
CHANGED
@@ -1,30 +1,2 @@
|
|
1
1
|
source "http://rubygems.org"
|
2
|
-
|
3
|
-
gem 'json', '>=1.6.5'
|
4
|
-
gem 'atomic'
|
5
|
-
gem 'facter'
|
6
|
-
gem 'statval'
|
7
|
-
gem 'threadpool'
|
8
|
-
|
9
|
-
group :development do
|
10
|
-
gem 'rake'
|
11
|
-
gem 'yard'
|
12
|
-
gem 'irbtools'
|
13
|
-
end
|
14
|
-
|
15
|
-
group :test do
|
16
|
-
gem 'rspec', '2.6.0'
|
17
|
-
gem 'simplecov'
|
18
|
-
end
|
19
|
-
|
20
|
-
platforms :ruby do
|
21
|
-
gem 'redcarpet'
|
22
|
-
end
|
23
|
-
|
24
|
-
platforms :rbx do
|
25
|
-
gem 'redcarpet'
|
26
|
-
end
|
27
|
-
|
28
|
-
platforms :jruby do
|
29
|
-
gem 'maruku'
|
30
|
-
end
|
2
|
+
gemspec
|
data/Gemfile.lock
CHANGED
@@ -1,90 +1,46 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
andromeda (0.1.3)
|
5
|
+
atomic
|
6
|
+
facter
|
7
|
+
json
|
8
|
+
statval
|
9
|
+
threadpool
|
10
|
+
|
1
11
|
GEM
|
2
12
|
remote: http://rubygems.org/
|
3
13
|
specs:
|
4
|
-
atomic (1.0.
|
5
|
-
atomic (1.0.0-java)
|
6
|
-
awesome_print (1.0.2)
|
7
|
-
boson (1.1.1)
|
8
|
-
clipboard (1.0.1)
|
9
|
-
coderay (1.0.6)
|
14
|
+
atomic (1.0.1)
|
10
15
|
diff-lcs (1.1.3)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
paint (>= 0.8.1)
|
15
|
-
unicode-display_width (>= 0.1.1)
|
16
|
-
g (1.6.0)
|
17
|
-
ruby_gntp
|
18
|
-
hirb (0.6.2)
|
19
|
-
interactive_editor (0.0.10)
|
20
|
-
spoon (>= 0.0.1)
|
21
|
-
irbtools (1.2.2)
|
22
|
-
awesome_print (~> 1.0.2)
|
23
|
-
boson (~> 1.1.1)
|
24
|
-
clipboard (~> 1.0.1)
|
25
|
-
coderay (~> 1.0.5)
|
26
|
-
every_day_irb (>= 1.2.2)
|
27
|
-
fancy_irb (>= 0.7.2)
|
28
|
-
g (>= 1.5.0)
|
29
|
-
hirb (~> 0.6.1)
|
30
|
-
interactive_editor (>= 0.0.10)
|
31
|
-
method_locator (>= 0.0.4)
|
32
|
-
method_source (>= 0.7.0)
|
33
|
-
methodfinder (>= 1.2.5)
|
34
|
-
ori (~> 0.1.0)
|
35
|
-
paint (>= 0.8.4)
|
36
|
-
sketches (>= 0.1.1)
|
37
|
-
wirb (>= 0.4.2)
|
38
|
-
zucker (>= 12.1)
|
39
|
-
json (1.6.6)
|
40
|
-
json (1.6.6-java)
|
41
|
-
maruku (0.6.0)
|
42
|
-
syntax (>= 1.0.0)
|
43
|
-
method_locator (0.0.4)
|
44
|
-
method_source (0.7.1)
|
45
|
-
methodfinder (1.2.5)
|
46
|
-
multi_json (1.3.2)
|
47
|
-
ori (0.1.0)
|
48
|
-
paint (0.8.4)
|
16
|
+
facter (1.6.9)
|
17
|
+
json (1.7.3)
|
18
|
+
multi_json (1.3.5)
|
49
19
|
rake (0.9.2.2)
|
50
20
|
redcarpet (2.1.1)
|
51
|
-
rspec (2.
|
52
|
-
rspec-core (~> 2.
|
53
|
-
rspec-expectations (~> 2.
|
54
|
-
rspec-mocks (~> 2.
|
55
|
-
rspec-core (2.
|
56
|
-
rspec-expectations (2.
|
57
|
-
diff-lcs (~> 1.1.
|
58
|
-
rspec-mocks (2.
|
59
|
-
|
60
|
-
|
61
|
-
multi_json (~> 1.3)
|
21
|
+
rspec (2.10.0)
|
22
|
+
rspec-core (~> 2.10.0)
|
23
|
+
rspec-expectations (~> 2.10.0)
|
24
|
+
rspec-mocks (~> 2.10.0)
|
25
|
+
rspec-core (2.10.1)
|
26
|
+
rspec-expectations (2.10.0)
|
27
|
+
diff-lcs (~> 1.1.3)
|
28
|
+
rspec-mocks (2.10.1)
|
29
|
+
simplecov (0.6.4)
|
30
|
+
multi_json (~> 1.0)
|
62
31
|
simplecov-html (~> 0.5.3)
|
63
32
|
simplecov-html (0.5.3)
|
64
|
-
sketches (0.1.1)
|
65
|
-
spoon (0.0.1)
|
66
33
|
statval (0.1.2)
|
67
|
-
syntax (1.0.0)
|
68
34
|
threadpool (0.1.0.1)
|
69
|
-
|
70
|
-
wirb (0.4.2)
|
71
|
-
yard (0.7.5)
|
72
|
-
zucker (12.1)
|
35
|
+
yard (0.8.1)
|
73
36
|
|
74
37
|
PLATFORMS
|
75
|
-
java
|
76
38
|
ruby
|
77
39
|
|
78
40
|
DEPENDENCIES
|
79
|
-
|
80
|
-
facter
|
81
|
-
irbtools
|
82
|
-
json (>= 1.6.5)
|
83
|
-
maruku
|
41
|
+
andromeda!
|
84
42
|
rake
|
85
43
|
redcarpet
|
86
|
-
rspec
|
44
|
+
rspec
|
87
45
|
simplecov
|
88
|
-
statval
|
89
|
-
threadpool
|
90
46
|
yard
|
data/README.md
CHANGED
@@ -24,7 +24,7 @@ Below is an example that writes events to a file and reads them back such that t
|
|
24
24
|
r = Cmd::Reader.new path: '/tmp/some_file'
|
25
25
|
p = Cmd::Parser.new
|
26
26
|
t = Kit::Tee.new
|
27
|
-
s = Sync::
|
27
|
+
s = Sync::Bracket.new
|
28
28
|
# Connect the processing steps (Plans)
|
29
29
|
s >> r >> p >> t
|
30
30
|
# Enfore reader to run on a separate single thread
|
@@ -76,8 +76,8 @@ To sum up, plans are factory objects that describe the instantiation of concrete
|
|
76
76
|
### Quick Usage Example
|
77
77
|
|
78
78
|
class MyPlan < Andromeda::Plan
|
79
|
-
|
80
|
-
|
79
|
+
spot_attr :a, :b
|
80
|
+
spot_meth :alternative
|
81
81
|
|
82
82
|
def data_key(name, data) ; data end
|
83
83
|
|
@@ -135,7 +135,7 @@ Andromeda provides a small set of reserved default tags that should not be overw
|
|
135
135
|
|
136
136
|
#### Wating for event handling completion
|
137
137
|
|
138
|
-
Waiting for event handling completion may be achieved by utilizing a special wrapper plan (cf. Sync::
|
138
|
+
Waiting for event handling completion may be achieved by utilizing a special wrapper plan (cf. Sync::Bracket). This is implemented using an atomic counter (cf. Atom::Region).
|
139
139
|
|
140
140
|
#### Performance
|
141
141
|
|
data/ROADMAP.md
CHANGED
@@ -4,12 +4,12 @@ This document contains planning steps and ideas for the future of andromeda.
|
|
4
4
|
|
5
5
|
## Short-Term Todo's
|
6
6
|
|
7
|
-
* Test with macruby, figure out if rubinius pre-compilation should be added
|
8
|
-
* Convert old Pool code into Guards
|
9
|
-
* Convert Kit into Plans
|
10
|
-
* Convert Command into Plans, moving it into a submodule
|
7
|
+
* DONE Test with macruby, figure out if rubinius pre-compilation should be added, doesnt work
|
8
|
+
* DONE Convert old Pool code into Guards
|
9
|
+
* DONE Convert Kit into Plans
|
10
|
+
* DONE Convert Command into Plans, moving it into a submodule
|
11
11
|
* Test scope, tags, threading in IRB
|
12
|
-
* Subscopes
|
12
|
+
* Subscopes ?
|
13
13
|
|
14
14
|
### Write Test-Cases
|
15
15
|
|
@@ -23,7 +23,7 @@ around when andromeda is re-used by neoscout.
|
|
23
23
|
* Add high-level description to README.md
|
24
24
|
* Add examples to README.md
|
25
25
|
* Add link to yardocs to README.md as soon as that makes sense
|
26
|
-
* Figure out yardoc methods for documenting
|
26
|
+
* Figure out yardoc methods for documenting spot_meth and spot_attr
|
27
27
|
|
28
28
|
### Write a better DSL for connecting plans
|
29
29
|
|
@@ -69,5 +69,4 @@ on intern using the yet to be written Atom::* vars.
|
|
69
69
|
|
70
70
|
Add automatic distribution support.
|
71
71
|
|
72
|
-
It should not be that hard. In the end this is just a mildly interesting graph transformation on the topology, a bit of rewiring, and some support code to run stuff on remote machines. Ah maybe we just use capistrano for that. Of course, that would be static only. Dynamic job submission is a diffrerent story, as is at-most-once messaging (i.e. transactionality).
|
73
|
-
|
72
|
+
It should not be that hard. In the end this is just a mildly interesting graph transformation on the topology, a bit of rewiring, and some support code to run stuff on remote machines. Ah maybe we just use capistrano for that. Of course, that would be static only. Dynamic job submission is a diffrerent story, as is at-most-once messaging (i.e. transactionality).
|
data/andromeda.gemspec
CHANGED
@@ -5,7 +5,7 @@ require 'andromeda/version'
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = 'andromeda'
|
7
7
|
s.version = Andromeda::VERSION
|
8
|
-
s.summary = 'light
|
8
|
+
s.summary = 'light weight framework for complex event processing based on a dataflow DSL'
|
9
9
|
s.description = 'Andromeda is a light weight framework for complex event processing on multicore architectures. Andromeda users construct networks of plans that are interconnected via endpoint spots, describe how plans are scheduled onto threads, and process data by feeding data events to the resulting structure.'
|
10
10
|
s.author = 'Stefan Plantikow'
|
11
11
|
s.email = 'stefanp@moviepilot.com'
|
@@ -20,4 +20,20 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.bindir = 'script'
|
21
21
|
s.executables = `git ls-files -- script/*`.split("\n").map{ |f| File.basename(f) }
|
22
22
|
s.licenses = ['PUBLIC DOMAIN WITHOUT ANY WARRANTY']
|
23
|
+
|
24
|
+
s.add_dependency 'json'
|
25
|
+
s.add_dependency 'atomic'
|
26
|
+
s.add_dependency 'facter'
|
27
|
+
s.add_dependency 'statval'
|
28
|
+
s.add_dependency 'threadpool'
|
29
|
+
|
30
|
+
s.add_development_dependency 'rspec'
|
31
|
+
s.add_development_dependency 'simplecov'
|
32
|
+
s.add_development_dependency 'rake'
|
33
|
+
s.add_development_dependency 'yard'
|
34
|
+
|
35
|
+
case RUBY_ENGINE.to_sym
|
36
|
+
when :jruby then s.add_development_dependency 'maruku'
|
37
|
+
else s.add_development_dependency 'redcarpet'
|
38
|
+
end
|
23
39
|
end
|
data/lib/andromeda.rb
CHANGED
@@ -16,40 +16,40 @@ require 'andromeda/version'
|
|
16
16
|
|
17
17
|
module Andromeda
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
19
|
+
def self.files
|
20
|
+
f = []
|
21
|
+
f << 'andromeda/impl/to_s'
|
22
|
+
f << 'andromeda/impl/atom'
|
23
|
+
f << 'andromeda/impl/xor_id'
|
24
|
+
f << 'andromeda/impl/class_attr'
|
25
|
+
f << 'andromeda/impl/proto_plan'
|
26
|
+
|
27
|
+
f << 'andromeda/id'
|
28
|
+
f << 'andromeda/atom'
|
29
|
+
f << 'andromeda/error'
|
30
|
+
f << 'andromeda/copy_clone'
|
31
|
+
f << 'andromeda/guide_track'
|
32
|
+
f << 'andromeda/pool_guide'
|
33
|
+
|
34
|
+
f << 'andromeda/spot'
|
35
|
+
f << 'andromeda/plan'
|
36
|
+
f << 'andromeda/sync'
|
37
|
+
f << 'andromeda/sugar'
|
38
|
+
|
39
|
+
f << 'andromeda/kit'
|
40
|
+
f << 'andromeda/cmd'
|
41
|
+
f << 'andromeda/map_reduce'
|
42
|
+
f
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.load_relative(f)
|
46
|
+
path = "#{File.join(File.dirname(caller[0]), f)}.rb"
|
47
|
+
load path
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.reload!
|
51
|
+
files.each { |f| load_relative f }
|
52
|
+
end
|
53
53
|
|
54
54
|
end
|
55
55
|
|
data/lib/andromeda/atom.rb
CHANGED
@@ -1,105 +1,105 @@
|
|
1
1
|
module Andromeda
|
2
2
|
|
3
|
-
|
3
|
+
module Impl
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
class Atom < Atomic
|
6
|
+
include To_S
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
def initialize(init_val = nil)
|
9
|
+
super init_val
|
10
|
+
end
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
def empty? ; value.nil? end
|
13
|
+
def full? ; ! value.nil? end
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
def to_short_s ; "(#{To_S.short_s(value)})" end
|
16
|
+
alias_method :inspect, :to_s
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
def wait_while(&test)
|
19
|
+
while test.call(value) ; Thread::pass end
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
def wait_until_eq(val = nil)
|
23
|
+
raise ArgumentError unless val.kind_of?(Fixnum)
|
24
|
+
wait_while { |v| v != val }
|
25
|
+
end
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
def wait_until_ne(val = nil)
|
28
|
+
raise ArgumentError unless val.kind_of?(Fixnum)
|
29
|
+
wait_while { |v| v == val }
|
30
|
+
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
def wait_until_empty?
|
33
|
+
wait_until_eq nil
|
34
|
+
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
def wait_until_full?
|
37
|
+
wait_until_ne nil
|
38
|
+
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
def with_value
|
41
|
+
update { |v| yield v ; v }
|
42
|
+
end
|
43
|
+
end
|
44
44
|
|
45
|
-
|
45
|
+
end
|
46
46
|
|
47
|
-
|
47
|
+
module Atom
|
48
48
|
|
49
|
-
|
50
|
-
|
49
|
+
class Region
|
50
|
+
include Impl::To_S
|
51
51
|
|
52
|
-
|
53
|
-
|
52
|
+
def to_short_s ; "(#{Impl::To_S.short_s(value)})" end
|
53
|
+
alias_method :inspect, :to_s
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
def initialize(init_value = 0)
|
56
|
+
init_value = init_value[:init_value].to_i if init_value.kind_of?(Hash)
|
57
|
+
raise ArgumentError unless init_value.kind_of?(Fixnum)
|
58
|
+
@count = Impl::Atom.new init_value
|
59
|
+
end
|
60
60
|
|
61
|
-
|
61
|
+
alias_method :inspect, :to_s
|
62
62
|
|
63
|
-
|
63
|
+
def value ; @count.value end
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
65
|
+
def enter(amount = 1)
|
66
|
+
raise ArgumentError unless amount.kind_of?(Fixnum)
|
67
|
+
raise ArgumentError unless amount >= 0
|
68
|
+
@count.update { |v| v + amount }
|
69
|
+
end
|
70
70
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
def leave(amount = 1)
|
72
|
+
raise ArgumentError unless amount >= 0
|
73
|
+
raise ArgumentError unless amount.kind_of?(Fixnum)
|
74
|
+
@count.update { |v| v - amount }
|
75
|
+
end
|
76
76
|
|
77
|
-
|
78
|
-
|
77
|
+
def wait_until_eq(val) ; @count.wait_until_eq(val) end
|
78
|
+
end
|
79
79
|
|
80
|
-
|
81
|
-
|
80
|
+
class Var < Impl::Atom
|
81
|
+
end
|
82
82
|
|
83
|
-
|
84
|
-
|
83
|
+
class FillOnce < Var
|
84
|
+
def empty! ; super.update nil end
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
86
|
+
def update(v)
|
87
|
+
super.update do |o|
|
88
|
+
raise ArgumentError, 'Attempt to refill FillOnce' if o
|
89
|
+
v
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
93
|
|
94
|
-
|
95
|
-
|
94
|
+
class Combiner < Var
|
95
|
+
attr_reader :combiner
|
96
96
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
97
|
+
def update(v)
|
98
|
+
super.update do |o|
|
99
|
+
if combiner then combiner.call o, v else v end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
103
|
|
104
|
-
|
104
|
+
end
|
105
105
|
end
|