wildcloud-router 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 0.0.3 (30.12.2011)
2
+
3
+ * big rewrite
4
+ * depend on wildcloud-logger and wildcloud-configuration
5
+ * reporting
6
+ * basic support for keep-alive from clients
7
+
1
8
  ## 0.0.2 (30.12.2011)
2
9
 
3
10
  * bugfix: race condition in connection to backend server
data/bin/wildcloud-router CHANGED
@@ -22,6 +22,14 @@ require 'eventmachine'
22
22
 
23
23
  require 'wildcloud/router/server'
24
24
 
25
+ begin
26
+ EventMachine.epoll
27
+ end
28
+
29
+ begin
30
+ EventMachine.kqueue
31
+ end
32
+
25
33
  EventMachine.run do
26
34
  Wildcloud::Router::Server.start
27
35
  end
@@ -0,0 +1,23 @@
1
+ module Wildcloud
2
+ module Router
3
+ class Cache
4
+
5
+ def self.put(target, connection)
6
+ @connections ||= {}
7
+ @connections[target] ||= []
8
+ @connections << connection
9
+ end
10
+
11
+ def self.get(target)
12
+ @connections ||= {}
13
+ @connections[target] ||= []
14
+ @connections[target].shift
15
+ end
16
+
17
+ def self.inspect
18
+ @connections.inspect
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -18,52 +18,72 @@ module Wildcloud
18
18
  module Router
19
19
  module Client
20
20
 
21
- def initialize(proxy)
22
- @proxy = proxy
21
+ def initialize(target)
22
+ @target = target
23
23
  @closed = false
24
- @parser = Http::Parser.new(self)
25
- @buffer = []
26
- @time = Time.now
27
24
  end
28
25
 
29
- def closed?
30
- @closed
31
- end
26
+ # EventMachine
32
27
 
33
28
  def post_init
34
- send_line("#{@proxy.request_method} #{@proxy.request_url} HTTP/#{@proxy.request_version}")
35
- @proxy.request_headers.each do |name, value|
36
- send_line("#{name}: #{value}")
37
- end
38
- send_line('')
39
- send_data(@proxy.buffer)
40
- EventMachine.enable_proxy(@proxy, self)
29
+ @parser = Http::ResponseParser.new(self)
41
30
  end
42
31
 
43
32
  def receive_data(data)
33
+ @outbound += data.size
44
34
  @parser << data
45
35
  rescue Http::Parser::Error => error
46
36
  Router.logger.debug('Proxy client') { "Error #{error}" }
47
37
  end
48
38
 
39
+ def unbind
40
+ @parser = nil
41
+ @stop_time = Time.now
42
+ Router.monitor.request(@target, @stop_time - @proxy.start_time, @inbound, @outbound)
43
+ @closed = true
44
+ @proxy.close_connection(true) if @proxy and !@proxy.closed?
45
+ end
46
+
47
+ # HTTP parser
48
+
49
49
  def on_headers_complete(headers)
50
50
  @proxy.send_line("HTTP/#{@parser.http_version.join('.')} #{@parser.status_code} #{CODE[@parser.status_code]}")
51
51
  headers.each do |name, value|
52
52
  @proxy.send_line("#{name}: #{value}")
53
53
  end
54
54
  @proxy.send_line('')
55
- EventMachine.enable_proxy(self, @proxy)
56
- end
57
-
58
- def unbind
59
- @closed = true
60
- @proxy.close_connection(true) if @proxy and !@proxy.closed?
61
55
  end
62
56
 
63
57
  def on_body(chunk)
64
58
  @proxy.send_data(chunk)
65
59
  end
66
60
 
61
+ def on_message_complete
62
+ close_connection
63
+ end
64
+
65
+ # Tools
66
+
67
+ def make_request(proxy, version, method, url, headers)
68
+ @proxy = proxy
69
+ @inbound = 0
70
+ @outbound = 0
71
+ send_line("#{method} #{url} HTTP/#{version}")
72
+ headers.each do |name, value|
73
+ send_line("#{name}: #{value}")
74
+ end
75
+ send_line('')
76
+ end
77
+
78
+ def send_data(data)
79
+ @inbound += data.size
80
+ super(data)
81
+ end
82
+
83
+ def closed?
84
+ @closed
85
+ end
86
+
67
87
  def send_line(data)
68
88
  send_data("#{data}\r\n")
69
89
  end
@@ -14,17 +14,19 @@
14
14
  require 'yaml'
15
15
 
16
16
  require 'wildcloud/router/logger'
17
+ require 'wildcloud/configuration'
17
18
 
18
19
  module Wildcloud
19
20
  module Router
21
+
20
22
  def self.configuration
21
23
  return @configuration if @configuration
