scales-server 0.0.1.beta.2 → 0.0.4
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/bin/scales-server-proxy +17 -0
- data/lib/scales-server.rb +1 -0
- data/lib/scales-server/base.rb +8 -6
- data/lib/scales-server/boot/autoload.rb +2 -1
- data/lib/scales-server/boot/initializers/proxy.rb +2 -0
- data/lib/scales-server/dispatch.rb +2 -1
- data/lib/scales-server/dispatch/enqueue.rb +3 -4
- data/lib/scales-server/dispatch/lookup.rb +1 -1
- data/lib/scales-server/dispatch/response.rb +49 -0
- data/lib/scales-server/proxy.rb +31 -0
- data/lib/scales-server/proxy/backend.rb +66 -0
- data/lib/scales-server/proxy/callbacks.rb +31 -0
- data/lib/scales-server/version.rb +1 -1
- metadata +33 -14
@@ -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)
|
data/lib/scales-server.rb
CHANGED
data/lib/scales-server/base.rb
CHANGED
@@ -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
|
-
|
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
|
@@ -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.
|
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
|
-
|
12
|
+
Storage::Async.add(Storage::REQUEST_QUEUE, JSON.generate(job))
|
13
13
|
|
14
|
-
response =
|
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",
|
23
|
+
Storage::Async.connection.set("test_last_request_id", id) if Goliath.env == :test
|
25
24
|
id
|
26
25
|
end
|
27
26
|
|
@@ -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
|
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.
|
5
|
-
prerelease:
|
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-
|
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: &
|
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: *
|
24
|
+
version_requirements: *70195223931780
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
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: *
|
35
|
+
version_requirements: *70195223931280
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: scales-core
|
38
|
-
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.
|
43
|
+
version: 0.0.4
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70195223930840
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: goliath
|
49
|
-
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: *
|
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:
|
118
|
+
version: '0'
|
100
119
|
requirements: []
|
101
120
|
rubyforge_project:
|
102
121
|
rubygems_version: 1.8.11
|