scales-server 0.0.1.beta.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'scales-server'
4
+
5
+ Scales.pwd = Dir.pwd
6
+
7
+ @port = 3000
8
+ @servers = []
9
+
10
+ arguments = ARGV.dup
11
+ while !arguments.empty? do
12
+ argument = arguments.shift
13
+ if argument == "-p" or argument == "--port" then @port = arguments.shift else @servers << argument end
14
+ end
15
+
16
+ Scales::Server::Proxy::Backend.add(@servers)
17
+ Scales::Server::Proxy.run!("0.0.0.0", @port)
@@ -5,6 +5,7 @@ module Scales
5
5
  autoload :Status, "scales-server/status"
6
6
  autoload :ContentType, "scales-server/content_type"
7
7
  autoload :Server, "scales-server/server"
8
+ autoload :Proxy, "scales-server/proxy"
8
9
  autoload :Dispatch, "scales-server/dispatch"
9
10
  end
10
11
  end
@@ -6,16 +6,18 @@ module Scales
6
6
  ARGV << "--environment" << "#{Scales.env}"
7
7
 
8
8
  server = Server.new
9
- runner = Goliath::Runner.new(ARGV, server)
10
- runner.app = Goliath::Rack::Builder.build(Server, server)
11
- runner.load_plugins(Server.plugins)
9
+ @runner = Goliath::Runner.new(ARGV, server)
10
+ @runner.app = Goliath::Rack::Builder.build(Server, server)
11
+ @runner.load_plugins(Server.plugins)
12
12
 
13
- status = Status.new(runner.address, runner.port)
13
+ status = Status.new(@runner.address, @runner.port)
14
14
  status.start!
15
- at_exit{ status.stop! }
16
15
  Scales::Server.status = status
17
16
 
18
- runner.run
17
+ @pid ||= Process.pid
18
+ at_exit{ status.stop! if !@runner.daemonize or Process.pid != @pid }
19
+
20
+ @runner.run
19
21
  end
20
22
 
21
23
  @@status = nil
@@ -1,4 +1,5 @@
1
1
  require 'scales-core'
2
2
  require 'securerandom'
3
3
 
4
- autoload :Goliath, "scales-server/boot/initializers/goliath"
4
+ autoload :Goliath, "scales-server/boot/initializers/goliath"
5
+ autoload :Proxy, "scales-server/boot/initializers/proxy"
@@ -0,0 +1,2 @@
1
+ require 'em-proxy'
2
+ require 'uri'
@@ -4,12 +4,13 @@ module Scales
4
4
  autoload :Lookup, "scales-server/dispatch/lookup"
5
5
  autoload :Enqueue, "scales-server/dispatch/enqueue"
6
6
  autoload :Request, "scales-server/dispatch/request"
7
+ autoload :Response, "scales-server/dispatch/response"
7
8
  autoload :Job, "scales-server/dispatch/job"
8
9
 
9
10
  class << self
10
11
 
11
12
  def request(env)
12
- if is_get_request?(env) then Lookup.ressource(env) else Enqueue.request(env) end
13
+ if is_get_request?(env) then Lookup.resource(env) else Enqueue.request(env) end
13
14
  end
14
15
 
15
16
  private
@@ -9,10 +9,9 @@ module Scales
9
9
  job = Request.to_job(id, env)
10
10
 
11
11
  Scales::Server.status.put_request_in_queue!(job)
12
- Queue::Async.add(JSON.generate(job))
12
+ Storage::Async.add(Storage::REQUEST_QUEUE, JSON.generate(job))
13
13
 
14
- response = PubSub::Async.subscribe("scales_response_#{id}")
15
- response = Job.to_response(response)
14
+ response = Response.subscribe(id)
16
15
  Scales::Server.status.took_response_from_queue!(response)
17
16
  response
18
17
  end
@@ -21,7 +20,7 @@ module Scales
21
20
 
22
21
  def create_random_id
23
22
  id = SecureRandom.hex(16)
24
- Storage::Async.connection.set("test_last_request_id", "scales_response_#{id}") if Goliath.env == :test
23
+ Storage::Async.connection.set("test_last_request_id", id) if Goliath.env == :test
25
24
  id
26
25
  end
27
26
 
@@ -4,7 +4,7 @@ module Scales
4
4
  module Lookup
