forever 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,120 +1 @@
1
- # Ruby Forever
2
-
3
- Small daemon framework **for ruby**, with logging, error handler watcher and much more.
4
-
5
- The idea of the name and some concepts was taken by [forever for node.js](https://raw.github.com/indexzero/forever) written by Charlie Robbins.
6
-
7
- Please don't consider this gem as a port because is not.
8
-
9
- The executable name it's called ```foreverb``` to prevent collisions.
10
-
11
- ## Why?
12
-
13
- There are a lot of alternatives, one of the best is [resque](https://github.com/defunkt/resque), so why another daemons framework?
14
- In my servers I've several daemons and what I need is:
15
-
16
- * easily watch the process (memory, cpu)
17
- * easily manage exceptions
18
- * easily see logs
19
- * easily start/stop/restart daemon
20
-
21
- As like [sinatra](https://github.com/sinatra/sinatra) and [padrino](https://github.com/padrino/padrino-framework) I need a
22
- **thin** framework to do these jobs in few seconds. This mean that:
23
-
24
- * I can create a new job quickly
25
- * I can watch, start, stop it quickly
26
-
27
- So, if you have my needs, **Forever** can be the right choice for you.
28
-
29
- ## Install:
30
-
31
- ``` sh
32
- $ gem install forever
33
- ```
34
-
35
- ## Deamon Example:
36
-
37
- Place your script under your standard directory, generally on my env is _bin_ or _scripts_.
38
-
39
- In that case is: ```bin/foo```
40
-
41
- ``` rb
42
- #!/usr/bin/ruby
43
- require 'rubygems' unless defined?(Gem)
44
- require 'forever'
45
- require 'mail'
46
-
47
- Forever.run do
48
- ##
49
- # You can set these values:
50
- #
51
- # dir "foo" # Default: File.expand_path('../../', __FILE__)
52
- # file "bar" # Default: __FILE__
53
- # log "bar.log" # Default: File.expand_path(dir, '/log/[file_name].log')
54
- # pid "bar.pid" # Default: File.expand_path(dir, '/tmp/[file_name].pid')
55
- #
56
-
57
- on_error do |e|
58
- Mail.deliver do
59
- delivery_method :sendmail, :location => `which sendmail`.chomp
60
- to "d.dagostino@lipsiasoft.com"
61
- from "exceptions@lipsiasoft.com"
62
- subject "[Foo Watcher] #{e.message}"
63
- body "%s\n %s" % [e.message, e.backtrace.join("\n ")]
64
- end
65
- end
66
-
67
- on_ready do
68
- require 'bundler/setup'
69
- require 'foo'
70
- Foo.start_loop
71
- end
72
- end
73
- ```
74
-
75
- Assign right permission:
76
-
77
- ``` sh
78
- $ chmod +x bin/foo
79
- ```
80
-
81
- start the daemon:
82
-
83
- ``` sh
84
- $ bin/foo
85
- ```
86
-
87
- you should see an output like:
88
-
89
- ``` sh
90
- $ bin/foo
91
- => Process demonized with pid 19538
92
- ```
93
-
94
- you can stop it:
95
-
96
- ``` sh
97
- $ bin/foo stop
98
- => Found pid 19538...
99
- => Killing process 19538...
100
- ```
101
-
102
- ## Monitor your daemon(s):
103
-
104
- List daemons:
105
-
106
- ``` sh
107
- $ foreverb list
108
- PID RSS CPU CMD
109
- 19838 32512 1.6 Forever: bin/githubwatcher
110
- ```
111
-
112
- Stop daemon(s):
113
-
114
- ``` sh
115
- $ foreverb stop foo
116
- Do you want really stop Forever: bin/foo with pid 19538? y
117
- Killing process Forever: bin/foo with pid 19538...
118
- ```
119
-
120
- That's all!
1
+ MOVED HERE: https://github.com/DAddYE/foreverb
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 2
9
- version: 0.1.2
8
+ - 3
9
+ version: 0.1.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - DAddYE
@@ -16,44 +16,21 @@ cert_chain: []
16
16
 
17
17
  date: 2011-07-08 00:00:00 +02:00
18
18
  default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- name: thor
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- requirements:
25
- - - ~>
26
- - !ruby/object:Gem::Version
27
- segments:
28
- - 0
29
- - 14
30
- - 6
31
- version: 0.14.6
32
- type: :runtime
33
- version_requirements: *id001
19
+ dependencies: []
20
+
34
21
  description: Small daemon framework for ruby, with logging, error handler and more...
35
22
  email:
36
23
  - d.dagostino@lipsiasoft.com
37
- executables:
38
- - forever
39
- - foreverb
24
+ executables: []
25
+
40
26
  extensions: []
41
27
 
42
28
  extra_rdoc_files: []
43
29
 
44
30
  files:
45
- - .gitignore
46
- - Gemfile
47
31
  - README.md
48
- - Rakefile
49
- - bin/forever
50
- - bin/foreverb
51
- - forever.gemspec
52
- - lib/forever.rb
53
- - lib/forever/base.rb
54
- - lib/forever/version.rb
55
32
  has_rdoc: true
56
- homepage: https://github.com/daddye/forever
33
+ homepage: https://github.com/daddye/foreverb
57
34
  licenses: []
58
35
 
59
36
  post_install_message:
data/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- *.gem
2
- .bundle
3
- Gemfile.lock
4
- pkg/*
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in forever.gemspec
4
- gemspec
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require 'rubygems' unless defined?(Gem)
2
- require 'bundler/gem_tasks'
3
-
4
- task :clean do
5
- `rm -rf pkg`
6
- end
@@ -1,2 +0,0 @@
1
- #!/usr/bin/ruby
2
- warn "Use foreverb, this one is deprecated"
@@ -1,34 +0,0 @@
1
- #!/usr/bin/ruby
2
- require 'rubygems' unless defined?(Gem)
3
- require File.expand_path('../../lib/forever/version.rb', __FILE__)
4
- require 'thor'
5
-
6
- class CLI < Thor
7
- desc "list", "List Forever daemons"
8
- def list
9
- say "PID\tRSS\tCPU\tCMD", :green
10
- puts daemons.join("\n")
11
- end
12
-
13
- desc "stop [DAEMON]", "Stop a specified daemon"
14
- def stop(daemon)
15
- found = daemons.find_all { |d| d=~/#{daemon}/i }
16
- say "Daemon(s) matching '#{daemon}' not found", :red if found.empty?
17
- found.each do |daemon|
18
- daemon = daemon.split("\t")
19
- if yes? "Do you want really stop #{daemon[-1]} with pid #{daemon[0]}?"
20
- say "Killing process #{daemon[-1]} with pid #{daemon[0]}...", :green
21
- result = `kill #{daemon[0]}`.strip
22
- say result, :red if result != ""
23
- end
24
- end
25
- end
26
-
27
- private
28
- def daemons
29
- `ps axo pid,rss,pcpu,command | grep -vE "^USER|grep" | grep Forever: | awk '{print $1"\t"$2"\t"$3"\t"$4" "$5" "$6}'`.chomp.split("\n")
30
- end
31
- end
32
-
33
- ARGV << "-h" if ARGV.empty?
34
- CLI.start(ARGV)
@@ -1,21 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "forever/version"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "forever"
7
- s.version = Forever::VERSION
8
- s.authors = ["DAddYE"]
9
- s.email = ["d.dagostino@lipsiasoft.com"]
10
- s.homepage = "https://github.com/daddye/forever"
11
- s.summary = %q{Small daemon framework for ruby}
12
- s.description = %q{Small daemon framework for ruby, with logging, error handler and more...}
13
-
14
- s.rubyforge_project = "forever"
15
-
16
- s.files = `git ls-files`.split("\n")
17
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
- s.require_paths = ["lib"]
20
- s.add_dependency 'thor', '~>0.14.6'
21
- end
@@ -1,12 +0,0 @@
1
- require "forever/base"
2
-
3
- module Forever
4
- extend self
5
-
6
- def run(options={}, &block)
7
- caller_file = caller(1).map { |line| line.split(/:(?=\d|in )/)[0,1] }.flatten.first
8
- options[:dir] ||= File.expand_path('../../', caller_file) # => we presume we are calling it from a bin|script dir
9
- options[:file] ||= File.expand_path(caller_file)
10
- Base.new(options, &block)
11
- end # run
12
- end # Forever
@@ -1,251 +0,0 @@
1
- require 'fileutils'
2
-
3
- module Forever
4
- class Base
5
- def initialize(options={}, &block)
6
- options.each { |k,v| send(k, v) }
7
-
8
- instance_eval(&block)
9
-
10
- Dir.chdir(dir) if exists?(dir)
11
- Dir.mkdir(File.dirname(log)) if log && !File.exist?(File.dirname(log))
12
- Dir.mkdir(File.dirname(pid)) if pid && !File.exist?(File.dirname(pid))
13
-
14
- stop!
15
-
16
- return if ARGV[0] == "stop" || on_ready.nil?
17
-
18
- fork do
19
- $0 = "Forever: #{$0}"
20
- puts "=> Process demonized with pid #{Process.pid}"
21
-
22
- %w(INT TERM KILL).each { |signal| trap(signal) { stop! } }
23
-
24
- File.open(pid, "w") { |f| f.write(Process.pid.to_s) } if pid
25
-
26
- stream = log ? File.new(log, "w") : File.open('/dev/null', 'w')
27
- stream.sync = true
28
-
29
- STDOUT.reopen(stream)
30
- STDERR.reopen(STDOUT)
31
-
32
- begin
33
- on_ready.call
34
- rescue Exception => e
35
- Thread.list.reject { |t| t==Thread.current }.map(&:kill)
36
- on_error[e] if on_error
37
- stream.print "\n\n%s\n %s\n\n" % [e.message, e.backtrace.join("\n ")]
38
- sleep 30
39
- retry
40
- end
41
- end
42
- end
43
-
44
- ##
45
- # Caller file
46
- #
47
- def file(value=nil)
48
- value ? @_file = value : @_file
49
- end
50
-
51
- ##
52
- # Base working Directory
53
- #
54
- def dir(value=nil)
55
- value ? @_dir = value : @_dir
56
- end
57
-
58
- ##
59
- # File were we redirect STOUT and STDERR, can be false.
60
- #
61
- # Default: dir + 'log/[process_name].log'
62
- #
63
- def log(value=nil)
64
- @_log ||= File.join(dir, "log/#{File.basename(file)}.log") if exists?(dir, file)
65
- value ? @_log = value : @_log
66
- end
67
-
68
- ##
69
- # File were we store pid
70
- #
71
- # Default: dir + 'tmp/[process_name].pid'
72
- #
73
- def pid(value=nil)
74
- @_pid ||= File.join(dir, "tmp/#{File.basename(file)}.pid") if exists?(dir, file)
75
- value ? @_pid = value : @_pid
76
- end
77
-
78
- ##
79
- # Search if there is a running process and stop it
80
- #
81
- def stop!(kill=true)
82
- if exists?(pid)
83
- _pid = File.read(pid).to_i
84
- puts "=> Found pid #{_pid}..."
85
- FileUtils.rm_f(pid)
86
- begin
87
- puts "=> Killing process #{_pid}..."
88
- Process.kill(:KILL, _pid)
89
- rescue Errno::ESRCH => e
90
- puts "=> #{e.message}"
91
- end
92
- else
93
- puts "=> Pid not found, process seems don't exist!"
94
- end
95
- end
96
-
97
- ##
98
- # Callback raised when an error occour
99
- #
100
- def on_error(&block)
101
- block_given? ? @_on_error = block : @_on_error
102
- end
103
-
104
- ##
105
- # Callback to fire when the daemon start
106
- #
107
- def on_ready(&block)
108
- block_given? ? @_on_error = block : @_on_error
109
- end
110
-
111
- def to_s
112
- "#<Forever dir:#{dir}, file:#{file}, log:#{log}, pid:#{pid}>"
113
- end
114
- alias :inspect :to_s
115
-
116
- def config
117
- { :dir => dir, :file => file, :log => log, :pid => pid }.to_yaml
118
- end
119
- alias :to_yaml :config
120
-
121
- private
122
- def exists?(*values)
123
- values.all? { |value| value && File.exist?(value) }
124
- end
125
- end # Base
126
- end # Foreverrequire 'fileutils'
127
-
128
- module Forever
129
- class Base
130
- def initialize(options={}, &block)
131
- options.each { |k,v| send(k, v) }
132
-
133
- instance_eval(&block)
134
-
135
- Dir.chdir(dir) if exists?(dir)
136
- Dir.mkdir(File.dirname(log)) if log && !File.exist?(File.dirname(log))
137
- Dir.mkdir(File.dirname(pid)) if pid && !File.exist?(File.dirname(pid))
138
-
139
- stop!
140
-
141
- return if ARGV[0] == "stop" || on_ready.nil?
142
-
143
- fork do
144
- $0 = "Forever: #{$0}"
145
- puts "=> Process demonized with pid #{Process.pid}"
146
-
147
- %w(INT TERM KILL).each { |signal| trap(signal) { stop! } }
148
-
149
- File.open(pid, "w") { |f| f.write(Process.pid.to_s) } if pid
150
-
151
- stream = log ? File.new(log, "w") : File.open('/dev/null', 'w')
152
- stream.sync = true
153
-
154
- STDOUT.reopen(stream)
155
- STDERR.reopen(STDOUT)
156
-
157
- begin
158
- on_ready.call
159
- rescue Exception => e
160
- Thread.list.reject { |t| t==Thread.current }.map(&:kill)
161
- on_error[e] if on_error
162
- stream.print "\n\n%s\n %s\n\n" % [e.message, e.backtrace.join("\n ")]
163
- sleep 30
164
- retry
165
- end
166
- end
167
- end
168
-
169
- ##
170
- # Caller file
171
- #
172
- def file(value=nil)
173
- value ? @_file = value : @_file
174
- end
175
-
176
- ##
177
- # Base working Directory
178
- #
179
- def dir(value=nil)
180
- value ? @_dir = value : @_dir
181
- end
182
-
183
- ##
184
- # File were we redirect STOUT and STDERR, can be false.
185
- #
186
- # Default: dir + 'log/[process_name].log'
187
- #
188
- def log(value=nil)
189
- @_log ||= File.join(dir, "log/#{File.basename(file)}.log") if exists?(dir, file)
190
- value ? @_log = value : @_log
191
- end
192
-
193
- ##
194
- # File were we store pid
195
- #
196
- # Default: dir + 'tmp/[process_name].pid'
197
- #
198
- def pid(value=nil)
199
- @_pid ||= File.join(dir, "tmp/#{File.basename(file)}.pid") if exists?(dir, file)
200
- value ? @_pid = value : @_pid
201
- end
202
-
203
- ##
204
- # Search if there is a running process and stop it
205
- #
206
- def stop!(kill=true)
207
- if exists?(pid)
208
- _pid = File.read(pid).to_i
209
- puts "=> Found pid #{_pid}..."
210
- FileUtils.rm_f(pid)
211
- begin
212
- puts "=> Killing process #{_pid}..."
213
- Process.kill(:KILL, _pid)
214
- rescue Errno::ESRCH => e
215
- puts "=> #{e.message}"
216
- end
217
- else
218
- puts "=> Pid not found, process seems don't exist!"
219
- end
220
- end
221
-
222
- ##
223
- # Callback raised when an error occour
224
- #
225
- def on_error(&block)
226
- block_given? ? @_on_error = block : @_on_error
227
- end
228
-
229
- ##
230
- # Callback to fire when the daemon start
231
- #
232
- def on_ready(&block)
233
- block_given? ? @_on_error = block : @_on_error
234
- end
235
-
236
- def to_s
237
- "#<Forever dir:#{dir}, file:#{file}, log:#{log}, pid:#{pid}>"
238
- end
239
- alias :inspect :to_s
240
-
241
- def config
242
- { :dir => dir, :file => file, :log => log, :pid => pid }.to_yaml
243
- end
244
- alias :to_yaml :config
245
-
246
- private
247
- def exists?(*values)
248
- values.all? { |value| value && File.exist?(value) }
249
- end
250
- end # Base
251
- end # Forever
@@ -1,3 +0,0 @@
1
- module Forever
2
- VERSION = "0.1.2"
3
- end