em-proxy 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .bundle
data/.rspec ADDED
File without changes
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ em-proxy (0.1.5)
5
+ eventmachine
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ addressable (2.2.2)
11
+ ansi (1.2.2)
12
+ diff-lcs (1.1.2)
13
+ em-http-request (0.3.0)
14
+ addressable (>= 2.0.0)
15
+ escape_utils
16
+ eventmachine (>= 0.12.9)
17
+ escape_utils (0.1.9)
18
+ eventmachine (0.12.11)
19
+ rspec (2.4.0)
20
+ rspec-core (~> 2.4.0)
21
+ rspec-expectations (~> 2.4.0)
22
+ rspec-mocks (~> 2.4.0)
23
+ rspec-core (2.4.0)
24
+ rspec-expectations (2.4.0)
25
+ diff-lcs (~> 1.1.2)
26
+ rspec-mocks (2.4.0)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ ansi
33
+ em-http-request
34
+ em-proxy!
35
+ eventmachine
36
+ rspec
data/README.rdoc CHANGED
@@ -7,14 +7,17 @@ EventMachine Proxy DSL for writing high-performance transparent / intercepting p
7
7
 
8
8
  == Getting started
9
9
 
10
- # install & configure gemcutter repos
11
- gem update --system
12
- gem install gemcutter
13
- gem tumble
10
+ $> gem install em-proxy
11
+ $> em-proxy
12
+ Usage: em-proxy [options]
13
+ -l, --listen [PORT] Port to listen on
14
+ -d, --duplex [host:port, ...] List of backends to duplex data to
15
+ -r, --relay [hostname:port] Relay endpoint: hostname:port
16
+ -v, --verbose Run in debug mode
14
17
 
15
- gem install em-proxy
18
+ $> em-proxy -l 8080 -r localhost:8081 -d localhost:8082,localhost:8083 -v
16
19
 
17
- irb:0> require 'em-proxy'
20
+ The above will start em-proxy on port 8080, relay and respond with data from port 8081, and also (optional) duplicate all traffic to ports 8082 and 8083 (and discard their responses).
18
21
 
19
22
  == Simple port forwarding proxy
20
23
 
data/Rakefile CHANGED
@@ -1,19 +1,4 @@
1
- require 'rake'
1
+ require 'bundler'
2
2
 
3
- begin
4
- require 'jeweler'
5
- Jeweler::Tasks.new do |gemspec|
6
- gemspec.name = "em-proxy"
7
- gemspec.summary = "EventMachine Proxy DSL"
8
- gemspec.description = gemspec.summary
9
- gemspec.email = "ilya@igvita.com"
10
- gemspec.homepage = "http://github.com/igrigorik/em-proxy"
11
- gemspec.authors = ["Ilya Grigorik"]
12
- gemspec.add_dependency('eventmachine', '>= 0.12.9')
13
- gemspec.rubyforge_project = "em-proxy"
14
- end
15
-
16
- Jeweler::GemcutterTasks.new
17
- rescue LoadError
18
- puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
19
- end
3
+ Bundler.setup
4
+ Bundler::GemHelper.install_tasks
data/bin/em-proxy ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
6
+ require 'em-proxy'
7
+ require 'optparse'
8
+
9
+ ARGV << '--help' if ARGV.empty?
10
+
11
+ options = {}
12
+ OptionParser.new do |opts|
13
+ opts.banner = "Usage: em-proxy [options]"
14
+
15
+ opts.on("-l", "--listen [PORT]", Integer, "Port to listen on") do |v|
16
+ options[:listen] = v
17
+ end
18
+
19
+ opts.on("-d", "--duplex [host:port, ...]", Array, "List of backends to duplex data to") do |v|
20
+ options[:duplex] = v
21
+ end
22
+
23
+ opts.on("-r", "--relay [hostname:port]", String, "Relay endpoint: hostname:port") do |v|
24
+ options[:relay] = v.split(":")
25
+ end
26
+
27
+ opts.on("-v", "--verbose", "Run in debug mode") do |v|
28
+ options[:verbose] = v
29
+ end
30
+ end.parse!
31
+
32
+
33
+ Proxy.start(:host => "0.0.0.0", :port => options[:listen] , :debug => options[:verbose]) do |conn|
34
+ conn.server :relay, :host => options[:relay].first, :port => options[:relay].last.to_i
35
+
36
+ options[:duplex].each_with_index do |backend,i|
37
+ hostname, port = backend.split(":")
38
+ conn.server "backend_#{i}".intern, :host => hostname, :port => port.to_i
39
+ end if options[:duplex]
40
+
41
+ conn.on_data do |data|
42
+ data
43
+ end
44
+
45
+ conn.on_response do |server, resp|
46
+ resp if server == :relay
47
+ end
48
+ end
data/em-proxy.gemspec CHANGED
@@ -1,76 +1,25 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
1
  # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
