sinatra-health-check 0.1.0

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,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