Class: RGossip2::NodeList

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
ContextHelper
Defined in:
lib/rgossip2/node_list.rb

Instance Method Summary collapse

Constructor Details

#initialize(context) ⇒ NodeList

Returns a new instance of NodeList.



24
25
26
27
28
# File 'lib/rgossip2/node_list.rb', line 24

def initialize(context)
  @context = context
  @nodes = {}
  @mutex = Mutex.new
end

Instance Method Details

#choose_except(node) ⇒ Object

指定したNode以外のNodeをリストからランダムに選択する



48
49
50
51
52
53
54
55
56
# File 'lib/rgossip2/node_list.rb', line 48

def choose_except(node)
  node_list = []

  @nodes.each do |k, v|
    node_list << v if k != node.address
  end

  node_list.empty? ? nil : node_list[rand(node_list.size)]
end

#eachObject

Nodeの配列でイテレートする



34
35
36
37
38
# File 'lib/rgossip2/node_list.rb', line 34

def each
  @nodes.values.each do |i|
    yield(i)
  end
end

#serializeObject

ノード情報をいくつかの塊にごとにシリアライズする



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/rgossip2/node_list.rb', line 59

def serialize
  chunks = []
  nodes = []
  datasum = ''

  # バッファサイズ
  bufsiz = @context.buffer_size - @context.digest_length

  # Nodeはランダムな順序に変換
  @nodes.sort_by { rand }.each do |addr, node|
    # 長さを知るためにシリアライズ
    packed = node.serialize

    # Prevent infinite loop when packed exceeds bufsiz. Loop happens because packed is never less than bufsize, therefor always triggering a redo.
    if packed.length > bufsiz
      raise NodeListException.new("serialized packed length (#{packed.length}) exceeds bufsiz (#{bufsiz})")
    end

    # シリアライズしてバッファサイズ以下ならチャンクに追加
    if (datasum + packed).length <= bufsiz
      nodes << node
      datasum << packed
    else
      chunks << digest_and_message(nodes).join
      nodes.clear
      datasum.replace('')

      # バッファサイズを超える場合は次のチャンクに追加
      redo
    end
  end

  # 残りのNodeをチャンクに追加
  unless nodes.empty?
    chunks << digest_and_message(nodes).join
  end

  return chunks
end

#synchronizeObject

Mutex_mだとエラーになるので自前で定義



41
42
43
44
45
# File 'lib/rgossip2/node_list.rb', line 41

def synchronize
  @mutex.synchronize do
    yield
  end
end