5
5
  class << self
6
6
 
7
- def ressource(env)
7
+ def resource(env)
8
8
  response = Storage::Async.get_content(path(env), Scales.config.partials)
9
9
  response.nil? ? render_not_found : render(response)
10
10
  end
@@ -0,0 +1,49 @@
1
+ module Scales
2
+ module Server
3
+ module Dispatch
4
+ module Response
5
+ class << self
6
+
7
+ @@redis = nil
8
+ @@subscribers = {}
9
+ @@subscribed = false
10
+
11
+ def subscribe(id)
12
+ setup_subscription!
13
+ @@subscribers[id] = Fiber.current
14
+ Fiber.yield
15
+ end
16
+
17
+ def reset!
18
+ @@redis = nil
19
+ @@subscribers = {}
20
+ @@subscribed = false
21
+ end
22
+
23
+ private
24
+
25
+ def connect!
26
+ return if @@redis and @@redis.connected?
27
+ @@redis = Storage::Async.new_connection!
28
+ end
29
+
30
+ def setup_subscription!
31
+ connect!
32
+ return if @@subscribed
33
+
34
+ @@redis.subscribe(Storage::RESPONSE_CHANNEL)
35
+ @@redis.on(:message) do |channel, message|
36
+ response = Job.to_response(message)
37
+ id = response[1]['scales.id']
38
+
39
+ fiber = @@subscribers.delete(id)
40
+ fiber.resume(response) if fiber
41
+ end
42
+ @@subscribed = true
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,31 @@
1
+ module Scales
2
+ module Server
3
+ module Proxy
4
+ autoload :Backend, "scales-server/proxy/backend"
5
+ autoload :Callbacks, "scales-server/proxy/callbacks"
6
+
7
+ class << self
8
+
9
+ def run!(host = '0.0.0.0', port = 9999)
10
+
11
+ puts "Proxy Port: #{port}".green
12
+ puts "Server Ports: #{Backend.ports.join(', ')}".green
13
+
14
+ ::Proxy.start(:host => host, :port => port, :debug => false) do |connection|
15
+
16
+ Backend.select do |backend|
17
+ connection.server backend, :host => backend.host, :port => backend.port
18
+
19
+ connection.on_connect &Callbacks.on_connect
20
+ connection.on_data &Callbacks.on_data
21
+ connection.on_response &Callbacks.on_response
22
+ connection.on_finish &Callbacks.on_finish
23
+ end
24
+
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,66 @@
1
+ module Scales
2
+ module Server
3
+ module Proxy
4
+
5
+ class Backend
6
+ @ports = []
7
+ attr_reader :url, :host, :port
8
+ attr_accessor :load
9
+ alias :to_s :url
10
+
11
+ def initialize(options={})
12
+ raise ArgumentError, "Please provide a :url and :load" unless options[:url]
13
+ @url = options[:url]
14
+ @load = options[:load] || 0
15
+ parsed = URI.parse(@url)
16
+ @host, @port = parsed.host, parsed.port
17
+ end
18
+
19
+ def self.add(ports)
20
+ ports.each{ |port| @ports << { :url => "http://0.0.0.0:#{port}" } }
21
+ end
22
+
23
+ def self.ports
24
+ @ports.map{ |port| port[:url].split(":").last }
25
+ end
26
+
27
+ def self.select(strategy = :balanced)
28
+ @strategy = strategy.to_sym
29
+ case @strategy
30
+ when :balanced
31
+ backend = list.sort_by { |b| b.load }.first
32
+ when :roundrobin
33
+ @pool = list.clone if @pool.nil? || @pool.empty?
34
+ backend = @pool.shift
35
+ when :random
36
+ backend = list[ rand(list.size-1) ]
37
+ else
38
+ raise ArgumentError, "Unknown strategy: #{@strategy}"
39
+ end
40
+
41
+ Callbacks.on_select.call(backend)
42
+ yield backend if block_given?
43
+ backend
44
+ end
45
+
46
+ def self.list
47
+ @list ||= @ports.map { |backend| new backend }
48
+ end
49
+
50
+ def self.strategy
51
+ @strategy
52
+ end
53
+
54
+ def increment_counter
55
+ self.load += 1
56
+ end
57
+
58
+ def decrement_counter
59
+ self.load -= 1
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,31 @@
1
+ module Scales
2
+ module Server
3
+ module Proxy
4
+
5
+ module Callbacks
6
+ extend self
7
+
8
+ def on_connect
9
+ end
10
+
11
+ def on_data
12
+ lambda { |data| data }
13
+ end
14
+
15
+ def on_response
16
+ lambda { |backend, response| response }
17
+ end
18
+
19
+ def on_select
20
+ lambda { |backend| backend.increment_counter if Backend.strategy == :balanced }
21
+ end
22
+
23
+ def on_finish
24
+ lambda { |backend| backend.decrement_counter if Backend.strategy == :balanced }
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -1,5 +1,5 @@
1
1
  module Scales
