Class: RGossip::Client

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/rgossip/client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(initial_nodes = [], address = nil, data = nil, callback = nil) ⇒ Client

Returns a new instance of Client.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/rgossip/client.rb', line 9

def initialize(initial_nodes = [], address = nil,  data = nil, callback = nil)
  raise 'too large data' if data && data.length > RGossip.bufsiz

  @address = name2addr(address || IPSocket.getaddress(Socket.gethostname))

  RGossip.log("Initialize Client: initial_nodes=#{initial_nodes.inspect} address: #{@address} data: #{data.inspect}")

  @callback = callback
  @node_list = Nodes.new
  @dead_list = Nodes.new

  @my_node = Node.new(@node_list, @dead_list, @address, data, nil, self.method(:perform_callback))
  @my_node.update_timestamp
  @node_list << @my_node

  initial_nodes.uniq.each do |i|
    @node_list << Node.new(@node_list, @dead_list, name2addr(i), nil, nil, self.method(:perform_callback))
  end

  @gossiper = Gossiper.new(@my_node, @node_list)
  @receiver = Receiver.new(@my_node, @node_list, @dead_list, self.method(:perform_callback))
end

Instance Attribute Details

#dead_listObject (readonly)

Returns the value of attribute dead_list.



6
7
8
# File 'lib/rgossip/client.rb', line 6

def dead_list
  @dead_list
end

#my_nodeObject (readonly)

Returns the value of attribute my_node.



7
8
9
# File 'lib/rgossip/client.rb', line 7

def my_node
  @my_node
end

#node_listObject (readonly)

Returns the value of attribute node_list.



5
6
7
# File 'lib/rgossip/client.rb', line 5

def node_list
  @node_list
end

Instance Method Details

#add_node(address) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/rgossip/client.rb', line 100

def add_node(address)
  address = name2addr(address)

  @node_list.synchronize {
    @dead_list.synchronize {
      raise 'node is exist' if @node_list.any? {|i| i.address == address }

      node = Node.new(@node_list, @dead_list, address, nil, nil, self.method(:perform_callback))
      @node_list << node

      @dead_list.reject! do |i|
        i.address == address
      end

      node.start_timer if @running

      perform_callback([:add, address, nil, nil])
    }
  }
end

#addressObject



76
77
78
# File 'lib/rgossip/client.rb', line 76

def address
  @my_node.address
end

#callback=(v) ⇒ Object



92
93
94
95
96
97
98
# File 'lib/rgossip/client.rb', line 92

def callback=(v)
  @node_list.synchronize {
    @dead_list.synchronize {
      @callback = v
    }
  }
end

#clear_dead_listObject



143
144
145
146
147
# File 'lib/rgossip/client.rb', line 143

def clear_dead_list
  @dead_list.synchronize {
    @dead_list.clear
  }
end

#dataObject



80
81
82
83
84
# File 'lib/rgossip/client.rb', line 80

def data
  @node_list.synchronize {
    @my_node.data
  }
end

#data=(v) ⇒ Object



86
87
88
89
90
# File 'lib/rgossip/client.rb', line 86

def data=(v)
  @node_list.synchronize {
    @my_node.data = v
  }
end

#delete_node(address) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/rgossip/client.rb', line 121

def delete_node(address)
  address = name2addr(address)
  raise 'cannot delete own node' if @my_node.address == address

  @node_list.synchronize {
    @dead_list.synchronize {
      @node_list.reject! do |i|
        if i.address == address
          i.stop_timer
          true
        end
      end

      @dead_list.reject! do |i|
        i.address == address
      end

      perform_callback([:delete, address, nil, nil])
    }
  }
end

#eachObject



149
150
151
152
153
# File 'lib/rgossip/client.rb', line 149

def each
  @node_list.each do |node|
    yield([node.address, node.timestamp, node.data])
  end
end

#joinObject



67
68
69
70
# File 'lib/rgossip/client.rb', line 67

def join
  @gossiper.join
  @receiver.join
end

#running?Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/rgossip/client.rb', line 72

def running?
  !!@running
end

#startObject



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rgossip/client.rb', line 32

def start
  return if @running

  begin
    RGossip.log("Start Client: address=#{@address}")

    @node_list.each do |node|
      if node.address != @my_node.address
        node.start_timer
      end
    end

    @gossiper.start
    @receiver.start
  ensure
    @running = true
  end
end

#stopObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/rgossip/client.rb', line 51

def stop
  return unless @running

  begin
    RGossip.log("Stop Client")

    @gossiper.stop
    @receiver.stop

    @gossiper = nil
    @receiver = nil
  ensure
    @running = true
  end
end