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 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.
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'scales-server'
4
+
5
+ Scales.pwd = Dir.pwd
6
+ Scales.try_to_setup_env!
7
+ Scales::Server.run!
@@ -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,4 @@
1
+ require 'scales-core'
2
+ require 'securerandom'
3
+
4
+ autoload :Goliath, "scales-server/boot/initializers/goliath"
@@ -0,0 +1,2 @@
1
+ require 'goliath'
2
+ require 'goliath/test_helper'
@@ -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,15 @@
1
+ module Scales
2
+ module Server
3
+ module Dispatch
4
+ module Job
5
+ class << self
6
+
7
+ def to_response(response)
8
+ JSON.parse(response)
9
+ end
10
+
11
+ end
12
+ end
13
+ end
14
+ end
15
+ 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,16 @@
1
+ module Scales
2
+ module Server
3
+
4
+ class Server < Goliath::API
5
+ use Goliath::Rack::Params
6
+ use Goliath::Rack::DefaultMimeType
7
+ use ContentType, 'html'
8
+
9
+ def response(env)
10
+ Dispatch.request(env)
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+ 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
@@ -0,0 +1,5 @@
1
+ module Scales
2
+ module Server
3
+ VERSION = "0.0.1.beta.1"
4
+ end
5
+ 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: []