5
3
 
6
4
  Gem::Specification.new do |s|
7
- s.name = %q{em-proxy}
8
- s.version = "0.1.4"
5
+ s.name = "em-proxy"
6
+ s.version = "0.1.5"
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Ilya Grigorik"]
9
+ s.email = ["ilya@igvita.com"]
10
+ s.homepage = "http://github.com/igrigorik/em-proxy"
11
+ s.summary = %q{EventMachine Proxy DSL}
12
+ s.description = s.summary
9
13
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Ilya Grigorik"]
12
- s.date = %q{2010-10-03}
13
- s.description = %q{EventMachine Proxy DSL}
14
- s.email = %q{ilya@igvita.com}
15
- s.extra_rdoc_files = [
16
- "README.rdoc"
17
- ]
18
- s.files = [
19
- "README.rdoc",
20
- "Rakefile",
21
- "VERSION",
22
- "em-proxy.gemspec",
23
- "examples/appserver.rb",
24
- "examples/beanstalkd_interceptor.rb",
25
- "examples/duplex.rb",
26
- "examples/line_interceptor.rb",
27
- "examples/port_forward.rb",
28
- "examples/relay_port_forward.rb",
29
- "examples/schemaless-mysql/mysql_interceptor.rb",
30
- "examples/selective_forward.rb",
31
- "examples/simple.rb",
32
- "examples/smtp_spam_filter.rb",
33
- "examples/smtp_whitelist.rb",
34
- "lib/em-proxy.rb",
35
- "lib/em-proxy/backend.rb",
36
- "lib/em-proxy/connection.rb",
37
- "lib/em-proxy/proxy.rb",
38
- "spec/helper.rb",
39
- "spec/proxy_spec.rb"
40
- ]
41
- s.homepage = %q{http://github.com/igrigorik/em-proxy}
42
- s.rdoc_options = ["--charset=UTF-8"]
43
- s.require_paths = ["lib"]
44
- s.rubyforge_project = %q{em-proxy}
45
- s.rubygems_version = %q{1.3.7}
46
- s.summary = %q{EventMachine Proxy DSL}
47
- s.test_files = [
48
- "spec/helper.rb",
49
- "spec/proxy_spec.rb",
50
- "examples/appserver.rb",
51
- "examples/beanstalkd_interceptor.rb",
52
- "examples/duplex.rb",
53
- "examples/line_interceptor.rb",
54
- "examples/port_forward.rb",
55
- "examples/relay_port_forward.rb",
56
- "examples/schemaless-mysql/mysql_interceptor.rb",
57
- "examples/selective_forward.rb",
58
- "examples/simple.rb",
59
- "examples/smtp_spam_filter.rb",
60
- "examples/smtp_whitelist.rb"
61
- ]
62
-
63
- if s.respond_to? :specification_version then
64
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
65
- s.specification_version = 3
14
+ s.rubyforge_project = "em-proxy"
66
15
 
67
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
68
- s.add_runtime_dependency(%q<eventmachine>, [">= 0.12.9"])
69
- else
70
- s.add_dependency(%q<eventmachine>, [">= 0.12.9"])
71
- end
72
- else
73
- s.add_dependency(%q<eventmachine>, [">= 0.12.9"])
74
- end
75
- end
16
+ s.add_dependency "eventmachine"
17
+ s.add_development_dependency "rspec"
18
+ s.add_development_dependency "em-http-request"
19
+ s.add_development_dependency "ansi"
76
20
 
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ["lib"]
25
+ end
@@ -0,0 +1,20 @@
1
+ # A simple HTTP client, which sends multiple requests to the proxy server
2
+
3
+ require 'net/http'
4
+
5
+ proxy = Net::HTTP::Proxy('0.0.0.0', '9999')
6
+
7
+ count = ENV['COUNT'] || 5
8
+
9
+ threads = []
10
+ count.to_i.times do |i|
11
+ threads << Thread.new do
12
+ proxy.start('www.example.com') do |http|
13
+ puts http.get('/').body
14
+ puts "^^^ #{i+1} " + '-'*80 + "\n\n"
15
+ end
16
+ sleep 0.1
17
+ end
18
+ end
19
+
20
+ threads.each { |t| t.join }
@@ -0,0 +1,195 @@
1
+ require 'lib/em-proxy'
2
+ require 'ansi/code'
3
+ require 'uri'
4
+
5
+ # = Balancing Proxy
6
+ #
7
+ # A simple example of a balancing, reverse/forward proxy such as Nginx or HAProxy.
8
+ #
9
+ # Given a list of backends, it's able to distribute requests to backends
10
+ # via different strategies (_random_, _roundrobin_, _balanced_), see <tt>Backend.select</tt>.
11
+ #
12
+ # This example is provided for didactic purposes. Nevertheless, based on some preliminary benchmarks
13
+ # and live tests, it performs well in production usage.
14
+ #
15
+ # You can customize the behaviour of the proxy by changing the <tt>BalancingProxy::Callbacks</tt>
16
+ # callbacks. To give you some ideas:
17
+ #
18
+ # * Store statistics for the proxy load in Redis (eg.: <tt>$redis.incr "proxy>backends>#{backend}>total"</tt>)
19
+ # * Use Redis' _SortedSet_ instead of updating the <tt>Backend.list</tt> hash to allow for polling from external process
20
+ # * Use <b>em-websocket</b>[https://github.com/igrigorik/em-websocket] to build a web frontend for monitoring
21
+ #
22
+ module BalancingProxy
23
+ extend self
24
+
25
+ BACKENDS = [
26
+ {:url => "http://0.0.0.0:3000"},
27
+ {:url => "http://0.0.0.0:3001"},
28
+ {:url => "http://0.0.0.0:3002"}
29
+ ]
30
+
31
+ # Represents a "backend", ie. the endpoint for the proxy.
32
+ #
33
+ # This could be eg. a WEBrick webserver (see below), so the proxy server works as a _reverse_ proxy.
34
+ # But it could also be a proxy server, so the proxy server works as a _forward_ proxy.
35
+ #
36
+ class Backend
37
+
38
+ attr_reader :url, :host, :port
39
+ attr_accessor :load
40
+ alias :to_s :url
41
+
42
+ def initialize(options={})
43
+ raise ArgumentError, "Please provide a :url and :load" unless options[:url]
44
+ @url = options[:url]
45
+ @load = options[:load] || 0
46
+ parsed = URI.parse(@url)
47
+ @host, @port = parsed.host, parsed.port
48
+ end
49
+
50
+ # Select backend: balanced, round-robin or random
51
+ #
52
+ def self.select(strategy = :balanced)
53
+ @strategy = strategy.to_sym
54
+ case @strategy
55
+ when :balanced
56
+ backend = list.sort_by { |b| b.load }.first
57
+ when :roundrobin
58
+ @pool = list.clone if @pool.nil? || @pool.empty?
59
+ backend = @pool.shift
60
+ when :random
61
+ backend = list[ rand(list.size-1) ]
62
+ else
63
+ raise ArgumentError, "Unknown strategy: #{@strategy}"
64
+ end
65
+
66
+ Callbacks.on_select.call(backend)
67
+ yield backend if block_given?
68
+ backend
69
+ end
70
+
71
+ # List of backends
72
+ #
73
+ def self.list
74
+ @list ||= BACKENDS.map { |backend| new backend }
75
+ end
76
+
77
+ # Return balancing strategy
78
+ #
79
+ def self.strategy
80
+ @strategy
81
+ end
82
+
83
+ # Increment "currently serving requests" counter
84
+ #
85
+ def increment_counter
86
+ self.load += 1
87
+ end
88
+
89
+ # Decrement "currently serving requests" counter
90
+ #
91
+ def decrement_counter
92
+ self.load -= 1
93
+ end
94
+
95
+ end
96
+
97
+ # Callbacks for em-proxy events
98
+ #
99
+ module Callbacks
100
+ include ANSI::Code
101
+ extend self
102
+
103
+ def on_select
104
+ lambda do |backend|
105
+ puts black_on_white { 'on_select'.ljust(12) } + " #{backend.inspect}"
106
+ backend.increment_counter if Backend.strategy == :balanced
107
+ end
108
+ end
109
+
110
+ def on_connect
111
+ lambda do |backend|
112
+ puts black_on_magenta { 'on_connect'.ljust(12) } + ' ' + bold { backend }
113
+ end
114
+ end
115
+
116
+ def on_data
117
+ lambda do |data|
118
+ puts black_on_yellow { 'on_data'.ljust(12) }, data
119
+ data
120
+ end
121
+ end
122
+
123
+ def on_response
124
+ lambda do |backend, resp|
125
+ puts black_on_green { 'on_response'.ljust(12) } + " from #{backend}", resp
126
+ resp
127
+ end
128
+ end
129
+
130
+ def on_finish
131
+ lambda do |backend|
132
+ puts black_on_cyan { 'on_finish'.ljust(12) } + " for #{backend}", ''
133
+ backend.decrement_counter if Backend.strategy == :balanced
134
+ end
135
+ end
136
+
137
+ end
138
+
139
+ # Wrapping the proxy server
140
+ #
141
+ module Server
142
+ def run(host='0.0.0.0', port=9999)
143
+
144
+ puts ANSI::Code.bold { "Launching proxy at #{host}:#{port}...\n" }
145
+
146
+ Proxy.start(:host => host, :port => port, :debug => false) do |conn|
147
+
148
+ Backend.select do |backend|
149
+
150
+ conn.server backend, :host => backend.host, :port => backend.port
151
+
152
+ conn.on_connect &Callbacks.on_connect
153
+ conn.on_data &Callbacks.on_data
154
+ conn.on_response &Callbacks.on_response
155
+ conn.on_finish &Callbacks.on_finish
156
+ end
157
+
158
+ end
159
+ end
160
+
161
+ module_function :run
162
+ end
163
+
164
+ end
165
+
166
+ if __FILE__ == $0
167
+
168
+ require 'rack'
169
+
170
+ class Proxy
171
+ def self.stop
172
+ puts "Terminating ProxyServer"
173
+ EventMachine.stop
174
+ $servers.each do |pid|
175
+ puts "Terminating webserver #{pid}"
176
+ Process.kill('KILL', pid)
177
+ end
178
+ end
179
+ end
180
+
181
+ # Simple Rack app to run
182
+ app = proc { |env| [ 200, {'Content-Type' => 'text/plain'}, ["Hello World!"] ] }
183
+
184
+ # Run app on ports 3000-3002
185
+ $servers = []
186
+ 3.times do |i|
187
+ $servers << Process.fork { Rack::Handler::WEBrick.run(app, {:Host => "0.0.0.0", :Port => "300#{i}"}) }
188
+ end
189
+
190
+ puts ANSI::Code::green_on_black { "\n=> Send multiple requests to the proxy by running `ruby balancing-client.rb`\n" }
191
+
192
+ # Start proxy
193
+ BalancingProxy::Server.run
194
+
195
+ end
@@ -0,0 +1,103 @@
1
+ require 'spec/helper'
2
+ require 'examples/balancing'
3
+
4
+ describe BalancingProxy do
5
+
6
+ before(:each) do
7
+ class BalancingProxy::Backend
8
+ @list = nil; @pool = nil
9
+ end
10
+ end
11
+
12
+ before(:all) do
13
+ @original_stdout = $stdout
14
+ # Silence the noisy STDOUT output
15
+ $stdout = File.new('/dev/null', 'w')
16
+ end
17
+
18
+ after(:all) do
19
+ $stdout = @original_stdout
20
+ end
21
+
22
+ context "generally" do
23
+
24
+ it "should raise error for unknown strategy" do
25
+ lambda { BalancingProxy::Backend.select(:asdf)}.should raise_error(ArgumentError)
26
+ end
27
+
28
+ end
29
+
30
+ context "when using the 'random' strategy" do
31
+
32
+ it "should select random backend" do
33
+ class BalancingProxy::Backend
34
+ def self.list
35
+ @list ||= [
36
+ {:url => "http://127.0.0.1:3000"},
37
+ {:url => "http://127.0.0.2:3000"},
38
+ {:url => "http://127.0.0.3:3000"}
39
+ ].map { |backend| new backend }
40
+ end
41
+ end
42
+
43
+ srand(0)
44
+ BalancingProxy::Backend.select(:random).host.should == '127.0.0.1'
45
+ end
46
+
47
+ end
48
+
49
+ context "when using the 'roundrobin' strategy" do
50
+ it "should select backends in rotating order" do
51
+ class BalancingProxy::Backend
52
+ def self.list
53
+ @list ||= [
54
+ {:url => "http://127.0.0.1:3000"},
55
+ {:url => "http://127.0.0.2:3000"},
56
+ {:url => "http://127.0.0.3:3000"}
57
+ ].map { |backend| new backend }
58
+ end
59
+ end
60
+
61
+ BalancingProxy::Backend.select(:roundrobin).host.should == '127.0.0.1'
62
+ BalancingProxy::Backend.select(:roundrobin).host.should == '127.0.0.2'
63
+ BalancingProxy::Backend.select(:roundrobin).host.should == '127.0.0.3'
64
+ BalancingProxy::Backend.select(:roundrobin).host.should == '127.0.0.1'
65
+ end
66
+ end
67
+
68
+ context "when using the 'balanced' strategy" do
69
+
70
+ it "should select the first backend when all backends have the same load" do
71
+ class BalancingProxy::Backend
72
+ def self.list
73
+ @list ||= [
74
+ {:url => "http://127.0.0.3:3000", :load => 0},
75
+ {:url => "http://127.0.0.2:3000", :load => 0},
76
+ {:url => "http://127.0.0.1:3000", :load => 0}
77
+ ].map { |backend| new backend }
78
+ end
79
+ end
80
+
81
+ BalancingProxy::Backend.select.host.should == '127.0.0.3'
82
+ end
83
+
84
+ it "should select the least loaded backend" do
85
+ class BalancingProxy::Backend
86
+ def self.list
87
+ @list ||= [
88
+ {:url => "http://127.0.0.3:3000", :load => 2},
89
+ {:url => "http://127.0.0.2:3000", :load => 1},
90
+ {:url => "http://127.0.0.1:3000", :load => 0}
91
+ ].map { |backend| new backend }
92
+ end
93
+ end
94
+
95
+ BalancingProxy::Backend.select.host.should == '127.0.0.1'
96
+ BalancingProxy::Backend.select.host.should == '127.0.0.1'
97
+ BalancingProxy::Backend.select.host.should == '127.0.0.2'
98
+ BalancingProxy::Backend.select.host.should == '127.0.0.3'
99
+ end
100
+
101
+ end
102
+
103
+ end
data/spec/helper.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'rubygems'
2
- require 'spec'
2
+ require 'rspec'
3
3
  require 'pp'
4
4
  require 'em-http'
5
5
 
6
- require 'lib/em-proxy'
6
+ require 'lib/em-proxy'
data/spec/proxy_spec.rb CHANGED
@@ -54,7 +54,7 @@ describe Proxy do
54
54
 
55
55
  conn.on_response do |backend, resp|
56
56
  backend.should == :goog
57
- resp.should =~ /google/
57
+ resp.size.should >= 0
58
58
  EventMachine.stop
59
59
  end
60
60
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 4
9
- version: 0.1.4
8
+ - 5
9
+ version: 0.1.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ilya Grigorik
@@ -14,12 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-10-03 00:00:00 -04:00
17
+ date: 2011-01-16 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: eventmachine
22
- prerelease: false
23
22
  requirement: &id001 !ruby/object:Gem::Requirement
24
23
  none: false
25
24
  requirements:
@@ -27,25 +26,70 @@ dependencies:
27
26
  - !ruby/object:Gem::Version
28
27
  segments:
29
28
  - 0
30
- - 12
31
- - 9
32
- version: 0.12.9
29
+ version: "0"
33
30
  type: :runtime
31
+ prerelease: false
34
32
  version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ segments:
41
+ - 0
42
+ version: "0"
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: em-http-request
48
+ requirement: &id003 !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *id003
59
+ - !ruby/object:Gem::Dependency
60
+ name: ansi
61
+ requirement: &id004 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ type: :development
70
+ prerelease: false
71
+ version_requirements: *id004
35
72
  description: EventMachine Proxy DSL
36
- email: ilya@igvita.com
37
- executables: []
38
-
73
+ email:
74
+ - ilya@igvita.com
75
+ executables:
76
+ - em-proxy
39
77
  extensions: []
40
78
 
41
- extra_rdoc_files:
42
- - README.rdoc
79
+ extra_rdoc_files: []
80
+
43
81
  files:
82
+ - .gitignore
83
+ - .rspec
84
+ - Gemfile
85
+ - Gemfile.lock
44
86
  - README.rdoc
45
87
  - Rakefile
46
- - VERSION
88
+ - bin/em-proxy
47
89
  - em-proxy.gemspec
48
90
  - examples/appserver.rb
91
+ - examples/balancing-client.rb
92
+ - examples/balancing.rb
49
93
  - examples/beanstalkd_interceptor.rb
50
94
  - examples/duplex.rb
51
95
  - examples/line_interceptor.rb
@@ -60,6 +104,7 @@ files:
60
104
  - lib/em-proxy/backend.rb
61
105
  - lib/em-proxy/connection.rb
62
106
  - lib/em-proxy/proxy.rb
107
+ - spec/balancing_spec.rb
63
108
  - spec/helper.rb
64
109
  - spec/proxy_spec.rb
65
110
  has_rdoc: true
@@ -67,8 +112,8 @@ homepage: http://github.com/igrigorik/em-proxy
67
112
  licenses: []
68
113
 
69
114
  post_install_message:
70
- rdoc_options:
71
- - --charset=UTF-8
115
+ rdoc_options: []
116
+
72
117
  require_paths:
73
118
  - lib
74
119
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -76,6 +121,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
121
  requirements:
77
122
  - - ">="
78
123
  - !ruby/object:Gem::Version
124
+ hash: -2051780992673318158
79
125
  segments:
80
126
  - 0
81
127
  version: "0"
@@ -84,6 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
130
  requirements:
85
131
  - - ">="
86
132
  - !ruby/object:Gem::Version
133
+ hash: -2051780992673318158
87
134
  segments:
88
135
  - 0
89
136
  version: "0"
@@ -95,16 +142,6 @@ signing_key:
95
142
  specification_version: 3
96
143
  summary: EventMachine Proxy DSL
97
144
  test_files:
145
+ - spec/balancing_spec.rb
98
146
  - spec/helper.rb
99
147
  - spec/proxy_spec.rb
100
- - examples/appserver.rb
101
- - examples/beanstalkd_interceptor.rb
102
- - examples/duplex.rb
103
- - examples/line_interceptor.rb
104
- - examples/port_forward.rb
105
- - examples/relay_port_forward.rb
106
- - examples/schemaless-mysql/mysql_interceptor.rb
107
- - examples/selective_forward.rb
108
- - examples/simple.rb
109
- - examples/smtp_spam_filter.rb
110
- - examples/smtp_whitelist.rb
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.1.4