scales-server 0.0.1.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +22 -0
- data/bin/scales-server +7 -0
- data/lib/scales-server.rb +13 -0
- data/lib/scales-server/base.rb +32 -0
- data/lib/scales-server/boot/autoload.rb +4 -0
- data/lib/scales-server/boot/initializers/goliath.rb +2 -0
- data/lib/scales-server/content_type.rb +26 -0
- data/lib/scales-server/dispatch.rb +24 -0
- data/lib/scales-server/dispatch/enqueue.rb +32 -0
- data/lib/scales-server/dispatch/job.rb +15 -0
- data/lib/scales-server/dispatch/lookup.rb +30 -0
- data/lib/scales-server/dispatch/request.rb +29 -0
- data/lib/scales-server/server.rb +16 -0
- data/lib/scales-server/status.rb +68 -0
- data/lib/scales-server/version.rb +5 -0
- metadata +107 -0
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Thomas Fankhauser
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/bin/scales-server
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'scales-server/boot/autoload'
|
2
|
+
|
3
|
+
module Scales
|
4
|
+
module Server
|
5
|
+
autoload :Status, "scales-server/status"
|
6
|
+
autoload :ContentType, "scales-server/content_type"
|
7
|
+
autoload :Server, "scales-server/server"
|
8
|
+
autoload :Dispatch, "scales-server/dispatch"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
require "scales-server/version"
|
13
|
+
require "scales-server/base"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Scales
|
2
|
+
module Server
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def run!
|
6
|
+
ARGV << "--stdout" << "--environment" << "#{Scales.env}"
|
7
|
+
|
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)
|
12
|
+
|
13
|
+
status = Status.new(runner.address, runner.port)
|
14
|
+
status.start!
|
15
|
+
at_exit{ status.stop! }
|
16
|
+
Scales::Server.status = status
|
17
|
+
|
18
|
+
runner.run
|
19
|
+
end
|
20
|
+
|
21
|
+
@@status = nil
|
22
|
+
def status
|
23
|
+
@@status
|
24
|
+
end
|
25
|
+
|
26
|
+
def status=(status)
|
27
|
+
@@status = status
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Scales
|
2
|
+
module Server
|
3
|
+
|
4
|
+
class ContentType
|
5
|
+
include Goliath::Rack::AsyncMiddleware
|
6
|
+
|
7
|
+
TYPES = Scales::Helper::ContentTypes::TYPES
|
8
|
+
|
9
|
+
def initialize(app, format = 'html')
|
10
|
+
@app, @format = app, format
|
11
|
+
end
|
12
|
+
|
13
|
+
def post_process(env, status, headers, body)
|
14
|
+
headers['Content-Type'] = parse_from_format?(env['REQUEST_URI'])
|
15
|
+
[status, headers, body]
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse_from_format?(uri)
|
19
|
+
content_type = TYPES[@format.to_sym]
|
20
|
+
TYPES.each { |format, type| content_type = type and break if uri =~ /\.#{format}(\?|$)/ }
|
21
|
+
content_type
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Scales
|
2
|
+
module Server
|
3
|
+
module Dispatch
|
4
|
+
autoload :Lookup, "scales-server/dispatch/lookup"
|
5
|
+
autoload :Enqueue, "scales-server/dispatch/enqueue"
|
6
|
+
autoload :Request, "scales-server/dispatch/request"
|
7
|
+
autoload :Job, "scales-server/dispatch/job"
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
def request(env)
|
12
|
+
if is_get_request?(env) then Lookup.ressource(env) else Enqueue.request(env) end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def is_get_request?(env)
|
18
|
+
env["REQUEST_METHOD"] == "GET"
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Scales
|
2
|
+
module Server
|
3
|
+
module Dispatch
|
4
|
+
module Enqueue
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def request(env)
|
8
|
+
id = create_random_id
|
9
|
+
job = Request.to_job(id, env)
|
10
|
+
|
11
|
+
Scales::Server.status.put_request_in_queue!(job)
|
12
|
+
Queue::Async.add(JSON.generate(job))
|
13
|
+
|
14
|
+
response = PubSub::Async.subscribe("scales_response_#{id}")
|
15
|
+
response = Job.to_response(response)
|
16
|
+
Scales::Server.status.took_response_from_queue!(response)
|
17
|
+
response
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def create_random_id
|
23
|
+
id = SecureRandom.hex(16)
|
24
|
+
Storage::Async.connection.set("test_last_request_id", "scales_response_#{id}") if Goliath.env == :test
|
25
|
+
id
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Scales
|
2
|
+
module Server
|
3
|
+
module Dispatch
|
4
|
+
module Lookup
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def ressource(env)
|
8
|
+
response = Storage::Async.get_content(path(env), Scales.config.partials)
|
9
|
+
response.nil? ? render_not_found : render(response)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def path(env)
|
15
|
+
env["REQUEST_URI"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def render_not_found
|
19
|
+
[404, {}, "Not found"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def render(response)
|
23
|
+
[200, {}, response]
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Scales
|
2
|
+
module Server
|
3
|
+
module Dispatch
|
4
|
+
module Request
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def to_job(id, env)
|
8
|
+
scales_variables = { 'scales.id' => id }
|
9
|
+
request_variables = env.dup.keep_if{ |key, value| [
|
10
|
+
'REQUEST_METHOD',
|
11
|
+
'PATH_INFO',
|
12
|
+
'QUERY_STRING',
|
13
|
+
'SERVER_NAME',
|
14
|
+
'SERVER_PORT'
|
15
|
+
].include?(key) }
|
16
|
+
http_variables = env.dup.keep_if{ |key, value| key.match /^HTTP_/ }
|
17
|
+
rack_variables = {
|
18
|
+
'rack.version' => env['rack.version'],
|
19
|
+
'rack.url_scheme' => env['rack.url_scheme'],
|
20
|
+
'rack.input' => env['rack.input'].string
|
21
|
+
}
|
22
|
+
scales_variables.merge(request_variables).merge(http_variables).merge(rack_variables)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Scales
|
2
|
+
module Server
|
3
|
+
|
4
|
+
class Status
|
5
|
+
attr_reader :key, :id, :address, :port
|
6
|
+
|
7
|
+
def initialize address, port
|
8
|
+
@id = SecureRandom.hex(8)
|
9
|
+
@key = "scales_server_#{@id}"
|
10
|
+
@address, @port = address.to_s, port.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
def start!
|
14
|
+
data = {
|
15
|
+
:id => @id,
|
16
|
+
:key => @key,
|
17
|
+
:type => "server_started",
|
18
|
+
:spawned_at => Time.now.to_i,
|
19
|
+
:env => Scales.env,
|
20
|
+
:ip => @address,
|
21
|
+
:port => @port
|
22
|
+
}
|
23
|
+
json = JSON.generate(data)
|
24
|
+
|
25
|
+
Storage::Sync.connection.set(@key, json)
|
26
|
+
Storage::Sync.connection.publish("scales_monitor_events", json)
|
27
|
+
end
|
28
|
+
|
29
|
+
def stop!
|
30
|
+
data = {
|
31
|
+
:id => @id,
|
32
|
+
:key => @key,
|
33
|
+
:type => "server_stopped"
|
34
|
+
}
|
35
|
+
json = JSON.generate(data)
|
36
|
+
Storage::Sync.connection.del(@key)
|
37
|
+
Storage::Sync.connection.publish("scales_monitor_events", json)
|
38
|
+
end
|
39
|
+
|
40
|
+
def put_request_in_queue!(job)
|
41
|
+
data = {
|
42
|
+
:id => job['scales.id'],
|
43
|
+
:server_id => @id,
|
44
|
+
:type => "server_put_request_in_queue",
|
45
|
+
:path => job['PATH_INFO'],
|
46
|
+
:method => job['REQUEST_METHOD']
|
47
|
+
}
|
48
|
+
json = JSON.generate(data)
|
49
|
+
Storage::Sync.connection.publish("scales_monitor_events", json)
|
50
|
+
end
|
51
|
+
|
52
|
+
def took_response_from_queue!(response)
|
53
|
+
data = {
|
54
|
+
:id => response[1]['scales.id'],
|
55
|
+
:server_id => @id,
|
56
|
+
:type => "server_took_response_from_queue",
|
57
|
+
:path => response[1]['PATH_INFO'],
|
58
|
+
:method => response[1]['REQUEST_METHOD'],
|
59
|
+
:status => response[0]
|
60
|
+
}
|
61
|
+
json = JSON.generate(data)
|
62
|
+
Storage::Sync.connection.publish("scales_monitor_events", json)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: scales-server
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.beta.1
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Thomas Fankhauser
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &70229981956660 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.2.2
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70229981956660
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &70229981955500 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.11'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70229981955500
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: scales-core
|
38
|
+
requirement: &70229981954700 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - =
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.0.1.beta.1
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70229981954700
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: goliath
|
49
|
+
requirement: &70229981975600 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.0.0.beta.1
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70229981975600
|
58
|
+
description: Super Scale Caching Framework - Server
|
59
|
+
email:
|
60
|
+
- tommylefunk@googlemail.com
|
61
|
+
executables:
|
62
|
+
- scales-server
|
63
|
+
extensions: []
|
64
|
+
extra_rdoc_files: []
|
65
|
+
files:
|
66
|
+
- LICENSE
|
67
|
+
- lib/scales-server/base.rb
|
68
|
+
- lib/scales-server/boot/autoload.rb
|
69
|
+
- lib/scales-server/boot/initializers/goliath.rb
|
70
|
+
- lib/scales-server/content_type.rb
|
71
|
+
- lib/scales-server/dispatch/enqueue.rb
|
72
|
+
- lib/scales-server/dispatch/job.rb
|
73
|
+
- lib/scales-server/dispatch/lookup.rb
|
74
|
+
- lib/scales-server/dispatch/request.rb
|
75
|
+
- lib/scales-server/dispatch.rb
|
76
|
+
- lib/scales-server/server.rb
|
77
|
+
- lib/scales-server/status.rb
|
78
|
+
- lib/scales-server/version.rb
|
79
|
+
- lib/scales-server.rb
|
80
|
+
- !binary |-
|
81
|
+
YmluL3NjYWxlcy1zZXJ2ZXI=
|
82
|
+
homepage: http://itscales.org
|
83
|
+
licenses: []
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ! '>'
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 1.3.1
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 1.8.11
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: Serves all requests asynchronous from the cache and puts jobs into the request
|
106
|
+
queue for the workers.
|
107
|
+
test_files: []
|