DanaDanger-equity 0.1 → 0.2

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/bin/equity CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
- # equity 0.1 - simple queueing software load balancer
3
+ # equity 0.2 - simple queueing software load balancer
4
4
  #
5
5
  # Usage: equity [-d] <listen-port> [<node-address>:]<node-port> ...
6
6
  #
@@ -12,6 +12,7 @@
12
12
 
13
13
  require 'socket'
14
14
  require 'equity/node'
15
+ require 'equity/manager'
15
16
 
16
17
  # Prints a debug message if debugging is enabled.
17
18
  def debug(socket, message)
@@ -25,7 +26,7 @@ end
25
26
  $debugging = !!ARGV.delete('-d')
26
27
 
27
28
  if ARGV.length < 2
28
- STDERR.puts 'equity 0.1'
29
+ STDERR.puts 'equity 0.2'
29
30
  STDERR.puts 'Usage: equity [-d] <listen-port> [<node-address>:]<node-port> ...'
30
31
  STDERR.print "\n"
31
32
  STDERR.puts 'The -d option turns on debug mode. Equity will remain in the foreground and'
@@ -65,12 +66,6 @@ unless $debugging
65
66
  STDERR.reopen STDOUT
66
67
  end
67
68
 
68
- # Start up server.
69
- $client_queue = []
70
-
71
- $server = TCPServer.new(nil, $listen_port)
72
- $server.listen(5)
73
-
74
69
  # Set up SIGINT handler to print node counters.
75
70
  trap 'SIGINT', Proc.new {
76
71
  debug(nil, "\nNode Counters")
@@ -80,7 +75,16 @@ trap 'SIGINT', Proc.new {
80
75
  exit
81
76
  }
82
77
 
83
- puts "Ready on port #{$listen_port}" if $debugging
78
+ # Start up control server.
79
+ $control_server = Equity::Manager.new($nodes, $listen_port)
80
+
81
+ # Start up server.
82
+ $client_queue = []
83
+
84
+ $server = TCPServer.new(nil, $listen_port)
85
+ $server.listen(5)
86
+
87
+ debug(nil, "Ready on port #{$listen_port}")
84
88
 
85
89
  # Loop forever.
86
90
  while true
@@ -117,6 +121,7 @@ while true
117
121
  while !$client_queue.empty?
118
122
  client = $client_queue.shift
119
123
  found_a_node = false
124
+ failure_count = 0
120
125
  sorted_notes = $nodes.sort {|a,b| a.counter <=> b.counter}
121
126
  sorted_notes.each do |node|
122
127
  next if node.connected?
@@ -124,15 +129,26 @@ while true
124
129
  node.connect(client)
125
130
  rescue
126
131
  debug(client, "connection to #{node} failed")
132
+ failure_count += 1
127
133
  next
128
134
  end
129
135
  debug(client, "assigned to #{node}")
130
136
  found_a_node = true
131
137
  break
132
138
  end
133
- unless found_a_node
134
- $client_queue.unshift(client)
135
- break
139
+
140
+ $client_queue.unshift(client) unless found_a_node
141
+
142
+ if failure_count == $nodes.length
143
+ # All nodes failed. Disconnect all queued clients.
144
+ debug(nil, 'All nodes failed')
145
+ $client_queue.each {|client| client.close}
146
+ $client_queue.replace []
136
147
  end
148
+
149
+ break unless found_a_node
137
150
  end
151
+
152
+ # Check for control packets.
153
+ $control_server.process_commands
138
154
  end
@@ -0,0 +1,45 @@
1
+ module Equity
2
+ class Manager
3
+
4
+ CMD_NODE_STATUS = "\000"
5
+
6
+ def initialize(nodes, port)
7
+ @nodes = nodes
8
+ @socket = UDPSocket.new
9
+ @socket.bind(nil, port)
10
+ end
11
+
12
+ def process_commands
13
+ begin
14
+ data, address = @socket.recvfrom_nonblock(1024)
15
+ rescue Errno::EAGAIN
16
+ end
17
+ return unless data
18
+
19
+ case data
20
+ when CMD_NODE_STATUS
21
+ reply = node_status_message
22
+ else
23
+ return
24
+ end
25
+ UDPSocket.new.send(reply, 0, address[2], address[1])
26
+ end
27
+
28
+ private
29
+
30
+ def node_status_message
31
+ message = [@nodes.length].pack('C')
32
+ @nodes.each do |node|
33
+ message += [
34
+ 5 + node.address.length,
35
+ (node.connected? ? 1 : 0),
36
+ node.counter,
37
+ node.port
38
+ ].pack('nCNn')
39
+ message += node.address
40
+ end
41
+ message
42
+ end
43
+
44
+ end
45
+ end
data/lib/equity/node.rb CHANGED
@@ -4,6 +4,8 @@ module Equity
4
4
  # Represents a cluster node.
5
5
  class Node
6
6
  attr_reader :counter
7
+ attr_reader :address
8
+ attr_reader :port
7
9
 
8
10
  def initialize(address, port)
9
11
  @client = nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: DanaDanger-equity
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.1"
4
+ version: "0.2"
5
5
  platform: ruby
6
6
  authors:
7
7
  - DanaDanger
@@ -23,6 +23,7 @@ extra_rdoc_files: []
23
23
 
24
24
  files:
25
25
  - bin/equity
26
+ - lib/equity/manager.rb
26
27
  - lib/equity/node.rb
27
28
  - lib/equity/socket_pairing.rb
28
29
  has_rdoc: false