ruby-watchcat-pure 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README +64 -0
  2. data/examples/example.rb +21 -0
  3. data/lib/watchcat.rb +142 -0
  4. metadata +57 -0
data/README ADDED
@@ -0,0 +1,64 @@
1
+ == Introduction
2
+
3
+ Ruby/Watchcat allows the development of watchcatd-aware applications in
4
+ Ruby.
5
+
6
+ Watchcatd is a watchdog-like daemon in the sense that it takes actions
7
+ in situations where a machine is under heavy load and/or unresponsive.
8
+ However, watchcatd isn't as drastic as the usual watchdog systems, which
9
+ generally reboot the machine. Instead, all it does is sending a signal to
10
+ a registered process (which by default is SIGKILL) if the process doesn't
11
+ send it a heartbeat before a user-specified timeout.
12
+
13
+ Ruby/Watchcatd allows a Ruby application to register itself with watchcatd.
14
+
15
+
16
+ == Requirements
17
+
18
+ Ruby/Watchcatd was tested with Ruby versions >= 1.8.4 and requires watchcatd
19
+ version 1.1 and libwcat version 1.0 to be installed (see References below).
20
+
21
+
22
+ == Installation
23
+
24
+ The easiest way to install Ruby/Watchcat is to use rubygems:
25
+
26
+ * For the C extension:
27
+ gem install ruby-watchcat
28
+
29
+ * For the pure-Ruby version:
30
+ gem install ruby-watchcat-pure
31
+
32
+ The C extension requires you to have the libwcat development package
33
+ installed.
34
+
35
+ == License
36
+
37
+ Copyright (c) 2006, 2007, 2008 Andre Nathan <andre@digirati.com.br>
38
+
39
+ Permission to use, copy, modify, and distribute this software for any
40
+ purpose with or without fee is hereby granted, provided that the above
41
+ copyright notice and this permission notice appear in all copies.
42
+
43
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
44
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
45
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
46
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
47
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
48
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
49
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
50
+
51
+
52
+ == Author
53
+
54
+ Ruby/Watchcat was developed by Andre Nathan.
55
+
56
+
57
+ == References
58
+
59
+ * Ruby/Watchcat homepage:
60
+ http://oss.digirati.com.br/ruby-watchcat/
61
+ * Rubyforge project home:
62
+ http://www.rubyforge.org/projects/watchcat
63
+ * Watchcatd and libwcat:
64
+ http://oss.digirati.com.br/watchcatd/
@@ -0,0 +1,21 @@
1
+ require 'watchcat'
2
+
3
+ # Create a new cat.
4
+ cat = Watchcat.new(:timeout => 5, :signal => 'KILL', :info => 'rubykill!')
5
+ loop do
6
+ # Do something that might be slow.
7
+ sleep 4 + rand(3)
8
+ puts 'survived'
9
+ cat.heartbeat
10
+ end
11
+ cat.close # clean cat's litter box.
12
+
13
+ # If you call it with a block, the cat cleans its own litter box.
14
+ Watchcat.new do |cat|
15
+ loop do
16
+ # Do something that might be slow.
17
+ sleep 4 + rand(3)
18
+ puts 'survived'
19
+ cat.heartbeat
20
+ end
21
+ end
data/lib/watchcat.rb ADDED
@@ -0,0 +1,142 @@
1
+ #--
2
+ # Copyright (c) 2008 Andre Nathan <andre@digirati.com.br>
3
+ #
4
+ # Permission to use, copy, modify, and distribute this software for any
5
+ # purpose with or without fee is hereby granted, provided that the above
6
+ # copyright notice and this permission notice appear in all copies.
7
+ #
8
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ #
16
+ # $Id: watchcat.rb 24 2008-08-04 14:47:08Z andre $
17
+ #++
18
+
19
+ # Pure-ruby version of libwcat.
20
+
21
+ require 'fcntl'
22
+ require 'socket'
23
+
24
+ #
25
+ # == Overview
26
+ #
27
+ # Ruby/Watchcat is a library for the development of watchcatd-aware
28
+ # applications. It requires watchcatd to be installed and running, and
29
+ # communicates with it via UNIX sockets.
30
+ #
31
+ class Watchcat
32
+ DEFAULT_TIMEOUT = 60
33
+ DEFAULT_DEVICE = '/dev/watchcat'
34
+ DEFAULT_SIGNAL = Signal.list['KILL']
35
+
36
+ # Create a new Watchcat object. The parameter hash may have the following
37
+ # symbols:
38
+ # +timeout+::
39
+ # If watchcatd doesn't receive a heartbeat after this period (in seconds),
40
+ # it will signal the process. (default: 60)
41
+ # +signal+::
42
+ # Defines which signal will be sent to the process after the timeout
43
+ # expires. Can be a string like 'HUP' or 'SIGHUP' or an integer like 9.
44
+ # (default: 9)
45
+ # +info+::
46
+ # Should be a string which is added to the log generated by watchcatd
47
+ # when it signals a process. (default: nil)
48
+ # +device+::
49
+ # The watchcat device. (default: +/dev/watchcat+). Use for debugging
50
+ # purposes.
51
+ #
52
+ # If a block is given, the Watchcat object will be yielded and automatically
53
+ # closed on block termination.
54
+ def initialize(args = {}) # :yield:
55
+ timeout = args[:timeout] || DEFAULT_TIMEOUT
56
+ device = args[:device] || DEFAULT_DEVICE
57
+ info = args[:info] ? args[:info].to_s : ''
58
+
59
+ unless timeout.is_a? Fixnum
60
+ raise ArgumentError, 'timeout must be an integer'
61
+ end
62
+
63
+ case args[:signal]
64
+ when nil
65
+ signal = DEFAULT_SIGNAL
66
+ when String
67
+ signal = Signal.list[args[:signal].sub(/^SIG/, '')]
68
+ raise ArgumentError, "invalid signal name" if signal.nil?
69
+ when Fixnum
70
+ signal = args[:signal]
71
+ else
72
+ raise ArgumentError, "signal must be an integer or a string"
73
+ end
74
+
75
+ @sock = UNIXSocket.new(device)
76
+ if Fcntl.const_defined? :F_SETFD
77
+ @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
78
+ end
79
+
80
+ msg = "version: 1\ntimeout: #{timeout}\nsignal: #{signal}"
81
+ if info.nil?
82
+ msg << "\n\n"
83
+ else
84
+ info.gsub!(/\n/, '_')
85
+ msg << "\ninfo: #{info}\n\n"
86
+ end
87
+
88
+ safe_write(@sock, msg)
89
+ if safe_read(@sock, 256) == "ok\n"
90
+ if block_given?
91
+ begin
92
+ yield(self)
93
+ ensure
94
+ @sock.close
95
+ end
96
+ end
97
+ return self
98
+ else
99
+ @sock.close
100
+ # Probably not the best error, but it matches the C library.
101
+ raise Errno::EPERM
102
+ end
103
+ end
104
+
105
+ # Send a heartbeat to watchcatd, telling it we're still alive.
106
+ def heartbeat
107
+ safe_write(@sock, '.')
108
+ return nil
109
+ end
110
+
111
+ # Close communication with watchcatd.
112
+ def close
113
+ begin
114
+ @sock.close
115
+ rescue Errno::EINTR
116
+ retry
117
+ end
118
+ return nil
119
+ end
120
+
121
+ private
122
+
123
+ def safe_write(fd, buf)
124
+ act = Signal.trap('PIPE', 'IGN')
125
+ begin
126
+ fd.syswrite(buf)
127
+ rescue Errno::EINTR
128
+ retry
129
+ end
130
+ Signal.trap('PIPE', act)
131
+ end
132
+
133
+ def safe_read(fd, len)
134
+ buf = ''
135
+ begin
136
+ buf = fd.sysread(len)
137
+ rescue Errno::EINTR
138
+ retry
139
+ end
140
+ return buf
141
+ end
142
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-watchcat-pure
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Andre Nathan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-08-06 00:00:00 -03:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Ruby/Watchcat-Pure is a pure-ruby implementation of libwatchcat for the development of watchcatd-aware applications.
17
+ email: andre@digirati.com.br
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - README
26
+ - lib/watchcat.rb
27
+ - examples/example.rb
28
+ has_rdoc: true
29
+ homepage: http://watchcat.rubyforge.org
30
+ post_install_message:
31
+ rdoc_options:
32
+ - --title
33
+ - Ruby/Watchcat--main
34
+ - README
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: "0"
42
+ version:
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ requirements:
50
+ - watchcatd
51
+ rubyforge_project: ruby-watchcat
52
+ rubygems_version: 1.0.0
53
+ signing_key:
54
+ specification_version: 2
55
+ summary: A pure-ruby implementation of libwatchcat
56
+ test_files: []
57
+