22
- file = '/etc/wildcloud/router.yml'
23
- unless File.exists?(file)
24
- file = './router.yml'
24
+ config = Wildcloud::Configuration.load('router')
25
+ config.sources.each do |source|
26
+ self.logger.info('Configuration', "Loaded configuration from #{source}")
25
27
  end
26
- Router.logger.info('Config') { "Loading from file #{file}" }
27
- @configuration = YAML.load_file(file)
28
+ @configuration = config.configuration
28
29
  end
30
+
29
31
  end
30
32
  end
@@ -41,6 +41,7 @@ module Wildcloud
41
41
  def connect_amqp
42
42
  Router.logger.info('Core') { "Connecting to broker" }
43
43
  @amqp = AMQP.connect(Router.configuration["amqp"])
44
+ Router.logger_add_amqp(@amqp)
44
45
  @channel = AMQP::Channel.new(@amqp)
45
46
  # Communication infrastructure
46
47
  @topic = @channel.topic('wildcloud.router')
@@ -64,12 +65,12 @@ module Wildcloud
64
65
  @routes = data['routes']
65
66
  end
66
67
 
67
- def parse_target(target)
68
- target = target.split(':')
68
+ def parse_target(raw_target)
69
+ target = raw_target.split(':')
69
70
  if target.size == 1
70
- { "socket" => target[0] }
71
+ { "socket" => target[0]}
71
72
  else
72
- { "address" => target[0], "port" => target[1] }
73
+ { "address" => target[0], "port" => target[1]}
73
74
  end
74
75
  end
75
76
 
@@ -27,12 +27,15 @@ module Wildcloud
27
27
  @logger = Wildcloud::Logger::Logger.new
28
28
  @logger.application = 'wildcloud.router'
29
29
  @logger.add(Wildcloud::Logger::Middleware::Console)
30
- @logger.add(Wildcloud::Logger::Middleware::Json)
31
- @topic = AMQP::Channel.new(Core.instance.amqp).topic('wildcloud.logger')
32
- @logger.add(Wildcloud::Logger::Middleware::Amqp, :exchange => @topic, :routing_key => 'wildcloud.router')
33
30
  end
34
31
  @logger
35
32
  end
36
33
 
34
+ def self.logger_add_amqp(amqp)
35
+ logger.add(Wildcloud::Logger::Middleware::Json)
36
+ @topic = AMQP::Channel.new(amqp).topic('wildcloud.logger')
37
+ logger.add(Wildcloud::Logger::Middleware::Amqp, :exchange => @topic, :routing_key => 'wildcloud.router')
38
+ end
39
+
37
40
  end
38
41
  end
@@ -0,0 +1,52 @@
1
+ module Wildcloud
2
+ module Router
3
+
4
+ def self.monitor
5
+ @monitor ||= Monitor.new
6
+ end
7
+
8
+ class Monitor
9
+
10
+ def initialize
11
+ @channel = AMQP::Channel.new(Core.instance.amqp)
12
+ @topic = @channel.topic('wildcloud.monitor')
13
+ @data = setup
14
+ EventMachine.add_periodic_timer(1, &method(:report))
15
+ end
16
+
17
+ def report
18
+ data, @data = @data, setup
19
+ puts data.inspect
20
+ @topic.publish(JSON.dump(data), :routing_key => 'router')
21
+ end
22
+
23
+ def setup
24
+ {
25
+ :published_at => Time.now.to_i,
26
+ :node => Router.configuration['node']['name'],
27
+ :count => 0,
28
+ :inbound => 0,
29
+ :outbound => 0,
30
+ :time => 0,
31
+ :target => {},
32
+ }
33
+ end
34
+
35
+ def request(target, time, inbound, outbound)
36
+ return unless target
37
+ target = "#{target['address']}:#{target['port']}"
38
+ @data[:count] += 1
39
+ @data[:inbound] += inbound
40
+ @data[:outbound] += outbound
41
+ @data[:time] += time
42
+ #@data[:target][target] ||= {:count => 0, :outbound => 0, :inbound => 0, :time => 0}
43
+ #@data[:target][target][:count] += 1
44
+ #@data[:target][target][:time] += time
45
+ #@data[:target][target][:inbound] += inbound
46
+ #@data[:target][target][:outbound] += outbound
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+ end
@@ -15,39 +15,27 @@
15
15
  require 'http/parser'
16
16
 
17
17
  require 'wildcloud/router/client'
18
+ require 'wildcloud/router/monitor'
18
19
 
19
20
  module Wildcloud
20
21
  module Router
21
22
  module Proxy
22
23
 
23
- attr_reader :core, :request_headers, :buffer, :request_version, :request_method, :request_url
24
+ attr_reader :core, :start_time
24
25
 
25
26
  def initialize(core)
26
27
  @core = core
