process-daemon 0.6.1 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ce61de8f6a1e9c039282f457fed948aa8221d709
4
- data.tar.gz: e44c53039d96fc318d894527010a5f378c4fe490
3
+ metadata.gz: 4f2719836b2dfefcb18754e6157764c3f964d667
4
+ data.tar.gz: 696fd41006946dd13a6a04eaabef60e5f35c8925
5
5
  SHA512:
6
- metadata.gz: 8530411f7ca42fc9726424da6fc39358d2f6ca32fae5e67e8a6ec94682d2f2f4f7dbd7094c8367ab772f4762fadb89d495266be281d1d84e8121cc4bbcef7cd9
7
- data.tar.gz: 883851f2915344371a49de317a9d6fd057b7b70ec638a3a4a6a9c438baf17c3ad73fc17ecabe9896a8c0591c9b7e86e20d55ba786ea20e467fe0dd805475e4fd
6
+ metadata.gz: 4a2c171b1f7007a6c69e198ee47b56409c870a6c6fe525b6d0b75f75529ea8a4cc802bf22aaad27751f0ec7e631c6ea2221be4ad83e64b4ffe4fe84b1554aeb5
7
+ data.tar.gz: 37b32a1adec863f0b34451b11e1dec6ddaed83e0c568be6f72d4171e5b878a7c873814353f19273ad901e63933381ee2a4699c340b18735742da40432bec4d2c
@@ -1,11 +1,10 @@
1
1
  language: ruby
2
2
  sudo: false
3
3
  rvm:
4
- - 2.2
5
- - 2.1
6
- - 2.0
4
+ - 2.0.0
5
+ - 2.1.8
6
+ - 2.2.4
7
+ - 2.3.0
8
+ - ruby-head
7
9
  - rbx-2
8
- matrix:
9
- allow_failures:
10
- - rvm: rbx-2
11
10
  env: COVERAGE=true
data/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  `Process::Daemon` is a stable and helpful base class for long running tasks and daemons. Provides standard `start`, `stop`, `restart`, `status` operations.
4
4
 
