rails_runner 0.0.1
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +21 -0
- data/lib/rails_runner/config.rb +54 -0
- data/lib/rails_runner/instrumenter.rb +47 -0
- data/lib/rails_runner/messages/action.rb +25 -0
- data/lib/rails_runner/messages/batch.rb +38 -0
- data/lib/rails_runner/messages/endpoint.rb +31 -0
- data/lib/rails_runner/messages/minute.rb +80 -0
- data/lib/rails_runner/messages/request.rb +48 -0
- data/lib/rails_runner/middleware.rb +25 -0
- data/lib/rails_runner/notifications/default.rb +42 -0
- data/lib/rails_runner/notifications/process_action.rb +12 -0
- data/lib/rails_runner/notifications/render_partial.rb +11 -0
- data/lib/rails_runner/notifications/render_template.rb +11 -0
- data/lib/rails_runner/notifications/sql.rb +14 -0
- data/lib/rails_runner/notifications.rb +17 -0
- data/lib/rails_runner/railtie.rb +11 -0
- data/lib/rails_runner/subscriber.rb +34 -0
- data/lib/rails_runner/util.rb +31 -0
- data/lib/rails_runner/version.rb +3 -0
- data/lib/rails_runner/worker.rb +59 -0
- data/lib/rails_runner.rb +34 -0
- data/lib/tasks/rails_runner_tasks.rake +4 -0
- metadata +109 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 140270f54be56b6eb841de14c8d0b6489c3ad786
|
4
|
+
data.tar.gz: e93221ca8696a833cad6421d2a30d6ccca1f805f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 336638f0a7e7bdde650884ef05d823ea2633a09ba7c2735ec03e8fe2a2f875f95559895130ad6a5d3932f86e78cae38bd10b715ff6527fa1e100b3c669f5ef31
|
7
|
+
data.tar.gz: 96e042ca7425e45c388de5ffa75f94ae081e7a78c7efbc58495cbc7a8f3945cf16ca3419f8cf5aa978b66a61c914b6fba49c0f6186ec67f30120c6fc57bb545b
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'RailsRunner'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
Bundler::GemHelper.install_tasks
|
21
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module RailsRunner
|
4
|
+
class Config
|
5
|
+
class ConfigurationMissing < StandardError
|
6
|
+
def initialize(filename)
|
7
|
+
@filename = filename
|
8
|
+
end
|
9
|
+
|
10
|
+
def message(*args)
|
11
|
+
"Please make sure the configuration file exists: #{@filename}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(config_file)
|
16
|
+
@config_file = config_file
|
17
|
+
load_config
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_config
|
21
|
+
raise ConfigurationMissing.new(@config_file) unless File.exist?(@config_file)
|
22
|
+
file = YAML.load(File.read(@config_file))
|
23
|
+
if file && file[env]
|
24
|
+
@configuration = file[env].with_indifferent_access
|
25
|
+
else
|
26
|
+
@configuration = {}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def collector_url
|
31
|
+
@configuration[:collector_url] ||= 'http://www.railsrunner.com'
|
32
|
+
end
|
33
|
+
|
34
|
+
def client_id
|
35
|
+
@configuration[:client_id]
|
36
|
+
end
|
37
|
+
|
38
|
+
def app_name
|
39
|
+
@configuration[:app_name] ||= Rails.application.class.parent_name
|
40
|
+
end
|
41
|
+
|
42
|
+
def active?
|
43
|
+
@configuration[:active] ||= !%w(test development).include?(env)
|
44
|
+
end
|
45
|
+
|
46
|
+
def hostname
|
47
|
+
@hostname ||= Socket.gethostname
|
48
|
+
end
|
49
|
+
|
50
|
+
def env
|
51
|
+
ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Instrumenter
|
3
|
+
MUTEX = Mutex.new
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def current_request
|
7
|
+
Thread.current[:rails_runner_current_request]
|
8
|
+
end
|
9
|
+
|
10
|
+
def current_request=(request)
|
11
|
+
Thread.current[:rails_runner_current_request] = request
|
12
|
+
end
|
13
|
+
|
14
|
+
def start!
|
15
|
+
return @instance if @instance
|
16
|
+
|
17
|
+
MUTEX.synchronize do
|
18
|
+
return @instance if @instance
|
19
|
+
@instance = new.start
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def instance
|
24
|
+
@instance
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def start
|
29
|
+
@worker = Worker.start!
|
30
|
+
@subscriber = Subscriber.new.register
|
31
|
+
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def record(*args)
|
36
|
+
self.class.current_request = Request.new
|
37
|
+
end
|
38
|
+
|
39
|
+
def reset
|
40
|
+
self.class.current_request = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def publish(request)
|
44
|
+
@worker.push(request)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Action
|
3
|
+
include Beefcake::Message
|
4
|
+
|
5
|
+
required :category, :string, 1
|
6
|
+
required :object, :string, 2
|
7
|
+
required :start, :int64, 3
|
8
|
+
required :end, :int64, 4
|
9
|
+
required :duration, :int64, 5
|
10
|
+
required :explain, :string, 6
|
11
|
+
required :level, :int32, 7
|
12
|
+
|
13
|
+
def initialize(category, object, explain = '')
|
14
|
+
@category = category
|
15
|
+
@object = object
|
16
|
+
@explain = explain.to_s
|
17
|
+
@start = Util.time_in_usec
|
18
|
+
end
|
19
|
+
|
20
|
+
def finish
|
21
|
+
@end = Util.time_in_usec
|
22
|
+
@duration = @end - @start
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Batch
|
3
|
+
include Beefcake::Message
|
4
|
+
|
5
|
+
required :client_id, :string, 1
|
6
|
+
required :app_name, :string, 2
|
7
|
+
required :hostname, :string, 3
|
8
|
+
|
9
|
+
repeated :minutes, Minute, 5
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@client_id = RailsRunner.config.client_id
|
13
|
+
@app_name = RailsRunner.config.app_name
|
14
|
+
@hostname = RailsRunner.config.hostname
|
15
|
+
|
16
|
+
@_minutes = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def current_minute
|
20
|
+
@_minutes[minute] ||= RailsRunner::Minute.new(minute)
|
21
|
+
end
|
22
|
+
|
23
|
+
def encode(*)
|
24
|
+
@minutes = @_minutes.values
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def minutes
|
29
|
+
@minutes ||= @_minutes.values
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def minute
|
35
|
+
Time.now.to_i / 60
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Endpoint
|
3
|
+
include Beefcake::Message
|
4
|
+
required :name, :string, 1
|
5
|
+
required :errors, :int64, 2
|
6
|
+
repeated :times, :int64, 3, packed: true
|
7
|
+
repeated :counts, :int64, 4, packed: true
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
super
|
11
|
+
@errors = 0
|
12
|
+
@times = Hash.new { |h, k| h[k] = 0 }
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_time(time)
|
16
|
+
@times[time.to_i] += 1
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_error
|
20
|
+
@errors += 1
|
21
|
+
end
|
22
|
+
|
23
|
+
def times
|
24
|
+
@times.keys
|
25
|
+
end
|
26
|
+
|
27
|
+
def counts
|
28
|
+
@times.values
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Minute
|
3
|
+
include Beefcake::Message
|
4
|
+
|
5
|
+
required :minute, :int64, 1
|
6
|
+
repeated :endpoints, Endpoint, 2, packed: true
|
7
|
+
repeated :traces, Request, 3, packed: true
|
8
|
+
|
9
|
+
def initialize(minute = Time.now.to_i)
|
10
|
+
@minute = minute
|
11
|
+
@errors = 0
|
12
|
+
@endpoints = {}
|
13
|
+
@trace_endpoints = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_request(request)
|
17
|
+
add_error(request)
|
18
|
+
|
19
|
+
add_time(request)
|
20
|
+
|
21
|
+
add_trace(request)
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_trace(request)
|
25
|
+
return if request.traceable?
|
26
|
+
return if slower_request_registered?(request)
|
27
|
+
@trace_endpoints[request.name] = request
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_time(request)
|
31
|
+
time = rounded(request.duration)
|
32
|
+
endpoint(request.name).add_time(time) if request.name.present?
|
33
|
+
endpoint('total').add_time(time)
|
34
|
+
end
|
35
|
+
|
36
|
+
def traces
|
37
|
+
@trace_endpoints.values
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_error(request)
|
41
|
+
return unless request.error?
|
42
|
+
endpoint(request.name || 'total').add_error
|
43
|
+
end
|
44
|
+
|
45
|
+
def endpoints
|
46
|
+
@endpoints.values
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def endpoint(name)
|
52
|
+
@endpoints[name] ||= Endpoint.new(name: name)
|
53
|
+
end
|
54
|
+
|
55
|
+
def rounded(duration)
|
56
|
+
if duration < 500_000
|
57
|
+
mod = 10_000
|
58
|
+
elsif duration < 1000_000
|
59
|
+
mod = 50_000
|
60
|
+
elsif duration < 1500_000
|
61
|
+
mod = 100_000
|
62
|
+
elsif duration < 2250_000
|
63
|
+
mod = 150_000
|
64
|
+
elsif duration < 3000_000
|
65
|
+
mod = 200_000
|
66
|
+
else
|
67
|
+
return 3000_000
|
68
|
+
end
|
69
|
+
duration - (duration % mod)
|
70
|
+
end
|
71
|
+
|
72
|
+
def slower_request_registered?(request)
|
73
|
+
if @trace_endpoints[request.name]
|
74
|
+
@trace_endpoints[request.name].duration > request.duration
|
75
|
+
else
|
76
|
+
false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Request
|
3
|
+
include Beefcake::Message
|
4
|
+
|
5
|
+
optional :name, :string, 1
|
6
|
+
required :start, :int64, 2
|
7
|
+
required :end, :int64, 3
|
8
|
+
required :duration, :int64, 4
|
9
|
+
required :error, :bool, 5
|
10
|
+
repeated :actions, Action, 6, packed: true
|
11
|
+
|
12
|
+
attr_accessor :notifications
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@start = Util.time_in_usec
|
16
|
+
@current_level = 0
|
17
|
+
@actions = []
|
18
|
+
@notifications = []
|
19
|
+
end
|
20
|
+
|
21
|
+
def finish(error = false)
|
22
|
+
@end = Util.time_in_usec
|
23
|
+
@duration = @end - @start
|
24
|
+
@error = error
|
25
|
+
Instrumenter.instance.publish(self)
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_action(action)
|
29
|
+
action.level = @current_level
|
30
|
+
@current_level += 1
|
31
|
+
@actions << action
|
32
|
+
end
|
33
|
+
|
34
|
+
def finish_action(action)
|
35
|
+
return unless action
|
36
|
+
action.finish
|
37
|
+
@current_level -= 1
|
38
|
+
end
|
39
|
+
|
40
|
+
def traceable?
|
41
|
+
name.blank? || error?
|
42
|
+
end
|
43
|
+
|
44
|
+
def error?
|
45
|
+
@error
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Middleware
|
3
|
+
def initialize(app)
|
4
|
+
@app = app
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
begin
|
9
|
+
request = instrumenter.record 'Rack', 'rack.request'
|
10
|
+
resp = @app.call(env)
|
11
|
+
request.finish if request
|
12
|
+
resp
|
13
|
+
rescue Exception
|
14
|
+
request.finish(true) if request
|
15
|
+
raise
|
16
|
+
ensure
|
17
|
+
instrumenter.reset
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def instrumenter
|
22
|
+
RailsRunner::Instrumenter.instance
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Notifications
|
3
|
+
class Default
|
4
|
+
class << self
|
5
|
+
def notification(name)
|
6
|
+
RailsRunner::Notifications.add_notification(name, self)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_action(request, payload)
|
11
|
+
nil #
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class RenderDefault < Default
|
16
|
+
class << self
|
17
|
+
def mapped_paths
|
18
|
+
return @mapped_paths if @mapped_paths
|
19
|
+
@mapped_paths = {
|
20
|
+
Rails.root.to_s => ''
|
21
|
+
}
|
22
|
+
Gem.path.each do |path|
|
23
|
+
@mapped_paths[File.join(path, 'gems')] = 'gem'
|
24
|
+
end if defined?(Gem)
|
25
|
+
|
26
|
+
@mapped_paths
|
27
|
+
end
|
28
|
+
|
29
|
+
def prune_path(raw_path)
|
30
|
+
mapped_paths.each do |path, replacement|
|
31
|
+
raw_path = raw_path.gsub(path, replacement)
|
32
|
+
end
|
33
|
+
raw_path
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def prune_path(path)
|
38
|
+
self.class.prune_path(path)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Notifications
|
3
|
+
class ProcessAction < Default
|
4
|
+
notification 'process_action.action_controller'
|
5
|
+
|
6
|
+
def to_action(request, payload)
|
7
|
+
request.name = "#{payload[:controller]}##{payload[:action]}"
|
8
|
+
Action.new('Controller', request.name)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Notifications
|
3
|
+
class Sql < Default
|
4
|
+
IGNORED_NAMES = %w(SCHEMA EXPLAIN CACHE) << nil
|
5
|
+
|
6
|
+
notification 'sql.active_record'
|
7
|
+
|
8
|
+
def to_action(request, payload)
|
9
|
+
return if IGNORED_NAMES.include? payload[:name]
|
10
|
+
Action.new('Database', payload[:name], payload[:sql])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Notifications
|
3
|
+
class << self
|
4
|
+
DEFAULT_NOTIFICATION = Default.new
|
5
|
+
|
6
|
+
def add_notification(name, notification)
|
7
|
+
@notifications ||= {}
|
8
|
+
@notifications[name] = notification.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_action(request, name, payload)
|
12
|
+
notification = @notifications[name] || DEFAULT_NOTIFICATION
|
13
|
+
notification.to_action(request, payload)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
initializer 'rails_runner.configure' do |app|
|
4
|
+
Instrumenter.start!
|
5
|
+
app.middleware.insert 0, Middleware
|
6
|
+
RailsRunner.config = RailsRunner::Config.new(app.root.join('config/railsrunner.yml'))
|
7
|
+
|
8
|
+
puts "[RAILSRUNNER] started"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Subscriber
|
3
|
+
Notification = Struct.new(:name, :action)
|
4
|
+
|
5
|
+
def register
|
6
|
+
unregister if @subscriber
|
7
|
+
@subscriber = ActiveSupport::Notifications.subscribe nil, self
|
8
|
+
end
|
9
|
+
|
10
|
+
def start(name, id, payload)
|
11
|
+
request = Instrumenter.current_request
|
12
|
+
return unless request
|
13
|
+
|
14
|
+
if (action = Notifications.to_action(request, name, payload))
|
15
|
+
request.add_action(action)
|
16
|
+
end
|
17
|
+
|
18
|
+
request.notifications << Notification.new(name, action)
|
19
|
+
end
|
20
|
+
|
21
|
+
def finish(name, id, payload)
|
22
|
+
request = Instrumenter.current_request
|
23
|
+
return unless request
|
24
|
+
|
25
|
+
while (notification = request.notifications.pop)
|
26
|
+
if notification.name == name
|
27
|
+
request.finish_action(notification.action)
|
28
|
+
return
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module RailsRunner
|
5
|
+
class Util
|
6
|
+
class << self
|
7
|
+
def time_in_usec(time = Time.now)
|
8
|
+
time.to_i * 1_000_000 + time.usec
|
9
|
+
end
|
10
|
+
|
11
|
+
def post(body)
|
12
|
+
uri = URI.parse(URI.join("#{RailsRunner.config.collector_url}").to_s)
|
13
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
14
|
+
gzipped = Base64.encode64(gzip(body))
|
15
|
+
|
16
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
17
|
+
request.body = gzipped
|
18
|
+
request['Authorization'] = "#{RailsRunner.config.client_id}"
|
19
|
+
|
20
|
+
http.request(request)
|
21
|
+
end
|
22
|
+
|
23
|
+
def gzip(bytes)
|
24
|
+
gz = Zlib::GzipWriter.new(buffer = StringIO.new)
|
25
|
+
gz.write(bytes)
|
26
|
+
gz.close
|
27
|
+
buffer.string
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module RailsRunner
|
2
|
+
class Worker
|
3
|
+
MUTEX = Mutex.new
|
4
|
+
|
5
|
+
attr_accessor :requests, :batch
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def start!
|
9
|
+
return if @instance
|
10
|
+
MUTEX.synchronize do
|
11
|
+
return @instance if @instance
|
12
|
+
@instance = new.start
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def instance
|
17
|
+
@instance
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@queue = Queue.new
|
23
|
+
@requests = 0
|
24
|
+
@batch = Batch.new
|
25
|
+
end
|
26
|
+
|
27
|
+
def start
|
28
|
+
Thread.new do
|
29
|
+
while (request = @queue.pop)
|
30
|
+
begin
|
31
|
+
case request
|
32
|
+
when Request
|
33
|
+
batch.current_minute.add_request(request)
|
34
|
+
@requests += 1
|
35
|
+
when :flush
|
36
|
+
send_to_collector
|
37
|
+
end
|
38
|
+
rescue Exception => e
|
39
|
+
puts e.message
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def push(request)
|
47
|
+
@queue << request
|
48
|
+
end
|
49
|
+
|
50
|
+
def send_to_collector
|
51
|
+
@batch.encode(buffer = '')
|
52
|
+
|
53
|
+
Util.post(buffer)
|
54
|
+
|
55
|
+
@requests = 0
|
56
|
+
@batch = Batch.new
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/rails_runner.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'beefcake'
|
2
|
+
|
3
|
+
module RailsRunner
|
4
|
+
require 'rails_runner/util'
|
5
|
+
require 'rails_runner/messages/action'
|
6
|
+
require 'rails_runner/messages/endpoint'
|
7
|
+
require 'rails_runner/messages/request'
|
8
|
+
require 'rails_runner/messages/minute'
|
9
|
+
require 'rails_runner/messages/batch'
|
10
|
+
|
11
|
+
require 'rails_runner/notifications/default'
|
12
|
+
require 'rails_runner/notifications'
|
13
|
+
require 'rails_runner/notifications/process_action'
|
14
|
+
require 'rails_runner/notifications/render_partial'
|
15
|
+
require 'rails_runner/notifications/render_template'
|
16
|
+
require 'rails_runner/notifications/sql'
|
17
|
+
|
18
|
+
require 'rails_runner/instrumenter'
|
19
|
+
require 'rails_runner/middleware'
|
20
|
+
require 'rails_runner/railtie'
|
21
|
+
require 'rails_runner/subscriber'
|
22
|
+
require 'rails_runner/worker'
|
23
|
+
require 'rails_runner/config'
|
24
|
+
|
25
|
+
def config=(config)
|
26
|
+
@config = config
|
27
|
+
end
|
28
|
+
module_function :config=
|
29
|
+
|
30
|
+
def config
|
31
|
+
@config || RailsRunner::Config.new(Rails.root.join('config/railsrunner.yml'))
|
32
|
+
end
|
33
|
+
module_function :config
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails_runner
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Benoist Claassen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: beefcake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Running rails
|
56
|
+
email:
|
57
|
+
- benoist.claassen@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- lib/rails_runner/config.rb
|
63
|
+
- lib/rails_runner/instrumenter.rb
|
64
|
+
- lib/rails_runner/messages/action.rb
|
65
|
+
- lib/rails_runner/messages/batch.rb
|
66
|
+
- lib/rails_runner/messages/endpoint.rb
|
67
|
+
- lib/rails_runner/messages/minute.rb
|
68
|
+
- lib/rails_runner/messages/request.rb
|
69
|
+
- lib/rails_runner/middleware.rb
|
70
|
+
- lib/rails_runner/notifications/default.rb
|
71
|
+
- lib/rails_runner/notifications/process_action.rb
|
72
|
+
- lib/rails_runner/notifications/render_partial.rb
|
73
|
+
- lib/rails_runner/notifications/render_template.rb
|
74
|
+
- lib/rails_runner/notifications/sql.rb
|
75
|
+
- lib/rails_runner/notifications.rb
|
76
|
+
- lib/rails_runner/railtie.rb
|
77
|
+
- lib/rails_runner/subscriber.rb
|
78
|
+
- lib/rails_runner/util.rb
|
79
|
+
- lib/rails_runner/version.rb
|
80
|
+
- lib/rails_runner/worker.rb
|
81
|
+
- lib/rails_runner.rb
|
82
|
+
- lib/tasks/rails_runner_tasks.rake
|
83
|
+
- MIT-LICENSE
|
84
|
+
- Rakefile
|
85
|
+
- README.rdoc
|
86
|
+
homepage: http://railsrunner.com
|
87
|
+
licenses: []
|
88
|
+
metadata: {}
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
requirements: []
|
104
|
+
rubyforge_project:
|
105
|
+
rubygems_version: 2.0.3
|
106
|
+
signing_key:
|
107
|
+
specification_version: 4
|
108
|
+
summary: Running rails
|
109
|
+
test_files: []
|