27
- @parser = Http::Parser.new(self)
28
- @buffer = []
29
28
  @closed = false
30
- @time = Time.now
31
- @request_headers = nil
32
29
  end
33
30
 
34
- def post_init
35
- end
31
+ # EventMachine
36
32
 
37
- def closed?
38
- @closed
33
+ def post_init
39
34
  end
40
35
 
41
36
  def receive_data(data)
42
- offset = @parser << data
43
- if @request_headers
44
- @buffer = data[offset..-1]
45
- if @target["socket"]
46
- @client = EventMachine.connect(@target["socket"], Router::Client, self)
47
- else
48
- @client = EventMachine.connect(@target["address"], @target["port"], Router::Client, self)
49
- end
50
- end
37
+ @parser ||= Http::RequestParser.new(self)
38
+ @parser << data
51
39
  rescue HTTP::Parser::Error => error
52
40
  Router.logger.debug('Proxy') { "Error during parsing #{error.message}" }
53
41
  end
@@ -57,15 +45,36 @@ module Wildcloud
57
45
  @client.close_connection(true) if @client and !@client.closed?
58
46
  end
59
47
 
48
+ # HTTP parser
49
+
50
+ def on_message_begin
51
+ @start_time = Time.now
52
+ end
53
+
60
54
  def on_headers_complete(headers)
61
- @request_headers = headers
62
- @request_version = @parser.http_version.join('.')
63
- @request_method = @parser.http_method
64
- @request_url = @parser.request_url
65
- return bad_request unless @request_headers['Host']
66
- @target = @core.resolve(@request_headers['Host'])
67
- return bad_request unless @target
68
- :stop
55
+ return bad_request unless headers['Host']
56
+ target = @core.resolve(headers['Host'])
57
+ return bad_request unless target
58
+ if target["socket"]
59
+ @client = EventMachine.connect(target["socket"], Router::Client, target)
60
+ else
61
+ @client = EventMachine.connect(target["address"], target["port"], Router::Client, target)
62
+ end
63
+ @client.make_request(self, @parser.http_version.join('.'), @parser.http_method, @parser.request_url, headers)
64
+ end
65
+
66
+ def on_body(chunk)
67
+ @client.send_data(chunk)
68
+ end
69
+
70
+ def on_message_complete
71
+ @parser = nil
72
+ end
73
+
74
+ # Tools
75
+
76
+ def closed?
77
+ @closed
69
78
  end
70
79
 
71
80
  def bad_request
@@ -73,10 +82,6 @@ module Wildcloud
73
82
  :stop
74
83
  end
75
84
 
76
- def on_body(chunk)
77
- @buffer << chunk
78
- end
79
-
80
85
  def send_line(data)
81
86
  send_data("#{data}\r\n")
82
87
  end
@@ -14,6 +14,6 @@
14
14
 
15
15
  module Wildcloud
16
16
  module Router
17
- VERSION = '0.0.2' unless const_defined?(:VERSION)
17
+ VERSION = '0.0.3' unless const_defined?(:VERSION)
18
18
  end
19
19
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wildcloud-router
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-30 00:00:00.000000000 Z
12
+ date: 2012-01-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: amqp
16
- requirement: &2161097640 !ruby/object:Gem::Requirement
16
+ requirement: &2153214940 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - =
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.8.4
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2161097640
24
+ version_requirements: *2153214940
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: http_parser.rb
27
- requirement: &2161097140 !ruby/object:Gem::Requirement
27
+ requirement: &2153214200 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - =
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.5.3
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2161097140
35
+ version_requirements: *2153214200
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: json
38
- requirement: &2161096640 !ruby/object:Gem::Requirement
38
+ requirement: &2153213680 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - =
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.6.4
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2161096640
46
+ version_requirements: *2153213680
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: wildcloud-logger
49
- requirement: &2161096160 !ruby/object:Gem::Requirement
49
+ requirement: &2153213220 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - =
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: 0.0.1
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *2161096160
57
+ version_requirements: *2153213220
58
58
  description: Routes requests across the platform
59
59
  email:
60
60
  - marek@jelen.biz
@@ -64,10 +64,12 @@ extensions: []
64
64
  extra_rdoc_files: []
65
65
  files:
66
66
  - bin/wildcloud-router
67
+ - lib/wildcloud/router/cache.rb
67
68
  - lib/wildcloud/router/client.rb
68
69
  - lib/wildcloud/router/configuration.rb
69
70
  - lib/wildcloud/router/core.rb
70
71
  - lib/wildcloud/router/logger.rb
72
+ - lib/wildcloud/router/monitor.rb
71
73
  - lib/wildcloud/router/proxy.rb
72
74
  - lib/wildcloud/router/server.rb
73
75
  - lib/wildcloud/router/version.rb