DanaDanger-equity 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
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