proxymachine 0.2.3 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -20,20 +20,21 @@ contents of the transmission, then ProxyMachine will make your life easy!
20
20
  The idea here is simple. For each client connection, start receiving data
21
21
  chunks and placing them into a buffer. Each time a new chunk arrives, send the
22
22
  buffer to a user specified block. The block's job is to parse the buffer to
23
- determine where the connection should proxied. If the buffer contains enough
24
- data to make a determination, the block returns the address and port of the
25
- correct backend server. If not, it can choose to either do nothing and wait
26
- for more data to arrive, or close the connection. Once the block returns an
27
- address, a connection to the backend is made, the buffer is replayed to the
28
- backend, and the client and backend connections are hooked up to form a
29
- straight proxy. This bidirectional proxy continues to exist until either the
30
- client or backend close the connection.
23
+ determine where the connection should be proxied. If the buffer contains
24
+ enough data to make a determination, the block returns the address and port of
25
+ the correct backend server. If not, it can choose to do nothing and wait for
26
+ more data to arrive, close the connection, or close the connection after
27
+ sending custom data. Once the block returns an address, a connection to the
28
+ backend is made, the buffer is replayed to the backend, and the client and
29
+ backend connections are hooked up to form a transparent proxy. This
30
+ bidirectional proxy continues to exist until either the client or backend
31
+ close the connection.
31
32
 
32
33
 
33
34
  Installation
34
35
  ------------
35
36
 
36
- gem install mojombo-proxymachine -s http://gems.github.com
37
+ $ gem install proxymachine -s http://gemcutter.org
37
38
 
38
39
 
39
40
  Running
@@ -48,6 +49,19 @@ Running
48
49
  -p, --port PORT Port to listen on. Default 5432
49
50
 
50
51
 
52
+ Signals
53
+ -------
54
+
55
+ QUIT - Graceful shutdown. Stop accepting connections immediately and
56
+ wait as long as necessary for all connections to close.
57
+
58
+ TERM - Fast shutdown. Stop accepting connections immediately and wait
59
+ up to 10 seconds for connections to close before forcing
60
+ termination.
61
+
62
+ INT - Same as TERM
63
+
64
+
51
65
  Example routing config file
52
66
  ---------------------------
53
67
 
@@ -63,7 +77,7 @@ Example routing config file
63
77
  # header information from the Git protocol is parsed to find the
64
78
  # username and a lookup routine is run on the name to find the correct
65
79
  # backend server. If no match can be made yet, do nothing with the
66
- # connection yet.
80
+ # connection.
67
81
  proxy do |data|
68
82
  if data =~ %r{^....git-upload-pack /([\w\.\-]+)/[\w\.\-]+\000host=\w+\000}
69
83
  name = $1
@@ -80,7 +94,7 @@ Valid return values
80
94
  `{ :remote => String }` - String is the host:port of the backend server that will be proxied.
81
95
  `{ :remote => String, :data => String }` - Same as above, but send the given data instead.
82
96
  `{ :noop => true }` - Do nothing.
83
- `{ :close` => true } - Close the connection.
97
+ `{ :close => true }` - Close the connection.
84
98
  `{ :close => String }` - Close the connection after sending the String.
85
99
 
86
100
 
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :minor: 2
3
- :patch: 3
3
+ :patch: 6
4
4
  :major: 0
data/bin/proxymachine CHANGED
@@ -32,7 +32,8 @@ EOF
32
32
  opts.parse!
33
33
 
34
34
  load(options[:config])
35
- ProxyMachine.run(options[:host], options[:port])
35
+ name = options[:config].split('/').last.chomp('.rb')
36
+ ProxyMachine.run(name, options[:host], options[:port])
36
37
  rescue Exception => e
37
38
  if e.instance_of?(SystemExit)
38
39
  raise
data/examples/long.rb ADDED
@@ -0,0 +1,9 @@
1
+ # To try out the graceful exit via SIGQUIT, start up a proxymachine with this
2
+ # configuration, and run the following curl command a few times:
3
+ # curl http://localhost:5432/ubuntu-releases/9.10/ubuntu-9.10-beta-alternate-amd64.iso \
4
+ # -H "Host: mirrors.cat.pdx.edu" > /dev/null
5
+ # Then send a SIGQUIT to the process and stop the long downloads one by one.
6
+
7
+ proxy do |data|
8
+ { :remote => "mirrors.cat.pdx.edu:80" }
9
+ end
@@ -2,8 +2,10 @@ module EventMachine
2
2
  module Protocols
3
3
  class ClientConnection < Connection
4
4
  def self.start(host, port)
5
- EM.start_server(host, port, self)
5
+ $server = EM.start_server(host, port, self)
6
6
  puts "Listening on #{host}:#{port}"
7
+ puts "Send QUIT to quit after waiting for all connections to finish."
8
+ puts "Send TERM or INT to quit after waiting for up to 10 seconds for connections to finish."
7
9
  end
