epi 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ff6e7a2df3b27a605072bbedff81ea4ebb5b7c1b
4
- data.tar.gz: 4609bab09c0142f2206cb733d28fb22387806fa0
3
+ metadata.gz: 4f4c9fe139dc5bf2d4588ee4ee5e2348a634af58
4
+ data.tar.gz: 6209ed9c345315d1a980d697db4b38dc4595bc98
5
5
  SHA512:
6
- metadata.gz: bb50900af4312e6959956ec5a61af06f7dee51d8f509577e56eb55027c23a7a7c43e6dd2ea4ec03425e1bc0f880d9926e094667f55b0a7eb2d7b2c3ace8427bb
7
- data.tar.gz: 491f3d33d0b2be9d558f159c0ac8f502a037cbea1536444c4a53ea9c77739f208ebe05507c0c895fc47e2e4b3be29401618abba1ff3ea17448b283e23c5e3608
6
+ metadata.gz: a988b557f92226f25c0b22d0c212e1d1a3bfa14d4872e367a52a94a480f2bcc420ea70fe170a8d7ab78de9dde7644954b25556b3cb122dc517c22f8420f55ad6
7
+ data.tar.gz: 2c122327a30c948c96cab15e4b00631d7eb78d66d7cb1e7003665217cf00e1b947d508e61696fff04ee5d696fb9bae57e27abeb151ab0c681c1374d6c3fcfb55
@@ -0,0 +1 @@
1
+ -m markdown --exclude core_ext
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2014 Neil E. Pearson
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,118 @@
1
+ # Epinephrine
2
+
3
+ Keeps your workers alive.
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ $ gem install epi
9
+ ```
10
+
11
+ ## Job Configuration
12
+
13
+ Example `config.epi`:
14
+
15
+ ```ruby
16
+ job resque: 'Resque Workers' do |j|
17
+ j.user = 'webapp'
18
+ j.directory = File.expand_path('..', __FILE__)
19
+ j.environment = {
20
+ QUEUE: '*',
21
+ TERM_CHILD: 1,
22
+ PIDFILE: -> p { p.pidfile }
23
+ }
24
+ j.command = 'bundle exec rake resque:work'
25
+ j.initial_processes = 2
26
+ j.allowed_processes = 1..5
27
+ j.stdout = nil
28
+ j.stderr = '/var/log/worker_errors.log'
29
+ j.kill_timeout = 3.seconds
30
+
31
+ j.on(:touch, __FILE__) { |job| job.restart! }
32
+ j.on(:memory, :gt, 350.megabytes) { |process| process.restart! }
33
+ j.on(:uptime, :gt, 1.day) { |process| process.restart! }
34
+ end
35
+ ```
36
+
37
+ Tell Epi to watch this config file:
38
+
39
+ ```
40
+ $ epi config add config.epi
41
+ Added configuration file: /home/my_app/config.epi
42
+ ```
43
+
44
+ ## Behaviour
45
+
46
+ See what Epi is up to:
47
+
48
+ ```
49
+ $ epi status
50
+ ---
51
+ Running as: root
52
+ Since: Mon 20 Oct 2014 15:27:04
53
+ Jobs:
54
+ Resque Workers [resque]:
55
+ PID 40210:
56
+ Since: Mon 20 Oct 2014 15:31:20
57
+ CPU: 0.0%
58
+ Memory: 0.3%
59
+ PID 40213 [dying]:
60
+ Since: Mon 20 Oct 2014 15:31:21
61
+ CPU: 0.0%
62
+ Memory: 0.2%
63
+ ```
64
+
65
+ Start/stop workers:
66
+
67
+ ```
68
+ $ epi job resque more
69
+ Increasing 'Resque Workers' processes by 1 (from 2 to 3)
70
+ $ epi job resque 2 less
71
+ Decreasing 'Resque Workers' processes by 2 (from 3 to 1)
72
+ $ epi job resque 4
73
+ Increasing 'Resque Workers' processes by 3 (from 1 to 4)
74
+ $ epi job resque pause
75
+ Decreasing 'Resque Workers' processes by 4 (from 4 to 0)
76
+ $ epi job resque resume
77
+ Increasing 'Resque Workers' processes by 4 (from 0 to 4)
78
+ $ epi job resque max
79
+ Increasing 'Resque Workers' processes by 1 (from 4 to 5)
80
+ $ epi job resque restart
81
+ Replacing 5 'Resque Workers' processes
82
+ ```
83
+
84
+ Control the Epi daemon, and all its managed processes:
85
+
86
+ ```
87
+ $ epi stop
88
+ Stopping 5 processes ...
89
+ Shutting down ...
90
+ $ epi start
91
+ Starting 5 processes ...
92
+ $ epi restart
93
+ Stopping 5 processes ...
94
+ Shutting down ...
95
+ Starting 5 processes ...
96
+ ```
97
+
98
+ Config files will be reloaded whenever they change.
99
+
100
+ ## Polling
101
+
102
+ Epi checks the state of running processes every 5 seconds by running the `ps` command.
103
+
104
+ Change the number of seconds between polls by setting the `EPI_INTERVAL` environment variable.
105
+
106
+ ## Logging
107
+
108
+ Logs are written to `~/.epi/epi.log`, or `/var/log/epi.log` if run as root.
109
+
110
+ Set the `EPI_LOG` environment variable to tell Epi to write logs elsewhere. Set `EPI_LOG_LEVEL` to limit logging to *debug*, *info*, *error*, *warn*, *fatal*, or *unknown*.
111
+
112
+ ## Running as other users
113
+
114
+ You can only configure jobs to run as other users if the Epi daemon runs as root.
115
+
116
+ The daemon is started the first time you run the `epi` command, as whatever user ran it. If `epi` is ever run by `root`, the original user's daemon will be replaced by a daemon owned by `root`. Once that's happened, Epi will complain if you try to start or stop the daemon as any other user.
117
+
118
+ Epi recognises the history of its daemon running as root by the presence of data in `/etc/epi`. You can force it to use a particular user's data instead by setting the `EPI_HOME` environment variable to, for example, `~/.epi`.
@@ -6,9 +6,9 @@ module Epi
6
6
  class << self
7
7
 
8
8
  def run(args)
9
- command = args.shift || 'status' # The default command
9
+ command = args.shift || 'help' # The default command
10
10
  begin
11
- Command.run command, args
11
+ Command.run command.delete('-'), args
12
12
  rescue Exceptions::Fatal => error
13
13
  STDERR << error.message
14
14
  STDERR << "\n"
@@ -0,0 +1,67 @@
1
+ module Epi
2
+ module Cli
3
+ module Commands
4
+ # noinspection RubyStringKeysInHashInspection
5
+ class Help < Command
6
+
7
+ def run
8
+ puts doc
9
+ EM.stop
10
+ end
11
+
12
+ private
13
+
14
+ def doc
15
+ <<-EOF
16
+ Epinephrine v#{Epi::VERSION} (c) 2014 Neil E. Pearson
17
+ Licensed under the Apache License, Version 2.0
18
+ http://www.apache.org/licenses/LICENSE-2.0
19
+ See https://github.com/hx/epi for complete documentation
20
+
21
+ Usage:
22
+ #{$0} command [etc...]
23
+
24
+ Commands:
25
+ #{commands}
26
+ Env vars:
27
+ EPI_LOG Path to which logs should be written
28
+ EPI_LOG_LEVEL Logging severity (debug, info, warn, error, fatal)
29
+ EPI_INTERVAL Delay in seconds between process status checks
30
+ EPI_HOME Directory in which Epi should store state data
31
+ EOF
32
+ end
33
+
34
+ def commands
35
+ all =
36
+ {
37
+ 'help' => 'Show this screen',
38
+
39
+ 'config add PATH' => 'Start watching the config file at PATH',
40
+ 'config remove PATH' => 'Stop watching the config file at PATH',
41
+
42
+ 'job ID NUM' => 'Run NUM instances of ID job',
43
+ 'job ID [more|less]' => 'Run one more/less instances of ID job',
44
+ 'job ID NUM [more|less]' => 'Run NUM more/less instances of ID job',
45
+ 'job ID pause' => 'Stop all instances of ID job',
46
+ 'job ID reset' => 'Run the initial number of ID job instances',
47
+ 'job ID max' => 'Run the maximum allowed number of ID job instances',
48
+ 'job ID min' => 'Run the minimum allowed number of ID job instances',
49
+ 'job ID restart' => 'Replace all instances of ID job with new ones',
50
+
51
+ 'status' => 'Show details of running/dying instances',
52
+
53
+ 'start' => 'Start the Epi daemon, and all expected jobs',
54
+ 'stop' => 'Stop the Epi daemon, and all running jobs',
55
+ 'restart' => 'Restart the Epi daemon, and all running jobs'
56
+
57
+ }
58
+ max_key_width = all.keys.map(&:length).max
59
+ all.map do |cmd, desc|
60
+ " #{cmd} %s #{desc}\n" % (' ' * (max_key_width - cmd.length))
61
+ end.join ''
62
+ end
63
+
64
+ end
65
+ end
66
+ end
67
+ end
@@ -18,6 +18,14 @@ module Epi
18
18
  @by_pid = {}
19
19
  end
20
20
 
21
+ def interval
22
+ if @interval.nil?
23
+ @interval = (ENV['EPI_INTERVAL'] || 5).to_f
24
+ Epi.logger.info "Polling process status every #{@interval} second#{@interval == 1 ? '' : 's'}"
25
+ end
26
+ @interval
27
+ end
28
+
21
29
  def beat!
22
30
 
23
31
  # Cancel any scheduled beats
@@ -50,7 +58,7 @@ module Epi
50
58
  Data.save
51
59
 
52
60
  # Schedule the next beat
53
- @next_beat = EventMachine.add_timer(5) { beat! } # TODO: make interval configurable
61
+ @next_beat = EventMachine.add_timer(interval) { beat! }
54
62
  end
55
63
 
56
64
  def shutdown!(&callback)
@@ -1,3 +1,3 @@
1
1
  module Epi
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neil E. Pearson
@@ -32,6 +32,9 @@ executables:
32
32
  extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
+ - ".yardopts"
36
+ - LICENSE.txt
37
+ - README.md
35
38
  - bin/epi
36
39
  - lib/epi.rb
37
40
  - lib/epi/cli.rb