wildcloud-router 0.0.2 → 0.0.3

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/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