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.
@@ -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