Class: RGossip2::Client
- Inherits:
-
Object
- Object
- RGossip2::Client
- Includes:
- Enumerable, ContextHelper
- Defined in:
- lib/rgossip2/client.rb
Overview
class Client ゴシッププロトコルのクライアント兼サーバ
----------
--------
| Client |<>—---
| Node | ----------
| --------
| +-----------------------+
+---+| @node_list:NodeList |
| +-----------------------+
| +-----------------------+
+---+| @dead_list:NodeList |
+-----------------------+
Instance Attribute Summary collapse
-
#context ⇒ Object
readonly
Returns the value of attribute context.
-
#dead_list ⇒ Object
readonly
Returns the value of attribute dead_list.
-
#node_list ⇒ Object
readonly
Returns the value of attribute node_list.
-
#self_node ⇒ Object
readonly
Returns the value of attribute self_node.
Instance Method Summary collapse
-
#add_node(address) ⇒ Object
ノードの追加.
- #address ⇒ Object
-
#clear_dead_list ⇒ Object
デッドリストのクリーニング.
- #data ⇒ Object
- #data=(v) ⇒ Object
-
#delete_node(address) ⇒ Object
ノードの削除.
-
#each ⇒ Object
ノードを舐める.
-
#initialize(context, initial_nodes = [], address = nil, data = nil) ⇒ Client
constructor
A new instance of Client.
- #join ⇒ Object
- #logger ⇒ Object
- #running? ⇒ Boolean
- #start ⇒ Object
- #stop ⇒ Object
- #transaction ⇒ Object
Constructor Details
#initialize(context, initial_nodes = [], address = nil, data = nil) ⇒ Client
Returns a new instance of Client.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/rgossip2/client.rb', line 31 def initialize(context, initial_nodes = [], address = nil, data = nil) @context = context # データがバッファサイズを超える場合はエラー if data and data.length > @context.buffer_size raise 'Data is too large' end # IPアドレスを取得。デフォルトはローカルホストアドレス @address = name2addr(address || IPSocket.getaddress(Socket.gethostname)) info("Client is initialized: initial_nodes=#{initial_nodes.inspect}, address=#{@address}, data=#{data.inspect}") # NodeListを生成 @node_list = create(NodeList) @dead_list = create(NodeList) # Nodeを生成 @self_node = create(Node, @node_list, @dead_list, @address, data, nil) @self_node. @node_list[@address] = @self_node # 初期ノードを追加 initial_nodes_threads = [] initial_nodes.uniq.each do |i| initial_nodes_threads << Thread.start(i) do |addr| addr = name2addr(i) # 自ノードはスキップ next if addr == @address # つながらない場合はスキップ next unless connectable?(addr, @context.port) @node_list[addr] = create(Node, @node_list, @dead_list, addr, nil, nil) end end initial_nodes_threads.each {|i| i.join } # Gossiper、Receiverを生成 @gossiper = create(Gossiper, @self_node, @node_list) @receiver = create(Receiver, @self_node, @node_list, @dead_list) end |
Instance Attribute Details
#context ⇒ Object (readonly)
Returns the value of attribute context.
29 30 31 |
# File 'lib/rgossip2/client.rb', line 29 def context @context end |
#dead_list ⇒ Object (readonly)
Returns the value of attribute dead_list.
26 27 28 |
# File 'lib/rgossip2/client.rb', line 26 def dead_list @dead_list end |
#node_list ⇒ Object (readonly)
Returns the value of attribute node_list.
25 26 27 |
# File 'lib/rgossip2/client.rb', line 25 def node_list @node_list end |
#self_node ⇒ Object (readonly)
Returns the value of attribute self_node.
27 28 29 |
# File 'lib/rgossip2/client.rb', line 27 def self_node @self_node end |
Instance Method Details
#add_node(address) ⇒ Object
ノードの追加
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/rgossip2/client.rb', line 132 def add_node(address) address = name2addr(address) @node_list.synchronize { @dead_list.synchronize { # すでに存在する場合はエラー raise 'The node already exists' if @node_list[address] node = create(Node, @node_list, @dead_list, address, nil, nil) @node_list[address] = node # デッドリストからは追加したノードを削除 @dead_list.delete(address) node.start_timer if @running callback(:add, address, nil, nil, nil) } } end |
#address ⇒ Object
113 114 115 |
# File 'lib/rgossip2/client.rb', line 113 def address @self_node.address end |
#clear_dead_list ⇒ Object
デッドリストのクリーニング
176 177 178 179 180 181 182 183 184 185 |
# File 'lib/rgossip2/client.rb', line 176 def clear_dead_list dead_list_len = 0 @dead_list.synchronize { dead_list_len = @dead_list.length @dead_list.clear } return dead_list_len end |
#data ⇒ Object
117 118 119 |
# File 'lib/rgossip2/client.rb', line 117 def data @self_node.data end |
#data=(v) ⇒ Object
121 122 123 |
# File 'lib/rgossip2/client.rb', line 121 def data=(v) @self_node.data = v end |
#delete_node(address) ⇒ Object
ノードの削除
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/rgossip2/client.rb', line 154 def delete_node(address) address = name2addr(address) # 自分自身は削除できない raise 'Own node cannot be deleted' if @self_node.address == address @node_list.synchronize { @dead_list.synchronize { # ノードリストから削除してTimerを止める node = @node_list.delete(address) node.stop_timer if node # デッドリストからも削除 node = @dead_list.delete(address) node.stop_timer if node callback(:delete, address, nil, nil, nil) } } end |
#each ⇒ Object
ノードを舐める
188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/rgossip2/client.rb', line 188 def each @node_list.each do |node| address = node.address.dup = node..dup if data = node.data data = data.dup end yield([address, , data]) end end |
#join ⇒ Object
104 105 106 107 |
# File 'lib/rgossip2/client.rb', line 104 def join @gossiper.join @receiver.join end |
#logger ⇒ Object
201 202 203 |
# File 'lib/rgossip2/client.rb', line 201 def logger @context.logger end |
#running? ⇒ Boolean
109 110 111 |
# File 'lib/rgossip2/client.rb', line 109 def running? !!@running end |
#start ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/rgossip2/client.rb', line 73 def start # 開始している場合はスキップ return if @running info("Client is started: address=#{@address}") # NodoのTimerをスタート @node_list.each do |node| if node.address != @self_node.address node.start_timer end end @gossiper.start @receiver.start ensure @running = true end |
#stop ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/rgossip2/client.rb', line 92 def stop # 停止している場合はスキップ return unless @running info("Client is stopped") @gossiper.stop @receiver.stop ensure @running = false end |
#transaction ⇒ Object
125 126 127 128 129 |
# File 'lib/rgossip2/client.rb', line 125 def transaction @node_list.synchronize { yield } end |