RingyDingy 1.0.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.
data/CHANGES ADDED
@@ -0,0 +1,4 @@
1
+ = 1.0.0
2
+
3
+ Birthday!
4
+
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright 2006, Eric Hodel. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+ 3. Neither the names of the authors nor the names of their contributors
13
+ may be used to endorse or promote products derived from this software
14
+ without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
17
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
20
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
22
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Manifest.txt ADDED
@@ -0,0 +1,7 @@
1
+ CHANGES
2
+ LICENSE
3
+ Manifest.txt
4
+ README
5
+ Rakefile
6
+ lib/ringy_dingy.rb
7
+ test/test_ringy_dingy.rb
data/README ADDED
@@ -0,0 +1,38 @@
1
+ = RingyDingy
2
+
3
+ RingyDingy is a little boat that keeps your DRb service afloat!
4
+
5
+ Rubyforge Project:
6
+
7
+ http://rubyforge.org/projects/seattlerb
8
+
9
+ Documentation:
10
+
11
+ ri RingyDingy
12
+
13
+ == About
14
+
15
+ RingyDingy automatically registers a service with a RingServer. If
16
+ communication between the RingServer and the RingyDingy is lost, RingyDingy
17
+ will re-register its service with the RingServer when it reappears.
18
+
19
+ Similarly, the RingServer will automatically drop registrations by a RingyDingy
20
+ that it can't communicate with after a short timeout.
21
+
22
+ == Installing RingyDingy
23
+
24
+ Just install the gem:
25
+
26
+ $ sudo gem install RingyDingy
27
+
28
+ == Using RingyDingy
29
+
30
+ require 'rubygems'
31
+ require 'ringy_dingy'
32
+ require 'my_drb_service'
33
+
34
+ my_drb_service = MyDRbService.new
35
+
36
+ RingyDingy.new(my_drb_service).run
37
+
38
+ DRb.thread.join
data/Rakefile ADDED
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/gempackagetask'
6
+
7
+ $VERBOSE = nil
8
+
9
+ spec = Gem::Specification.new do |s|
10
+ s.name = 'RingyDingy'
11
+ s.version = '1.0.0'
12
+ s.summary = 'RingyDingy is a little boat that keeps your DRb service afloat!'
13
+ s.description = 'RingyDingy automatically re-registers your DRb service with a RingServer should communication with the RingServer stop.'
14
+ s.author = 'Eric Hodel'
15
+ s.email = 'drbrain@segment7.net'
16
+
17
+ s.has_rdoc = true
18
+ s.files = File.read('Manifest.txt').split($/)
19
+ s.require_path = 'lib'
20
+ end
21
+
22
+ desc 'Run tests'
23
+ task :default => [ :test ]
24
+
25
+ Rake::TestTask.new('test') do |t|
26
+ t.libs << 'test'
27
+ t.pattern = 'test/test_*.rb'
28
+ t.verbose = true
29
+ end
30
+
31
+ desc 'Update Manifest.txt'
32
+ task :update_manifest do
33
+ sh "find . -type f | sed -e 's%./%%' | egrep -v 'svn|swp|~' | egrep -v '^(doc|pkg)/' | sort > Manifest.txt"
34
+ end
35
+
36
+ desc 'Generate RDoc'
37
+ Rake::RDocTask.new :rdoc do |rd|
38
+ rd.rdoc_dir = 'doc'
39
+ rd.rdoc_files.add 'lib', 'README', 'LICENSE', 'CHANGES'
40
+ rd.main = 'README'
41
+ rd.options << '-d' if `which dot` =~ /\/dot/
42
+ rd.options << '-t RingyDingy Documentation'
43
+ end
44
+
45
+ desc 'Build Gem'
46
+ Rake::GemPackageTask.new spec do |pkg|
47
+ pkg.need_tar = true
48
+ end
49
+
50
+ desc 'Clean up'
51
+ task :clean => [ :clobber_rdoc, :clobber_package ]
52
+
53
+ desc 'Clean up'
54
+ task :clobber => [ :clean ]
55
+
56
+ # vim: syntax=Ruby
@@ -0,0 +1,120 @@
1
+ require 'English'
2
+ require 'drb'
3
+ require 'rinda/ring'
4
+
5
+ ##
6
+ # RingyDingy registers a DRb service with a Rinda::RingServer and re-registers
7
+ # the service if communication with the Rinda::RingServer is ever lost.
8
+ #
9
+ # Similarly, if the Rinda::RingServer should ever lose contact with the
10
+ # service the registration will be automatically dropped after a short
11
+ # timeout.
12
+ #
13
+ # = Example
14
+ #
15
+ # my_service = MyService.new
16
+ # rd = RingyDingy.new my_service, :MyService
17
+ # rd.run
18
+ # DRb.thread.join
19
+
20
+ class RingyDingy
21
+
22
+ ##
23
+ # Interval to check the RingServer for our registration information.
24
+
25
+ attr_accessor :check_every
26
+
27
+ ##
28
+ # RingyDingy service identifier. Use this to distinguish between
29
+ # RingyDingys registering the same service.
30
+
31
+ attr_reader :identifier
32
+
33
+ ##
34
+ # RingyDingy run loop thread.
35
+
36
+ attr_reader :thread
37
+
38
+ if $TESTING then
39
+ attr_accessor :ring_finger, :renewer, :thread # :nodoc:
40
+ attr_writer :ring_server # :nodoc:
41
+ end
42
+
43
+ ##
44
+ # Creates a new RingyDingy that registers +object+ as +service+ with
45
+ # optional identifier +name+.
46
+
47
+ def initialize(object, service = :RingyDingy, name = nil)
48
+ DRb.start_service
49
+
50
+ @identifier = [Socket.gethostname.downcase, $PID, name].compact.join '_'
51
+ @object = object
52
+ @service = service || :RingyDingy
53
+
54
+ @check_every = 180
55
+ @renewer = Rinda::SimpleRenewer.new
56
+
57
+ @ring_finger = Rinda::RingFinger.new
58
+ @ring_server = nil
59
+
60
+ @thread = nil
61
+ end
62
+
63
+ ##
64
+ # Registers this service with the primary Rinda::RingServer.
65
+
66
+ def register
67
+ ring_server.write [:name, @service, DRbObject.new(@object), @identifier],
68
+ @renewer
69
+ return nil
70
+ end
71
+
72
+ ##
73
+ # Looks for a registration tuple in the primary Rinda::RingServer. If a
74
+ # RingServer can't be found or contacted, returns false.
75
+
76
+ def registered?
77
+ registrations = ring_server.read_all [:name, :RingyDingy, nil, @identifier]
78
+ registrations.any? { |registration| registration[2] == @object }
79
+ rescue DRb::DRbConnError
80
+ @ring_server = nil
81
+ return false
82
+ end
83
+
84
+ ##
85
+ # Looks up the primary Rinde::RingServer.
86
+
87
+ def ring_server
88
+ return @ring_server unless @ring_server.nil?
89
+ @ring_server = @ring_finger.lookup_ring_any
90
+ end
91
+
92
+ ##
93
+ # Starts a thread that checks for a registration tuple every #check_every
94
+ # seconds.
95
+
96
+ def run
97
+ @thread = Thread.start do
98
+ loop do
99
+ begin
100
+ register unless registered?
101
+ rescue DRb::DRbConnError
102
+ @ring_server = nil
103
+ rescue RuntimeError => e
104
+ raise unless e.message == 'RingNotFound'
105
+ end
106
+ sleep @check_every
107
+ end
108
+ end
109
+ end
110
+
111
+ ##
112
+ # Stops checking for registration tuples.
113
+
114
+ def stop
115
+ @thread.kill
116
+ return nil
117
+ end
118
+
119
+ end
120
+
@@ -0,0 +1,156 @@
1
+ require 'test/unit'
2
+
3
+ $TESTING = true
4
+
5
+ require 'ringy_dingy'
6
+
7
+ class StubRingFinger
8
+
9
+ attr_accessor :ring_server
10
+
11
+ def initialize
12
+ @ring_server = nil
13
+ end
14
+
15
+ def lookup_ring_any
16
+ raise RuntimeError, 'RingNotFound' if @ring_server.nil?
17
+ @ring_server
18
+ end
19
+
20
+ end
21
+
22
+ class StubRingServer
23
+
24
+ attr_accessor :tuples
25
+
26
+ def initialize
27
+ @tuples = []
28
+ end
29
+
30
+ def write(*args)
31
+ @tuples << args
32
+ end
33
+
34
+ def read_all(*args)
35
+ @tuples.map { |t,r| t }
36
+ end
37
+
38
+ end
39
+
40
+ class Rinda::SimpleRenewer
41
+
42
+ attr_reader :sec
43
+
44
+ def ==(other)
45
+ self.class === other and sec == other.sec
46
+ end
47
+
48
+ end
49
+
50
+ class TestRingyDingy < Test::Unit::TestCase
51
+
52
+ def setup
53
+ @identifier = "#{Socket.gethostname.downcase}_#{$PID}"
54
+ @object = ""
55
+ @ringy_dingy = RingyDingy.new @object
56
+
57
+ @stub_ring_server = StubRingServer.new
58
+ @ringy_dingy.ring_server = @stub_ring_server
59
+ end
60
+
61
+ def test_identifier
62
+ assert_equal @identifier, @ringy_dingy.identifier
63
+
64
+ @ringy_dingy = RingyDingy.new @object, nil, 'blah'
65
+
66
+ assert_equal "#{@identifier}_blah", @ringy_dingy.identifier
67
+ end
68
+
69
+ def test_register
70
+ @ringy_dingy.register
71
+
72
+ expected = [
73
+ [[:name, :RingyDingy, DRbObject.new(@object), @identifier],
74
+ Rinda::SimpleRenewer.new]
75
+ ]
76
+
77
+ assert_equal expected, @stub_ring_server.tuples
78
+ end
79
+
80
+ def test_register_service
81
+ @ringy_dingy = RingyDingy.new @object, :MyDRbService
82
+ @ringy_dingy.ring_server = @stub_ring_server
83
+ @ringy_dingy.register
84
+
85
+ expected = [
86
+ [[:name, :MyDRbService, DRbObject.new(@object), @identifier],
87
+ Rinda::SimpleRenewer.new]
88
+ ]
89
+
90
+ assert_equal expected, @stub_ring_server.tuples
91
+ end
92
+
93
+ def test_registered_eh
94
+ @stub_ring_server.tuples << [
95
+ [:name, :RingyDingy, @object, @identifier], nil]
96
+
97
+ assert_equal true, @ringy_dingy.registered?
98
+ end
99
+
100
+ def test_registered_eh_not_registered
101
+ assert_equal false, @ringy_dingy.registered?
102
+ end
103
+
104
+ def test_registered_eh_no_ring_server
105
+ def @stub_ring_server.read_all(*args)
106
+ raise DRb::DRbConnError
107
+ end
108
+
109
+ assert_equal false, @ringy_dingy.registered?
110
+
111
+ assert_equal nil, @ringy_dingy.instance_variable_get(:@ring_server)
112
+ end
113
+
114
+ def test_registered_eh_service
115
+ @ringy_dingy = RingyDingy.new @object, :MyDRbService
116
+ @ringy_dingy.ring_server = @stub_ring_server
117
+
118
+ @stub_ring_server.tuples << [
119
+ [:name, :MyDRbService, @object, @identifier], nil]
120
+
121
+ assert_equal true, @ringy_dingy.registered?
122
+ end
123
+
124
+ def test_renewer
125
+ assert_equal Rinda::SimpleRenewer.new, @ringy_dingy.renewer
126
+ end
127
+
128
+ def test_ring_server
129
+ util_create_stub_ring_finger :server
130
+
131
+ assert_equal :server, @ringy_dingy.ring_server
132
+ end
133
+
134
+ def test_ring_server_not_found
135
+ util_create_stub_ring_finger
136
+
137
+ assert_raise RuntimeError do @ringy_dingy.ring_server end
138
+ end
139
+
140
+ def test_stop
141
+ @ringy_dingy.thread = Thread.start do sleep end
142
+ assert_equal nil, @ringy_dingy.stop
143
+ end
144
+
145
+ def util_create_stub_ring_finger(rs = nil)
146
+ @ringy_dingy.ring_server = nil
147
+
148
+ ring_finger = StubRingFinger.new
149
+
150
+ ring_finger.ring_server = rs unless rs.nil?
151
+
152
+ @ringy_dingy.ring_finger = ring_finger
153
+ end
154
+
155
+ end
156
+
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.99
3
+ specification_version: 1
4
+ name: RingyDingy
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2006-09-09 00:00:00 -07:00
8
+ summary: RingyDingy is a little boat that keeps your DRb service afloat!
9
+ require_paths:
10
+ - lib
11
+ email: drbrain@segment7.net
12
+ homepage:
13
+ rubyforge_project:
14
+ description: RingyDingy automatically re-registers your DRb service with a RingServer should communication with the RingServer stop.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Eric Hodel
31
+ files:
32
+ - CHANGES
33
+ - LICENSE
34
+ - Manifest.txt
35
+ - README
36
+ - Rakefile
37
+ - lib/ringy_dingy.rb
38
+ - test/test_ringy_dingy.rb
39
+ test_files: []
40
+
41
+ rdoc_options: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ executables: []
46
+
47
+ extensions: []
48
+
49
+ requirements: []
50
+
51
+ dependencies: []
52
+