Class: Rinda::RingFinger

Inherits:
Object
  • Object
show all
Defined in:
lib/rinda/ring.rb

Overview

RingFinger is used by RingServer clients to discover the RingServer’s TupleSpace. Typically, all a client needs to do is call RingFinger.primary to retrieve the remote TupleSpace, which it can then begin using.

Constant Summary collapse

@@broadcast_list =
['<broadcast>', 'localhost']
@@finger =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(broadcast_list = @@broadcast_list, port = Ring_PORT) ⇒ RingFinger

Creates a new RingFinger that will look for RingServers at port on the addresses in broadcast_list.



147
148
149
150
151
152
# File 'lib/rinda/ring.rb', line 147

def initialize(broadcast_list=@@broadcast_list, port=Ring_PORT)
  @broadcast_list = broadcast_list || ['localhost']
  @port = port
  @primary = nil
  @rings = []
end

Instance Attribute Details

#broadcast_listObject

The list of addresses where RingFinger will send query packets.



131
132
133
# File 'lib/rinda/ring.rb', line 131

def broadcast_list
  @broadcast_list
end

#portObject

The port that RingFinger will send query packets to.



136
137
138
# File 'lib/rinda/ring.rb', line 136

def port
  @port
end

#primaryObject

Contain the first advertised TupleSpace after lookup_ring_any is called.



141
142
143
# File 'lib/rinda/ring.rb', line 141

def primary
  @primary
end

Class Method Details

.fingerObject

Creates a singleton RingFinger and looks for a RingServer. Returns the created RingFinger.



106
107
108
109
110
111
112
# File 'lib/rinda/ring.rb', line 106

def self.finger
  unless @@finger
    @@finger = self.new
    @@finger.lookup_ring_any
  end
  @@finger
end

.primaryObject

Returns the first advertised TupleSpace.



117
118
119
# File 'lib/rinda/ring.rb', line 117

def self.primary
  finger.primary
end

.to_aObject

Contains all discovered TupleSpaces except for the primary.



124
125
126
# File 'lib/rinda/ring.rb', line 124

def self.to_a
  finger.to_a
end

Instance Method Details

#each {|@primary| ... } ⇒ Object

Iterates over all discovered TupleSpaces starting with the primary.

Yields:



164
165
166
167
168
169
# File 'lib/rinda/ring.rb', line 164

def each
  lookup_ring_any unless @primary
  return unless @primary
  yield(@primary)
  @rings.each { |x| yield(x) }
end

#lookup_ring(timeout = 5, &block) ⇒ Object

Looks up RingServers waiting timeout seconds. RingServers will be given block as a callback, which will be called with the remote TupleSpace.



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/rinda/ring.rb', line 176

def lookup_ring(timeout=5, &block)
  return lookup_ring_any(timeout) unless block_given?

  msg = Marshal.dump([[:lookup_ring, DRbObject.new(block)], timeout])
  @broadcast_list.each do |it|
    soc = UDPSocket.open
    begin
      soc.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
      soc.send(msg, 0, it, @port)
    rescue
      nil
    ensure
      soc.close
    end
  end
  sleep(timeout)
end

#lookup_ring_any(timeout = 5) ⇒ Object

Returns the first found remote TupleSpace. Any further recovered TupleSpaces can be found by calling to_a.



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/rinda/ring.rb', line 198

def lookup_ring_any(timeout=5)
  queue = Queue.new

  Thread.new do
    self.lookup_ring(timeout) do |ts|
      queue.push(ts)
    end
    queue.push(nil)
  end

  @primary = queue.pop
  raise('RingNotFound') if @primary.nil?

  Thread.new do
    while it = queue.pop
      @rings.push(it)
    end
  end

  @primary
end

#to_aObject

Contains all discovered TupleSpaces except for the primary.



157
158
159
# File 'lib/rinda/ring.rb', line 157

def to_a
  @rings
end