sinatra-health-check 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 334bafa6e4d41f6204c4b8dd3c85c9ae0bcd7197
4
+ data.tar.gz: 177f9eb36abcbc83d387f6cf2893d60853bc45e4
5
+ SHA512:
6
+ metadata.gz: 31e2492861672eb3e93bd0ebfce9ec1ae0c635d74dca19c9b10a85ccb8064cc14eef85aaf6ee57312e91912a5fc99120db96aa8c023f455f131e06b888ef5c93
7
+ data.tar.gz: 2cc30092da95700d7c10710b0594c97257c162518a0a9030ec364364b7c0466f842746870d3fd5119681615158d4006b051694e8f5423231b3065b36eadd5f4b
data/.cane ADDED
@@ -0,0 +1,3 @@
1
+ --style-measure 120
2
+ --color
3
+ --parallel
@@ -0,0 +1,7 @@
1
+ .bundle
2
+ .DS_Store
3
+ *.swp
4
+ *.gem
5
+ Gemfile.lock
6
+ vendor
7
+ coverage/
@@ -0,0 +1,5 @@
1
+ SimpleCov.start do
2
+ add_group 'Library', 'lib'
3
+ add_filter '/vendor'
4
+ add_filter '/spec'
5
+ end
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.5
6
+ - 2.2.0
7
+ env:
8
+ global:
9
+ - CODECLIMATE_REPO_TOKEN=8143d01ffb9603990dea3670c8286ab5b7fcad8131d1c3c9dfd714134664e7c6
10
+ script: bundle exec rake
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,41 @@
1
+ sinatra-health-check
2
+ ====================
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/sinatra-health-check.svg)](http://badge.fury.io/rb/sinatra-health-check) [![travis-ci](https://travis-ci.org/otto-de/sinatra-health-check.png?branch=master)](https://travis-ci.org/otto-de/sinatra-health-check) [![Code Climate](https://codeclimate.com/github/otto-de/sinatra-health-check/badges/gpa.svg)](https://codeclimate.com/github/otto-de/sinatra-health-check) [![Test Coverage](https://codeclimate.com/github/otto-de/sinatra-health-check/badges/coverage.svg)](https://codeclimate.com/github/otto-de/sinatra-health-check)
5
+
6
+ This tiny gem adds graceful stop to your sinatra application.
7
+
8
+ Stopping apps gracefully allows your running requests to finish before killing the app. It gives some time to configure load balancers before shutting things down.
9
+
10
+ Usage
11
+ -----
12
+
13
+ Initialize the health check:
14
+
15
+ ```ruby
16
+ require 'sinatra-health-check'
17
+ @checker = SinatraHealthCheck::Checker.new
18
+ ```
19
+
20
+ Then use it inside your health check route:
21
+
22
+ ```ruby
23
+ get "/ping" do
24
+ if @checker.healthy?
25
+ "pong"
26
+ else
27
+ status 503
28
+ "unhealthy"
29
+ end
30
+ end
31
+ ```
32
+
33
+ Contributing
34
+ ------------
35
+
36
+ It's fast and simple: fork + PR.
37
+
38
+ License
39
+ -------
40
+
41
+ This program is licensed under the MIT license. See LICENSE for details.
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
+
3
+ require 'rake'
4
+ require 'rspec/core/rake_task'
5
+ require 'cane/rake_task'
6
+
7
+ task :default => [:spec, :quality]
8
+
9
+ RSpec::Core::RakeTask.new do |t|
10
+ t.pattern = 'spec/**/*_spec.rb'
11
+ end
12
+
13
+ Cane::RakeTask.new(:quality) do |cane|
14
+ cane.canefile = '.cane'
15
+ end
@@ -0,0 +1,4 @@
1
+ module SinatraHealthCheck
2
+ require_relative 'sinatra-health-check/version'
3
+ require_relative 'sinatra-health-check/checker'
4
+ end
@@ -0,0 +1,73 @@
1
+ # The application health check.
2
+ # Create an instance and use .health to repond to your health check requests.
3
+ class SinatraHealthCheck::Checker
4
+
5
+ DEFAULT_OPTS = {
6
+ :exit => true,
7
+ :health => true,
8
+ :logger => nil,
9
+ :signals => %w[TERM INT],
10
+ :timeout => 10,
11
+ :wait => 0,
12
+ }
13
+
14
+ require 'thread'
15
+
16
+ attr_accessor :health
17
+ alias :healthy? :health
18
+
19
+ # Create a health checker.
20
+ # Params:
21
+ # ++exit++: call ++exit++ at the end of ++graceful_stop++
22
+ # ++health++: initial health state
23
+ # ++logger++: a logger
24
+ # ++signals++: array of signals to register a graceful stop handler
25
+ # ++timeout++: timeout for graceful stop in seconds
26
+ def initialize(opts = DEFAULT_OPTS)
27
+ @opts = DEFAULT_OPTS.merge(opts)
28
+ @health = @opts[:health]
29
+ trap(@opts[:signals])
30
+ end
31
+
32
+ # Set application to unhealthy state and stop it after wating for ++@timeout++.
33
+ def graceful_stop
34
+ # set to unhealthy state
35
+ unless @stopper
36
+ # spawn a thread to stop application after a given time
37
+ @stopper = Thread.new do
38
+ if @opts[:wait] > 0
39
+ logger.info "asked to stop application, waiting for #{@opts[:wait]}s before doing so" if logger
40
+ sleep @opts[:wait]
41
+ end
42
+ logger.info "stopping application, waiting for #{@opts[:timeout]}s" if logger
43
+ @health = false
44
+ sleep @opts[:timeout]
45
+ logger.info "exit application" if logger
46
+ exit if @opts[:exit]
47
+ end
48
+ end
49
+ end
50
+
51
+ # Waits for the stopping thread to finish
52
+ def join
53
+ @stopper.join if @stopper
54
+ end
55
+
56
+ private
57
+
58
+ def logger
59
+ @opts[:logger]
60
+ end
61
+
62
+ # Register signal handler to stop application gracefully.
63
+ # Params:
64
+ # ++signals++: array of signal names
65
+ def trap(signals)
66
+ if signals and signals.size > 0
67
+ logger.info "register graceful stop handler for signals: #{signals.join(', ')}" if logger
68
+ signals.each do |sig|
69
+ Signal.trap(sig) { graceful_stop }
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+ module SinatraHealthCheck
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/sinatra-health-check/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "sinatra-health-check"
6
+ gem.version = SinatraHealthCheck::VERSION
7
+ gem.authors = ["Felix Bechstein"]
8
+ gem.email = %w{felix.bechstein@otto.de}
9
+ gem.description = %q{A simple health check for sinatra applications}
10
+ gem.summary = %q{This health check adds graceful stop to your sinatra applications}
11
+ gem.homepage = 'https://github.com/otto-de/sinatra-health-check'
12
+ gem.license = 'MIT'
13
+
14
+ gem.files = `git ls-files`.split($\)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.require_paths = %w{lib}
18
+
19
+ gem.add_development_dependency 'rake'
20
+ gem.add_development_dependency 'rspec', '~> 3.0'
21
+ gem.add_development_dependency 'rspec-its'
22
+ gem.add_development_dependency 'pry'
23
+ gem.add_development_dependency 'cane'
24
+ gem.add_development_dependency 'simplecov'
25
+ gem.add_development_dependency 'codeclimate-test-reporter'
26
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe SinatraHealthCheck::Checker do
4
+
5
+ describe '#init, default values' do
6
+ its(:health) { should == true }
7
+ end
8
+
9
+ describe '#init, custom values' do
10
+ subject { described_class.new(:timeout => 10, :health => false)}
11
+ its(:health) { should == false }
12
+ end
13
+
14
+ context '#graceful_stop' do
15
+ subject { described_class.new(:timeout => 12)}
16
+
17
+ it 'gracefully stops the app' do
18
+ # it's healthy before stopping
19
+ expect(subject.health).to be_truthy
20
+
21
+ expect(subject).to receive(:sleep).ordered.with(12) {
22
+ if subject.healthy?
23
+ puts 'health state should be false here'
24
+ raise Error, 'health state should be false here'
25
+ end
26
+ }
27
+ expect(subject).to receive(:exit).ordered
28
+ subject.graceful_stop
29
+ subject.join
30
+
31
+ # it's unhealthy after stopping
32
+ expect(subject.health).to be_falsey
33
+ end
34
+ end
35
+
36
+ context '#graceful_stop, w/ :wait' do
37
+ subject { described_class.new(:wait => 5)}
38
+
39
+ it 'does not call exit' do
40
+ expect(subject).to receive(:sleep).ordered.with(5)
41
+ expect(subject).to receive(:sleep).ordered.with(10)
42
+ expect(subject).to receive(:exit).ordered
43
+ subject.graceful_stop
44
+ subject.join
45
+ end
46
+ end
47
+
48
+ context '#graceful_stop, w/o exit' do
49
+ subject { described_class.new(:exit => false)}
50
+
51
+ it 'does not call exit' do
52
+ expect(subject).to receive(:sleep).with(10)
53
+ expect(subject).not_to receive(:exit)
54
+ subject.graceful_stop
55
+ subject.join
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'rspec'
4
+ require 'rspec/its'
5
+ require 'simplecov'
6
+ require 'codeclimate-test-reporter'
7
+ require 'sinatra-health-check'
8
+
9
+ CodeClimate::TestReporter.start
10
+
11
+ RSpec.shared_context "local paths" do
12
+ def project_dir
13
+ File.expand_path(File.join(File.dirname(__FILE__), '..'))
14
+ end
15
+ end
16
+
17
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
18
+
19
+ RSpec.configure do |c|
20
+ c.mock_with :rspec
21
+ c.color = true
22
+ c.formatter = :documentation
23
+ c.tty = true
24
+ end
metadata ADDED
@@ -0,0 +1,157 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-health-check
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Felix Bechstein
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-its
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
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: cane
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: codeclimate-test-reporter
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: A simple health check for sinatra applications
112
+ email:
113
+ - felix.bechstein@otto.de
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".cane"
119
+ - ".gitignore"
120
+ - ".simplecov"
121
+ - ".travis.yml"
122
+ - Gemfile
123
+ - README.md
124
+ - Rakefile
125
+ - lib/sinatra-health-check.rb
126
+ - lib/sinatra-health-check/checker.rb
127
+ - lib/sinatra-health-check/version.rb
128
+ - sinatra-health-check.gemspec
129
+ - spec/sinatra-health-check/checker_spec.rb
130
+ - spec/spec_helper.rb
131
+ homepage: https://github.com/otto-de/sinatra-health-check
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.4.3
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: This health check adds graceful stop to your sinatra applications
155
+ test_files:
156
+ - spec/sinatra-health-check/checker_spec.rb
157
+ - spec/spec_helper.rb