epi 0.1.0 → 0.1.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 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