2
2
  module Server
3
- VERSION = "0.0.1.beta.2"
3
+ VERSION = "0.0.4"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scales-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.beta.2
5
- prerelease: 6
4
+ version: 0.0.4
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Thomas Fankhauser
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-01 00:00:00.000000000 Z
12
+ date: 2012-08-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &70117378273540 !ruby/object:Gem::Requirement
16
+ requirement: &70195223931780 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.9.2.2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70117378273540
24
+ version_requirements: *70195223931780
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &70117378271400 !ruby/object:Gem::Requirement
27
+ requirement: &70195223931280 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,21 +32,21 @@ dependencies:
32
32
  version: '2.11'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70117378271400
35
+ version_requirements: *70195223931280
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: scales-core
38
- requirement: &70117378269120 !ruby/object:Gem::Requirement
38
+ requirement: &70195223930840 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - =
42
42
  - !ruby/object:Gem::Version
43
- version: 0.0.1.beta.2
43
+ version: 0.0.4
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70117378269120
46
+ version_requirements: *70195223930840
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: goliath
49
- requirement: &70117378283580 !ruby/object:Gem::Requirement
49
+ requirement: &70195223930340 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,12 +54,24 @@ dependencies:
54
54
  version: 1.0.0.beta.1
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70117378283580
57
+ version_requirements: *70195223930340
58
+ - !ruby/object:Gem::Dependency
59
+ name: em-proxy
60
+ requirement: &70195223929840 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: 0.1.6
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70195223929840
58
69
  description: Super Scale Caching Framework - Server
59
70
  email:
60
71
  - tommylefunk@googlemail.com
61
72
  executables:
62
73
  - scales-server
74
+ - scales-server-proxy
63
75
  extensions: []
64
76
  extra_rdoc_files: []
65
77
  files:
@@ -67,18 +79,25 @@ files:
67
79
  - lib/scales-server/base.rb
68
80
  - lib/scales-server/boot/autoload.rb
69
81
  - lib/scales-server/boot/initializers/goliath.rb
82
+ - lib/scales-server/boot/initializers/proxy.rb
70
83
  - lib/scales-server/content_type.rb
71
84
  - lib/scales-server/dispatch/enqueue.rb
72
85
  - lib/scales-server/dispatch/job.rb
73
86
  - lib/scales-server/dispatch/lookup.rb
74
87
  - lib/scales-server/dispatch/request.rb
88
+ - lib/scales-server/dispatch/response.rb
75
89
  - lib/scales-server/dispatch.rb
90
+ - lib/scales-server/proxy/backend.rb
91
+ - lib/scales-server/proxy/callbacks.rb
92
+ - lib/scales-server/proxy.rb
76
93
  - lib/scales-server/server.rb
77
94
  - lib/scales-server/status.rb
78
95
  - lib/scales-server/version.rb
79
96
  - lib/scales-server.rb
80
97
  - !binary |-
81
98
  YmluL3NjYWxlcy1zZXJ2ZXI=
99
+ - !binary |-
100
+ YmluL3NjYWxlcy1zZXJ2ZXItcHJveHk=
82
101
  homepage: http://itscales.org
83
102
  licenses: []
84
103
  post_install_message:
@@ -94,9 +113,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
94
113
  required_rubygems_version: !ruby/object:Gem::Requirement
95
114
  none: false
96
115
  requirements:
97
- - - ! '>'
116
+ - - ! '>='
98
117
  - !ruby/object:Gem::Version
99
- version: 1.3.1
118
+ version: '0'
100
119
  requirements: []
101
120
  rubyforge_project:
102
121
  rubygems_version: 1.8.11