8
10
 
9
11
  def post_init
data/lib/proxymachine.rb CHANGED
@@ -5,20 +5,30 @@ require 'proxymachine/client_connection'
5
5
  require 'proxymachine/server_connection'
6
6
 
7
7
  class ProxyMachine
8
- def self.log(str)
9
- puts str if false
8
+ MAX_FAST_SHUTDOWN_SECONDS = 10
9
+
10
+ def self.update_procline
11
+ $0 = "proxymachine - #{@@name} #{@@listen} - #{self.count} connections"
12
+ end
13
+
14
+ def self.count
15
+ @@counter
10
16
  end
11
17
 
12
18
  def self.incr
13
- @@counter ||= 0
14
19
  @@counter += 1
15
- log @@counter
20
+ self.update_procline
21
+ @@counter
16
22
  end
17
23
 
18
24
  def self.decr
19
- @@counter ||= 0
20
25
  @@counter -= 1
21
- log @@counter
26
+ if $server.nil?
27
+ puts "Waiting for #{@@counter} connections to finish."
28
+ end
29
+ self.update_procline
30
+ EM.stop if $server.nil? and @@counter == 0
31
+ @@counter
22
32
  end
23
33
 
24
34
  def self.set_router(block)
@@ -29,11 +39,45 @@ class ProxyMachine
29
39
  @@router
30
40
  end
31
41
 
32
- def self.run(host, port)
42
+ def self.graceful_shutdown(signal)
43
+ EM.stop_server($server) if $server
44
+ puts "Received #{signal} signal. No longer accepting new connections."
45
+ puts "Waiting for #{ProxyMachine.count} connections to finish."
46
+ $server = nil
47
+ EM.stop if ProxyMachine.count == 0
48
+ end
49
+
50
+ def self.fast_shutdown(signal)
51
+ EM.stop_server($server) if $server
52
+ puts "Received #{signal} signal. No longer accepting new connections."
53
+ puts "Maximum time to wait for connections is #{MAX_FAST_SHUTDOWN_SECONDS} seconds."
54
+ puts "Waiting for #{ProxyMachine.count} connections to finish."
55
+ $server = nil
56
+ EM.stop if ProxyMachine.count == 0
57
+ Thread.new do
58
+ sleep MAX_FAST_SHUTDOWN_SECONDS
59
+ exit!
60
+ end
61
+ end
62
+
63
+ def self.run(name, host, port)
64
+ @@counter = 0
65
+ @@name = name
66
+ @@listen = "#{host}:#{port}"
67
+ self.update_procline
33
68
  EM.epoll
34
69
 
35
70
  EM.run do
36
71
  EventMachine::Protocols::ClientConnection.start(host, port)
72
+ trap('QUIT') do
73
+ self.graceful_shutdown('QUIT')
74
+ end
75
+ trap('TERM') do
76
+ self.fast_shutdown('TERM')
77
+ end
78
+ trap('INT') do
79
+ self.fast_shutdown('INT')
80
+ end
37
81
  end
38
82
  end
39
83
  end
data/proxymachine.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{proxymachine}
5
- s.version = "0.2.3"
5
+ s.version = "0.2.6"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Tom Preston-Werner"]
9
- s.date = %q{2009-08-18}
9
+ s.date = %q{2009-10-01}
10
10
  s.default_executable = %q{proxymachine}
11
11
  s.email = %q{tom@mojombo.com}
12
12
  s.executables = ["proxymachine"]
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
23
23
  "VERSION.yml",
24
24
  "bin/proxymachine",
25
25
  "examples/git.rb",
26
+ "examples/long.rb",
26
27
  "examples/transparent.rb",
27
28
  "lib/proxymachine.rb",
28
29
  "lib/proxymachine/client_connection.rb",
@@ -40,6 +41,7 @@ Gem::Specification.new do |s|
40
41
  "test/proxymachine_test.rb",
41
42
  "test/test_helper.rb",
42
43
  "examples/git.rb",
44
+ "examples/long.rb",
43
45
  "examples/transparent.rb"
44
46
  ]
45
47
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: proxymachine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Preston-Werner
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-18 00:00:00 -07:00
12
+ date: 2009-10-01 00:00:00 -07:00
13
13
  default_executable: proxymachine
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -40,6 +40,7 @@ files:
40
40
  - VERSION.yml
41
41
  - bin/proxymachine
42
42
  - examples/git.rb
43
+ - examples/long.rb
43
44
  - examples/transparent.rb
44
45
  - lib/proxymachine.rb
45
46
  - lib/proxymachine/client_connection.rb
@@ -79,4 +80,5 @@ test_files:
79
80
  - test/proxymachine_test.rb
80
81
  - test/test_helper.rb
81
82
  - examples/git.rb
83
+ - examples/long.rb
82
84
  - examples/transparent.rb