hirefireapp 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.
- data/.gitignore +2 -0
- data/README.md +5 -0
- data/bin/hirefireapp +39 -0
- data/hirefireapp.gemspec +20 -0
- data/lib/hirefireapp/middleware.rb +165 -0
- data/lib/hirefireapp/railtie.rb +9 -0
- data/lib/hirefireapp.rb +12 -0
- metadata +62 -0
data/.gitignore
ADDED
data/README.md
ADDED
data/bin/hirefireapp
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'open-uri'
|
4
|
+
|
5
|
+
def usage
|
6
|
+
puts
|
7
|
+
puts "Usage:"
|
8
|
+
puts
|
9
|
+
puts " hirefireapp http://mydomain.com/"
|
10
|
+
puts
|
11
|
+
puts "Or locally:"
|
12
|
+
puts
|
13
|
+
puts " gem install thin"
|
14
|
+
puts " thin start -p 3000"
|
15
|
+
puts " hirefireapp http://127.0.0.1:3000/"
|
16
|
+
puts
|
17
|
+
puts "SSL Enabled URLs:"
|
18
|
+
puts
|
19
|
+
puts " hirefireapp https://mydomain.com/"
|
20
|
+
end
|
21
|
+
|
22
|
+
if (url = ARGV[0]).nil?
|
23
|
+
usage
|
24
|
+
else
|
25
|
+
begin
|
26
|
+
response = open(File.join(url, 'hirefireapp', 'test')).read
|
27
|
+
rescue
|
28
|
+
puts
|
29
|
+
puts "Could not connect to: #{url}"
|
30
|
+
usage
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
if response =~ /\[HireFireApp\:\s/
|
35
|
+
puts response
|
36
|
+
else
|
37
|
+
puts "Could not find HireFireApp at #{url}."
|
38
|
+
end
|
39
|
+
end
|
data/hirefireapp.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
|
5
|
+
# General configuration / information
|
6
|
+
gem.name = 'hirefireapp'
|
7
|
+
gem.version = '0.0.1'
|
8
|
+
gem.platform = Gem::Platform::RUBY
|
9
|
+
gem.authors = 'Michael van Rooijen'
|
10
|
+
gem.email = 'meskyanichi@gmail.com'
|
11
|
+
gem.homepage = 'http://hirefireapp.com/'
|
12
|
+
gem.summary = %|HireFireApp.com - The Heroku Worker Monitor - Save money and scale at the same time!|
|
13
|
+
gem.description = %|HireFireApp.com - The Heroku Worker Monitor - Save money and scale at the same time! We monitor your applications by the minute!|
|
14
|
+
|
15
|
+
# Files and folder that need to be compiled in to the Ruby Gem
|
16
|
+
gem.files = %x[git ls-files].split("\n")
|
17
|
+
gem.executables = ['hirefireapp']
|
18
|
+
gem.require_path = 'lib'
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module HireFireApp
|
4
|
+
class Middleware
|
5
|
+
|
6
|
+
##
|
7
|
+
# Initialize the Rack Middleware by setting the app instance
|
8
|
+
# as well as allowing HireFire to request information via the token uri.
|
9
|
+
def initialize(app)
|
10
|
+
@app = app
|
11
|
+
@token = ENV['HIREFIREAPP_TOKEN']
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# If we are currently in the Heroku environment, and the path to the HireFire info uri
|
16
|
+
# has been requested (and the token belongs to the app) then we'll calculate the amount of
|
17
|
+
# jobs that are currently pending (either Delayed Job with Active Record / Mongoid or Resque with Redis).
|
18
|
+
#
|
19
|
+
# Once the job_count has been determined, we build a simple JSON string object and
|
20
|
+
# create a rack-based json response with 200 status. This will be returned to the HireFire service
|
21
|
+
# in order to determine what actions to take in terms of scaling up or down.
|
22
|
+
def call(env)
|
23
|
+
@env = env
|
24
|
+
|
25
|
+
if test?
|
26
|
+
[ 200, {'Content-Type' => 'text/html'}, self ]
|
27
|
+
elsif info?
|
28
|
+
[ 200, {'Content-Type' => 'application/json'}, self ]
|
29
|
+
else
|
30
|
+
@app.call(env)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Response body
|
36
|
+
def each(&block)
|
37
|
+
if test?
|
38
|
+
block.call "[HireFireApp: #{ok}] Worker: #{worker} - Mapper: #{mapper}"
|
39
|
+
elsif info?
|
40
|
+
block.call %|{"job_count":#{job_count || 'null'}}|
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
##
|
47
|
+
# Counts the amount of jobs that are currently queued
|
48
|
+
# and show be processed as soon as possible (aka the ones that are pending)
|
49
|
+
#
|
50
|
+
# @returns [Fixnum, nil] job_count returns nil if something went wrong
|
51
|
+
def job_count
|
52
|
+
begin
|
53
|
+
if defined?(Delayed::Worker)
|
54
|
+
count_delayed_job
|
55
|
+
elsif defined?(Resque)
|
56
|
+
count_resque
|
57
|
+
end
|
58
|
+
rescue => error
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Makes Delayed::Job count the amount of currently pending jobs.
|
65
|
+
# It'll use the ActiveRecord ORM, or the Mongoid ODM depending on
|
66
|
+
# which of them is defined.
|
67
|
+
#
|
68
|
+
# If ActiveRecord 2 (or earlier) is being used, ActiveRecord::Relation doesn't
|
69
|
+
# exist, and we'll have to use the old :conditions hash notation.
|
70
|
+
#
|
71
|
+
# @returns [Fixnum] delayed_job_count the amount of jobs currently pending
|
72
|
+
def count_delayed_job
|
73
|
+
if defined?(ActiveRecord) and Delayed::Worker.backend.to_s =~ /ActiveRecord/
|
74
|
+
if defined?(ActiveRecord::Relation)
|
75
|
+
Delayed::Job.
|
76
|
+
where(:failed_at => nil).
|
77
|
+
where('run_at <= ?', Time.now).count
|
78
|
+
else
|
79
|
+
Delayed::Job.all(
|
80
|
+
:conditions => [
|
81
|
+
'failed_at IS NULL and run_at <= ?', Time.now.utc
|
82
|
+
]
|
83
|
+
).count
|
84
|
+
end
|
85
|
+
elsif defined?(Mongoid) and Delayed::Worker.backend.to_s =~ /Mongoid/
|
86
|
+
Delayed::Job.where(
|
87
|
+
:failed_at => nil,
|
88
|
+
:run_at.lte => Time.now
|
89
|
+
).count
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Makes Resque count the amount of currently pending jobs.
|
95
|
+
#
|
96
|
+
# @returns [Fixnum] resque_job_count
|
97
|
+
# the number of jobs pending + the amount of workers currently working
|
98
|
+
def count_resque
|
99
|
+
Resque.info[:pending].to_i + Resque.info[:working].to_i
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# Returns the name of the mapper, or "Not Found" if not found
|
104
|
+
#
|
105
|
+
# @returns [String]
|
106
|
+
def mapper
|
107
|
+
if defined?(Redis) and defined?(Resque)
|
108
|
+
"Redis"
|
109
|
+
elsif defined?(Delayed::Worker)
|
110
|
+
if defined?(ActiveRecord) and Delayed::Worker.backend.to_s =~ /ActiveRecord/
|
111
|
+
"Active Record"
|
112
|
+
elsif defined?(Mongoid) and Delayed::Worker.backend.to_s =~ /Mongoid/
|
113
|
+
"Mongoid"
|
114
|
+
else
|
115
|
+
"Not Found"
|
116
|
+
end
|
117
|
+
else
|
118
|
+
"Not Found"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Returns the name of the worker type, or "Not Found" if not found
|
124
|
+
#
|
125
|
+
# @returns [String]
|
126
|
+
def worker
|
127
|
+
if defined?(Delayed::Job)
|
128
|
+
"Delayed Job"
|
129
|
+
elsif defined?(Resque)
|
130
|
+
"Resque"
|
131
|
+
else
|
132
|
+
"Not Found"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Returns "OK" if both the mapper and worker were found
|
138
|
+
#
|
139
|
+
# @returns [String]
|
140
|
+
def ok
|
141
|
+
if mapper =~ /Not Found/ or worker =~ /Not Found/
|
142
|
+
"Incomplete"
|
143
|
+
else
|
144
|
+
"OK"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
##
|
149
|
+
# Returns true if the REQUEST_PATH matches the test url
|
150
|
+
#
|
151
|
+
# @returns [String]
|
152
|
+
def test?
|
153
|
+
@env['REQUEST_PATH'] == "/hirefireapp/test"
|
154
|
+
end
|
155
|
+
|
156
|
+
##
|
157
|
+
# Returns true if the REQUEST_PATH matches the info url
|
158
|
+
#
|
159
|
+
# @returns [String]
|
160
|
+
def info?
|
161
|
+
@env['REQUEST_PATH'] == "/hirefireapp/#{@token}/info"
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
data/lib/hirefireapp.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
HIREFIRE_APP_PATH = File.expand_path('../hirefireapp', __FILE__)
|
4
|
+
|
5
|
+
# Load the HireFireApp middleware
|
6
|
+
require File.join(HIREFIRE_APP_PATH, 'middleware')
|
7
|
+
|
8
|
+
# If Rails::Railtie exists, then hook up HireFireApp automatically
|
9
|
+
if defined?(Rails::Railtie)
|
10
|
+
require File.join(HIREFIRE_APP_PATH, 'railtie')
|
11
|
+
end
|
12
|
+
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hirefireapp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Michael van Rooijen
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-05-23 00:00:00 +02:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: HireFireApp.com - The Heroku Worker Monitor - Save money and scale at the same time! We monitor your applications by the minute!
|
18
|
+
email: meskyanichi@gmail.com
|
19
|
+
executables:
|
20
|
+
- hirefireapp
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files: []
|
24
|
+
|
25
|
+
files:
|
26
|
+
- .gitignore
|
27
|
+
- README.md
|
28
|
+
- bin/hirefireapp
|
29
|
+
- hirefireapp.gemspec
|
30
|
+
- lib/hirefireapp.rb
|
31
|
+
- lib/hirefireapp/middleware.rb
|
32
|
+
- lib/hirefireapp/railtie.rb
|
33
|
+
has_rdoc: true
|
34
|
+
homepage: http://hirefireapp.com/
|
35
|
+
licenses: []
|
36
|
+
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: "0"
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
requirements: []
|
55
|
+
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 1.6.2
|
58
|
+
signing_key:
|
59
|
+
specification_version: 3
|
60
|
+
summary: HireFireApp.com - The Heroku Worker Monitor - Save money and scale at the same time!
|
61
|
+
test_files: []
|
62
|
+
|