5
- [![Build Status](https://travis-ci.org/ioquatix/process-daemon.svg?branch=master)](https://travis-ci.org/ioquatix/process-daemon)
6
- [![Code Climate](https://codeclimate.com/github/ioquatix/process-daemon.png)](https://codeclimate.com/github/ioquatix/process-daemon)
7
- [![Coverage Status](https://coveralls.io/repos/ioquatix/process-daemon/badge.svg?branch=master)](https://coveralls.io/r/ioquatix/process-daemon?branch=master)
5
+ [![Build Status](https://travis-ci.org/ioquatix/process-daemon.svg)](https://travis-ci.org/ioquatix/process-daemon)
6
+ [![Code Climate](https://codeclimate.com/github/ioquatix/process-daemon.svg)](https://codeclimate.com/github/ioquatix/process-daemon)
7
+ [![Coverage Status](https://coveralls.io/repos/ioquatix/process-daemon/badge.svg)](https://coveralls.io/r/ioquatix/process-daemon)
8
8
  [![Documentation](http://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/gems/process-daemon)
9
9
  [![Code](http://img.shields.io/badge/github-code-blue.svg)](https://github.com/ioquatix/process-daemon)
10
10
 
@@ -162,38 +162,38 @@ module Process
162
162
  self.shutdown
163
163
  end
164
164
 
165
- # A shared instance of the daemon.
166
- def self.instance
167
- @instance ||= self.new
168
- end
169
-
170
- # The process controller, responsible for managing the daemon process start, stop, restart, etc.
171
- def self.controller(options = {})
172
- @controller ||= Controller.new(instance, options)
173
- end
174
-
175
- # The main entry point for daemonized scripts.
176
- def self.daemonize(*args)
177
- # Wish Ruby 2.0 kwargs were backported to 1.9.3... oh well:
178
- options = (args.last === Hash) ? args.pop : {}
179
- argv = (args.last === Array) ? args.pop : ARGV
165
+ class << self
166
+ # A shared instance of the daemon.
167
+ def instance
168
+ @instance ||= self.new
169
+ end
180
170
 
181
- controller(options).daemonize(argv)
182
- end
183
-
184
- # Start the shared daemon instance.
185
- def self.start
186
- controller.start
187
- end
188
-
189
- # Stop the shared daemon instance.
190
- def self.stop
191
- controller.stop
192
- end
193
-
194
- # Check if the shared daemon instance is runnning or not.
195
- def self.status
196
- controller.status
171
+ # The process controller, responsible for managing the daemon process start, stop, restart, etc.
172
+ def controller(options = {})
173
+ @controller ||= Controller.new(instance, options)
174
+ end
175
+
176
+ # The main entry point for daemonized scripts.
177
+ def daemonize(*args, **options)
178
+ args = ARGV if args.empty?
179
+
180
+ controller(options).daemonize(args)
181
+ end
182
+
183
+ # Start the shared daemon instance.
184
+ def start
185
+ controller.start
186
+ end
187
+
188
+ # Stop the shared daemon instance.
189
+ def stop
190
+ controller.stop
191
+ end
192
+
193
+ # Check if the shared daemon instance is runnning or not.
194
+ def status
195
+ controller.status
196
+ end
197
197
  end
198
198
  end
199
199
  end
@@ -42,18 +42,18 @@ module Process
42
42
  case (argv.shift || :default).to_sym
43
43
  when :start
44
44
  start
45
- status
45
+ show_status
46
46
  when :stop
47
47
  stop
48
- status
48
+ show_status
49
49
  ProcessFile.cleanup(@daemon)
50
50
  when :restart
51
51
  stop
52
52
  ProcessFile.cleanup(@daemon)
53
53
  start
54
- status
54
+ show_status
55
55
  when :status
56
- status
56
+ show_status
57
57
  else
58
58
  @output.puts Rainbow("Invalid command. Please specify start, restart, stop or status.").red
59
59
  end
@@ -73,8 +73,8 @@ module Process
73
73
  File.umask 0000
74
74
  Dir.chdir @daemon.working_directory
75
75
 
76
- $stdin.reopen "/dev/null"
77
- $stdout.reopen @daemon.log_file_path, "a"
76
+ $stdin.reopen '/dev/null'
77
+ $stdout.reopen @daemon.log_file_path, 'a'
78
78
  $stdout.sync = true
79
79
 
80
80
  $stderr.reopen $stdout
@@ -99,7 +99,7 @@ module Process
99
99
  def start
100
100
  @output.puts Rainbow("Starting #{@daemon.name} daemon...").blue
101
101
 
102
- case ProcessFile.status(@daemon)
102
+ case self.status
103
103
  when :running
104
104
  @output.puts Rainbow("Daemon already running!").blue
105
105
  return
@@ -132,9 +132,11 @@ module Process
132
132
 
133
133
  # Prints out the status of the daemon
134
134
  def status
135
- daemon_state = ProcessFile.status(@daemon)
136
-
137
- case daemon_state
135
+ ProcessFile.status(@daemon)
136
+ end
137
+
138
+ def show_status
139
+ case self.status
138
140
  when :running
139
141
  @output.puts Rainbow("Daemon status: running pid=#{ProcessFile.recall(@daemon)}").green
140
142
  when :unknown
@@ -150,8 +152,6 @@ module Process
150
152
  when :stopped
151
153
  @output.puts Rainbow("Daemon status: stopped").blue
152
154
  end
153
-
154
- return daemon_state
155
155
  end
156
156
 
157
157
  # The pid of the daemon if it is available. The pid may be invalid if the daemon has crashed.
@@ -31,7 +31,7 @@ module Process
31
31
  reverse_each_line do |line|
32
32
  lines << line
33
33
 
34
- break if yield line
34
+ break if block_given? and yield line
35
35
  end
36
36
 
37
37
  return lines.reverse
@@ -81,14 +81,19 @@ module Process
81
81
 
82
82
  while offset == nil
83
83
  chunk = read_reverse(REVERSE_BUFFER_SIZE)
84
+
84
85
  return (buf == "" ? nil : buf) if chunk == nil
85
86
 
86
87
  buf = chunk + buf
87
88
 
88
- offset = buf.rindex(sep_string)
89
+ # Don't consider the last newline.
90
+ offset = buf.rindex(sep_string, -(sep_string.length + 1))
89
91
  end
90
92
 
91
- line = buf[offset...buf.size].sub(sep_string, "")
93
+ # Don't include newline:
94
+ offset += 1
95
+
96
+ line = buf[offset...buf.size]
92
97
 
93
98
  seek((end_pos - buf.size) + offset, IO::SEEK_SET)
94
99
 
@@ -20,6 +20,6 @@
20
20
 
21
21
  module Process
22
22
  class Daemon
23
- VERSION = "0.6.1"
23
+ VERSION = "1.0.0"
24
24
  end
25
25
  end
@@ -23,6 +23,6 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency "rainbow", "~> 2.0"
24
24
 
25
25
  spec.add_development_dependency "bundler", "~> 1.3"
26
- spec.add_development_dependency "rspec", "~> 3.3.0"
26
+ spec.add_development_dependency "rspec", "~> 3.4.0"
27
27
  spec.add_development_dependency "rake"
28
28
  end
@@ -0,0 +1,57 @@
1
+ # Copyright, 2007, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'process/daemon'
22
+
23
+ require 'webrick'
24
+ require 'webrick/https'
25
+
26
+ require 'xmlrpc/server'
27
+ require 'xmlrpc/client'
28
+
29
+ module Process::Daemon::DaemonizeSpec
30
+ class CrashDaemon < Process::Daemon
31
+ def working_directory
32
+ File.expand_path("../tmp", __FILE__)
33
+ end
34
+
35
+ def run
36
+ and_bobs_your_uncle
37
+ end
38
+ end
39
+
40
+ describe Process::Daemon do
41
+ it "should crash daemon and print exception" do
42
+ output = StringIO.new
43
+
44
+ controller = Process::Daemon::Controller.new(CrashDaemon.instance, :output => output)
45
+
46
+ controller.start
47
+
48
+ sleep 1
49
+
50
+ controller.show_status
51
+
52
+ expect(CrashDaemon.status).to be == :unknown
53
+ expect(output.string).to include("=== Daemon Exception Backtrace", "=== Daemon Crashed")
54
+ expect(output.string).to include("NameError", "and_bobs_your_uncle")
55
+ end
56
+ end
57
+ end
@@ -69,14 +69,10 @@ module Process::Daemon::DaemonSpec
69
69
  end
70
70
  end
71
71
 
72
- class SleepDaemon < Process::Daemon
72
+ class DefaultDaemon < Process::Daemon
73
73
  def working_directory
74
74
  File.expand_path("../tmp", __FILE__)
75
75
  end
76
-
77
- def run
78
- sleep 1 while true
79
- end
80
76
  end
81
77
 
82
78
  describe Process::Daemon do
@@ -90,6 +86,7 @@ module Process::Daemon::DaemonSpec
90
86
 
91
87
  it "should be running" do
92
88
  expect(XMLRPCDaemon.status).to be == :running
89
+ expect(XMLRPCDaemon.instance.crashed?).to be_falsey
93
90
  end
94
91
 
95
92
  it "should respond to connections" do
@@ -102,7 +99,7 @@ module Process::Daemon::DaemonSpec
102
99
  end
103
100
 
104
101
  it "should be a unique instance" do
105
- expect(XMLRPCDaemon.instance).to_not be == SleepDaemon.instance
102
+ expect(XMLRPCDaemon.instance).to_not be == DefaultDaemon.instance
106
103
  end
107
104
 
108
105
  it "should produce useful output" do
@@ -112,6 +109,7 @@ module Process::Daemon::DaemonSpec
112
109
 
113
110
  expect(controller.status).to be == :running
114
111
 
112
+ controller.show_status
115
113
  expect(output.string).to match /Daemon status: running pid=\d+/
116
114
 
117
115
  output.rewind
@@ -0,0 +1,57 @@
1
+ # Copyright, 2007, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'process/daemon'
22
+
23
+ require 'webrick'
24
+ require 'webrick/https'
25
+
26
+ require 'xmlrpc/server'
27
+ require 'xmlrpc/client'
28
+
29
+ module Process::Daemon::DaemonizeSpec
30
+ class SleepDaemon < Process::Daemon
31
+ def working_directory
32
+ File.expand_path("../tmp", __FILE__)
33
+ end
34
+ end
35
+
36
+ describe Process::Daemon do
37
+ it "should start daemon" do
38
+ SleepDaemon.daemonize(:start)
39
+
40
+ expect(SleepDaemon.status).to be == :running
41
+
42
+ SleepDaemon.daemonize(:stop)
43
+
44
+ expect(SleepDaemon.status).to be == :stopped
45
+ end
46
+
47
+ it "should restart daemon" do
48
+ SleepDaemon.daemonize(:restart)
49
+
50
+ expect(SleepDaemon.status).to be == :running
51
+
52
+ SleepDaemon.daemonize(:stop)
53
+
54
+ expect(SleepDaemon.status).to be == :stopped
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,36 @@
1
+ # Copyright, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'process/daemon'
22
+ require 'process/daemon/log_file'
23
+
24
+ module Process::Daemon::LogFileSpec
25
+ describe Process::Daemon::LogFile do
26
+ let(:daemon) {SleepDaemon.instance}
27
+
28
+ it "should give the several last lines" do
29
+ lines = File.readlines(__FILE__)
30
+
31
+ log_file = Process::Daemon::LogFile.open(__FILE__)
32
+
33
+ expect(log_file.tail_log).to be == lines
34
+ end
35
+ end
36
+ end
@@ -38,6 +38,7 @@ module Process::Daemon::NotificationSpec
38
38
  end
39
39
 
40
40
  it "can be signalled within trap context and across processes" do
41
+ ready = Process::Daemon::Notification.new
41
42
  notification = Process::Daemon::Notification.new
42
43
 
43
44
  pid = fork do
@@ -46,9 +47,13 @@ module Process::Daemon::NotificationSpec
46
47
  exit(0)
47
48
  end
48
49
 
50
+ ready.signal
51
+
49
52
  sleep
50
53
  end
51
54
 
55
+ ready.wait(timeout: 5.0)
56
+
52
57
  Process.kill(:INT, pid)
53
58
 
54
59
  notification.wait(timeout: 1.0)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: process-daemon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-23 00:00:00.000000000 Z
11
+ date: 2016-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 3.3.0
47
+ version: 3.4.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 3.3.0
54
+ version: 3.4.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -88,8 +88,11 @@ files:
88
88
  - lib/process/daemon/process_file.rb
89
89
  - lib/process/daemon/version.rb
90
90
  - process-daemon.gemspec
91
+ - spec/process/daemon/crashed_daemon_spec.rb
91
92
  - spec/process/daemon/daemon.rb
92
93
  - spec/process/daemon/daemon_spec.rb
94
+ - spec/process/daemon/daemonize_spec.rb
95
+ - spec/process/daemon/log_file_spec.rb
93
96
  - spec/process/daemon/notification_spec.rb
94
97
  - spec/process/daemon/privileges_spec.rb
95
98
  - spec/process/daemon/process_file_spec.rb
@@ -113,15 +116,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
116
  version: '0'
114
117
  requirements: []
115
118
  rubyforge_project:
116
- rubygems_version: 2.2.2
119
+ rubygems_version: 2.4.6
117
120
  signing_key:
118
121
  specification_version: 4
119
122
  summary: "`Process::Daemon` is a stable and helpful base class for long running tasks
120
123
  and daemons. Provides standard `start`, `stop`, `restart`, `status` operations."
121
124
  test_files:
125
+ - spec/process/daemon/crashed_daemon_spec.rb
122
126
  - spec/process/daemon/daemon.rb
123
127
  - spec/process/daemon/daemon_spec.rb
128
+ - spec/process/daemon/daemonize_spec.rb
129
+ - spec/process/daemon/log_file_spec.rb
124
130
  - spec/process/daemon/notification_spec.rb
125
131
  - spec/process/daemon/privileges_spec.rb
126
132
  - spec/process/daemon/process_file_spec.rb
127
- has_rdoc: yard