pylon 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/pylon/log.rb ADDED
@@ -0,0 +1,24 @@
1
+ #
2
+ # Author:: AJ Christensen (<aj@junglist.gen.nz>)
3
+ # Copyright:: Copyright (c) 2011 AJ Christensen
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or#implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ require "mixlib/log"
19
+
20
+ class Pylon
21
+ class Log
22
+ extend Mixlib::Log
23
+ end
24
+ end
data/lib/pylon/node.rb ADDED
@@ -0,0 +1,147 @@
1
+ # Author:: AJ Christensen (<aj@junglist.gen.nz>)
2
+ # Copyright:: Copyright (c) 2011 AJ Christensen
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or#implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ require "uuidtools"
18
+ require "ffi-rzmq"
19
+ require "thread"
20
+ require "json"
21
+
22
+ class Pylon
23
+ class Node
24
+
25
+ attr_accessor :uuid, :weight, :timestamp, :context
26
+ attr_reader :unicast_endpoint, :multicast_endpoint
27
+
28
+ def initialize(json=nil)
29
+ @context = ZMQ::Context.new(1)
30
+ end
31
+
32
+ def unicast_endpoint(arg=nil)
33
+ if arg != nil
34
+ @unicast_endpoint = arg
35
+ else
36
+ @unicast_endpoint ||= "tcp://#{Pylon::Config[:tcp_address]}:#{Pylon::Config[:tcp_port]}"
37
+ end
38
+ end
39
+
40
+ def multicast_endpoint(arg=nil)
41
+ if arg != nil
42
+ @multicast_endpoint = arg
43
+ else
44
+ @multicast_endpoint ||= "epgm://#{Pylon::Config[:interface]};#{Pylon::Config[:multicast_address]}:#{Pylon::Config[:multicast_port]}"
45
+ end
46
+ end
47
+
48
+ def weight(arg=nil)
49
+ if arg != nil
50
+ @weight = arg
51
+ else
52
+ @weight ||= (srand; rand * Pylon::Config[:maximum_weight] % Pylon::Config[:maximum_weight]).to_i
53
+ end
54
+ end
55
+
56
+ def timestamp(arg=nil)
57
+ if arg != nil
58
+ @timestamp = arg
59
+ else
60
+ @timestamp ||= Time.now.to_i
61
+ end
62
+ end
63
+
64
+ include Comparable
65
+ def <=>(node)
66
+ weight <=> node.weight
67
+ end
68
+
69
+ def uuid(arg=nil)
70
+ if arg != nil
71
+ @uuid = UUIDTools::UUID.parse(arg)
72
+ else
73
+ @uuid ||= random_uuid
74
+ end
75
+ end
76
+
77
+ def random_uuid
78
+ UUIDTools::UUID.timestamp_create
79
+ end
80
+
81
+ def unicast_announcer
82
+ Thread.new do
83
+ Log.debug "unicast_announcer: zeromq pub socket announcer starting up on #{unicast_endpoint}"
84
+ pub_socket = context.socket ZMQ::PUB
85
+ pub_socket.setsockopt ZMQ::IDENTITY, "node"
86
+ pub_socket.bind unicast_endpoint
87
+ loop do
88
+ sleep_after_announce = Pylon::Config[:sleep_after_announce]
89
+ Log.debug "#{self}: unicast announcing then sleeping #{sleep_after_announce} secs"
90
+ pub_socket.send_string uuid.to_s, ZMQ::SNDMORE
91
+ pub_socket.send_string self.to_json
92
+ #Thread.pass
93
+ sleep sleep_after_announce
94
+ end
95
+
96
+ end
97
+ end
98
+
99
+ def multicast_announcer
100
+ Thread.new do
101
+ Log.debug "multicast_announcer: zeromq pub socket announcer starting up on #{multicast_endpoint}"
102
+ pub_socket = context.socket ZMQ::PUB
103
+ pub_socket.setsockopt ZMQ::IDENTITY, "node"
104
+ pub_socket.setsockopt ZMQ::RATE, 1000
105
+ pub_socket.setsockopt ZMQ::MCAST_LOOP, Pylon::Config[:multicast_loopback]
106
+ pub_socket.connect multicast_endpoint
107
+ loop do
108
+ sleep_after_announce = Pylon::Config[:sleep_after_announce]
109
+ Log.debug "#{self}: announcing then sleeping #{sleep_after_announce} secs"
110
+ pub_socket.send_string uuid.to_s, ZMQ::SNDMORE
111
+ pub_socket.send_string self.to_json
112
+ #Thread.pass
113
+ sleep sleep_after_announce
114
+ end
115
+ end
116
+ end
117
+
118
+ def to_s
119
+ "node[#{uuid}/#{weight}]"
120
+ end
121
+
122
+ def to_hash
123
+ {
124
+ "json_class" => self.class.name,
125
+ "uuid" => @uuid,
126
+ "weight" => @weight,
127
+ "unicast_endpoint" => @unicast_endpoint,
128
+ "timestamp" => Time.now.to_i
129
+ }
130
+ end
131
+
132
+ def to_json(*a)
133
+ to_hash.to_json(*a)
134
+ end
135
+
136
+ def self.json_create(json)
137
+ Log.debug "json_create: trying to create pylon::node object from json: #{json}"
138
+ node = new(json)
139
+ node.uuid(json["uuid"])
140
+ node.weight json["weight"]
141
+ node.unicast_endpoint json["unicast_endpoint"]
142
+ node.timestamp json["timestamp"]
143
+ Log.debug "#{node}: created from json succesfully"
144
+ node
145
+ end
146
+ end
147
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'minitest/unit'
11
+
12
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ require 'boss'
15
+
16
+ class MiniTest::Unit::TestCase
17
+ end
18
+
19
+ MiniTest::Unit.autorun
data/test/test_boss.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestBoss < MiniTest::Unit::TestCase
4
+ def test_something_for_real
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,227 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pylon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - AJ Christensen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-18 00:00:00.000000000 +12:00
13
+ default_executable: pylon
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ffi-rzmq
17
+ requirement: &2157541480 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 0.8.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2157541480
26
+ - !ruby/object:Gem::Dependency
27
+ name: mixlib-log
28
+ requirement: &2157540240 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *2157540240
37
+ - !ruby/object:Gem::Dependency
38
+ name: mixlib-cli
39
+ requirement: &2157539040 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *2157539040
48
+ - !ruby/object:Gem::Dependency
49
+ name: mixlib-config
50
+ requirement: &2157538060 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *2157538060
59
+ - !ruby/object:Gem::Dependency
60
+ name: uuidtools
61
+ requirement: &2157537320 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: 2.1.2
67
+ type: :runtime
68
+ prerelease: false
69
+ version_requirements: *2157537320
70
+ - !ruby/object:Gem::Dependency
71
+ name: json
72
+ requirement: &2157536540 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: *2157536540
81
+ - !ruby/object:Gem::Dependency
82
+ name: minitest
83
+ requirement: &2157535700 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: *2157535700
92
+ - !ruby/object:Gem::Dependency
93
+ name: bundler
94
+ requirement: &2157534600 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ~>
98
+ - !ruby/object:Gem::Version
99
+ version: 1.0.0
100
+ type: :development
101
+ prerelease: false
102
+ version_requirements: *2157534600
103
+ - !ruby/object:Gem::Dependency
104
+ name: jeweler
105
+ requirement: &2157533720 !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 1.6.4
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: *2157533720
114
+ - !ruby/object:Gem::Dependency
115
+ name: rcov
116
+ requirement: &2157532940 !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ type: :development
123
+ prerelease: false
124
+ version_requirements: *2157532940
125
+ - !ruby/object:Gem::Dependency
126
+ name: vagrant
127
+ requirement: &2157511540 !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ! '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: *2157511540
136
+ - !ruby/object:Gem::Dependency
137
+ name: virtualbox
138
+ requirement: &2157510440 !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ type: :development
145
+ prerelease: false
146
+ version_requirements: *2157510440
147
+ description: leader election with zeromq for ruby using widely available leader election
148
+ algorithms, similar to gen_leader erlang project in essence
149
+ email: aj@junglist.gen.nz
150
+ executables:
151
+ - pylon
152
+ extensions: []
153
+ extra_rdoc_files:
154
+ - LICENSE
155
+ - README.org
156
+ files:
157
+ - .document
158
+ - Gemfile
159
+ - Gemfile.lock
160
+ - LICENSE
161
+ - NOTICE
162
+ - README.org
163
+ - Rakefile
164
+ - Vagrantfile
165
+ - bin/pylon
166
+ - cookbooks/pylon/README.rdoc
167
+ - cookbooks/pylon/metadata.rb
168
+ - cookbooks/pylon/recipes/default.rb
169
+ - lib/pylon.rb
170
+ - lib/pylon/application.rb
171
+ - lib/pylon/config.rb
172
+ - lib/pylon/daemon.rb
173
+ - lib/pylon/elector.rb
174
+ - lib/pylon/log.rb
175
+ - lib/pylon/node.rb
176
+ - test/helper.rb
177
+ - test/test_boss.rb
178
+ - vendor/cache/archive-tar-minitar-0.5.2.gem
179
+ - vendor/cache/erubis-2.7.0.gem
180
+ - vendor/cache/ffi-1.0.9.gem
181
+ - vendor/cache/ffi-rzmq-0.8.2.gem
182
+ - vendor/cache/git-1.2.5.gem
183
+ - vendor/cache/i18n-0.5.0.gem
184
+ - vendor/cache/jeweler-1.6.4.gem
185
+ - vendor/cache/json-1.5.3.gem
186
+ - vendor/cache/minitest-2.6.0.gem
187
+ - vendor/cache/mixlib-cli-1.2.2.gem
188
+ - vendor/cache/mixlib-config-1.1.2.gem
189
+ - vendor/cache/mixlib-log-1.3.0.gem
190
+ - vendor/cache/net-scp-1.0.4.gem
191
+ - vendor/cache/net-ssh-2.1.4.gem
192
+ - vendor/cache/rake-0.9.2.gem
193
+ - vendor/cache/rcov-0.9.10.gem
194
+ - vendor/cache/thor-0.14.6.gem
195
+ - vendor/cache/uuidtools-2.1.2.gem
196
+ - vendor/cache/vagrant-0.8.2.gem
197
+ - vendor/cache/virtualbox-0.9.1.gem
198
+ has_rdoc: true
199
+ homepage: http://github.com/fujin/pylon
200
+ licenses:
201
+ - APLv2
202
+ post_install_message:
203
+ rdoc_options: []
204
+ require_paths:
205
+ - lib
206
+ required_ruby_version: !ruby/object:Gem::Requirement
207
+ none: false
208
+ requirements:
209
+ - - ! '>='
210
+ - !ruby/object:Gem::Version
211
+ version: '0'
212
+ segments:
213
+ - 0
214
+ hash: 1409840759125787075
215
+ required_rubygems_version: !ruby/object:Gem::Requirement
216
+ none: false
217
+ requirements:
218
+ - - ! '>='
219
+ - !ruby/object:Gem::Version
220
+ version: '0'
221
+ requirements: []
222
+ rubyforge_project:
223
+ rubygems_version: 1.6.2
224
+ signing_key:
225
+ specification_version: 3
226
+ summary: standalone leader election with zeromq for ruby
227
+ test_files: []