rq 0.1.7

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.
@@ -0,0 +1,286 @@
1
+ unless defined? $__rq_util__
2
+ module RQ
3
+ #{{{
4
+ LIBDIR = File::dirname(File::expand_path(__FILE__)) + File::SEPARATOR unless
5
+ defined? LIBDIR
6
+
7
+ require 'pathname'
8
+ require 'socket'
9
+ require 'tmpdir'
10
+
11
+ module Util
12
+ #{{{
13
+ class << self
14
+ def export sym
15
+ #{{{
16
+ sym = "#{ sym }".intern
17
+ module_function sym
18
+ public sym
19
+ #}}}
20
+ end
21
+ def append_features c
22
+ #{{{
23
+ super
24
+ c.extend Util
25
+ #}}}
26
+ end
27
+ end
28
+ def mcp obj
29
+ #{{{
30
+ Marshal.load(Marshal.dump(obj))
31
+ #}}}
32
+ end
33
+ export 'mcp'
34
+ def klass
35
+ #{{{
36
+ self.class
37
+ #}}}
38
+ end
39
+ export 'klass'
40
+ def realpath path
41
+ #{{{
42
+ path = File::expand_path "#{ path }"
43
+ begin
44
+ Pathname::new(path).realpath.to_s
45
+ rescue Errno::ENOENT, Errno::ENOTDIR
46
+ path
47
+ end
48
+ #}}}
49
+ end
50
+ export 'realpath'
51
+ def hashify(*hashes)
52
+ #{{{
53
+ hashes.inject(accum={}){|accum,hash| accum.update hash}
54
+ #}}}
55
+ end
56
+ export 'hashify'
57
+ def getopt opt, hash, default = nil
58
+ #{{{
59
+ key = opt
60
+ return hash[key] if hash.has_key? key
61
+
62
+ key = "#{ key }"
63
+ return hash[key] if hash.has_key? key
64
+
65
+ key = key.intern
66
+ return hash[key] if hash.has_key? key
67
+
68
+ return default
69
+ #}}}
70
+ end
71
+ export 'getopt'
72
+ def alive? pid
73
+ #{{{
74
+ pid = Integer("#{ pid }")
75
+ begin
76
+ Process.kill 0, pid
77
+ true
78
+ rescue Errno::ESRCH
79
+ false
80
+ end
81
+ #}}}
82
+ end
83
+ export 'alive?'
84
+ def maim(pid, opts = {})
85
+ #{{{
86
+ sigs = getopt('signals', opts) || %w(SIGTERM SIGQUIT SIGKILL)
87
+ suspend = getopt('suspend', opts) || 4
88
+ pid = Integer("#{ pid }")
89
+ sigs.each do |sig|
90
+ begin
91
+ Process.kill(sig, pid)
92
+ rescue Errno::ESRCH
93
+ return nil
94
+ end
95
+ sleep 0.2
96
+ unless alive?(pid)
97
+ break
98
+ else
99
+ sleep suspend
100
+ end
101
+ end
102
+ not alive?(pid)
103
+ #}}}
104
+ end
105
+ export 'maim'
106
+ def timestamp time = Time.now
107
+ #{{{
108
+ usec = "#{ time.usec }"
109
+ usec << ('0' * (6 - usec.size)) if usec.size < 6
110
+ time.strftime('%Y-%m-%d %H:%M:%S.') << usec
111
+ #}}}
112
+ end
113
+ export 'timestamp'
114
+ def stamptime string, local = true
115
+ #{{{
116
+ string = "#{ string }"
117
+ pat = %r/^\s*(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d).(\d\d\d\d\d\d)\s*$/o
118
+ match = pat.match string
119
+ raise ArgumentError, "<#{ string.inspect }>" unless match
120
+ yyyy,mm,dd,h,m,s,u = match.to_a[1..-1].map{|m| m.to_i}
121
+ if local
122
+ Time.local yyyy,mm,dd,h,m,s,u
123
+ else
124
+ Time.gm yyyy,mm,dd,h,m,s,u
125
+ end
126
+ #}}}
127
+ end
128
+ export 'stamptime'
129
+ def escape! s, char, esc
130
+ #{{{
131
+ re = %r/([#{0x5c.chr << esc}]*)#{char}/
132
+ s.gsub!(re) do
133
+ (($1.size % 2 == 0) ? ($1 << esc) : $1) + char
134
+ end
135
+ #}}}
136
+ end
137
+ export 'escape!'
138
+ def escape s, char, esc
139
+ #{{{
140
+ ss = "#{ s }"
141
+ escape! ss, char, esc
142
+ ss
143
+ #}}}
144
+ end
145
+ export 'escape'
146
+ def fork(*args, &block)
147
+ #{{{
148
+ begin
149
+ verbose = $VERBOSE
150
+ $VERBOSE = nil
151
+ Process::fork(*args, &block)
152
+ ensure
153
+ $VERBOSE = verbose
154
+ end
155
+ #}}}
156
+ end
157
+ export 'fork'
158
+ def exec(*args, &block)
159
+ #{{{
160
+ begin
161
+ verbose = $VERBOSE
162
+ $VERBOSE = nil
163
+ Kernel::exec(*args, &block)
164
+ ensure
165
+ $VERBOSE = verbose
166
+ end
167
+ #}}}
168
+ end
169
+ export 'exec'
170
+ def system(*args, &block)
171
+ #{{{
172
+ begin
173
+ verbose = $VERBOSE
174
+ $VERBOSE = nil
175
+ Kernel::system(*args, &block)
176
+ ensure
177
+ $VERBOSE = verbose
178
+ end
179
+ #}}}
180
+ end
181
+ export 'system'
182
+ def hostname
183
+ #{{{
184
+ @__hostname__ ||= Socket::gethostname
185
+ #}}}
186
+ end
187
+ export 'hostname'
188
+ def host
189
+ #{{{
190
+ @__host__ ||= Socket::gethostname.gsub(%r/\..*$/o,'')
191
+ #}}}
192
+ end
193
+ export 'host'
194
+ def emsg e
195
+ #{{{
196
+ "#{ e.message } - (#{ e.class })"
197
+ #}}}
198
+ end
199
+ export 'emsg'
200
+ def btrace e
201
+ #{{{
202
+ (e.backtrace or []).join("\n")
203
+ #}}}
204
+ end
205
+ export 'btrace'
206
+ def errmsg e
207
+ #{{{
208
+ emsg(e) << "\n" << btrace(e)
209
+ #}}}
210
+ end
211
+ export 'errmsg'
212
+ def erreq a, b
213
+ #{{{
214
+ a.class == b.class and
215
+ a.message == b.message and
216
+ a.backtrace == b.backtrace
217
+ #}}}
218
+ end
219
+ export 'erreq'
220
+ def tmpnam dir = Dir.tmpdir, seed = File::basename($0)
221
+ #{{{
222
+ pid = Process.pid
223
+ path = "%s_%s_%s_%s_%d" %
224
+ [Util::hostname, seed, pid, Util::timestamp.gsub(/\s+/o,'_'), rand(101010)]
225
+ File::join(dir, path)
226
+ #}}}
227
+ end
228
+ export 'tmpnam'
229
+ def uncache file
230
+ #{{{
231
+ refresh = nil
232
+ begin
233
+ is_a_file = File === file
234
+ path = (is_a_file ? file.path : file.to_s)
235
+ stat = (is_a_file ? file.stat : File::stat(file.to_s))
236
+ refresh = tmpnam(File::dirname(path))
237
+ File::link path, refresh rescue File::symlink path, refresh
238
+ File::chmod stat.mode, path
239
+ File::utime stat.atime, stat.mtime, path
240
+ ensure
241
+ begin
242
+ File::unlink refresh if refresh
243
+ rescue Errno::ENOENT
244
+ end
245
+ end
246
+ #}}}
247
+ end
248
+ export 'uncache'
249
+ def columnize buf, width = 80, indent = 0
250
+ #{{{
251
+ column = []
252
+ words = buf.split %r/\s+/o
253
+ row = ' ' * indent
254
+ while((word = words.shift))
255
+ if((row.size + word.size) < (width - 1))
256
+ row << word
257
+ else
258
+ column << row
259
+ row = ' ' * indent
260
+ row << word
261
+ end
262
+ row << ' ' unless row.size == (width - 1)
263
+ end
264
+ column << row unless row.strip.empty?
265
+ column.join "\n"
266
+ #}}}
267
+ end
268
+ export 'columnize'
269
+ def defval var, default = nil
270
+ #{{{
271
+ v = "#{ var }"
272
+ c = "DEFAULT_#{ v }".upcase
273
+ begin
274
+ klass.send(v) || klass.const_get(c)
275
+ rescue NameError
276
+ default
277
+ end
278
+ #}}}
279
+ end
280
+ export 'defval'
281
+ #}}}
282
+ end # module Util
283
+ #}}}
284
+ end # module RQ
285
+ $__rq_util__ = __FILE__
286
+ end
@@ -0,0 +1,84 @@
1
+ unless defined? $__rq__
2
+ module RQ
3
+ #{{{
4
+ AUTHOR = 'ara.t.howard@noaa.gov'
5
+ LIBNAME = 'rq'
6
+ VERSION = '0.1.7'
7
+ LIBVER = "#{ LIBNAME }-#{ VERSION }"
8
+ DIRNAME = File::dirname(File::expand_path(__FILE__)) + File::SEPARATOR
9
+ ROOTDIR = File::dirname(DIRNAME)
10
+ LIBDIR = File::join(DIRNAME, LIBVER) + File::SEPARATOR
11
+ EXIT_SUCCESS = 0
12
+ EXIT_FAILURE = 1
13
+ #
14
+ # builtin
15
+ #
16
+ require 'optparse'
17
+ require 'logger'
18
+ require 'socket'
19
+ require 'rbconfig'
20
+ require 'optparse'
21
+ require 'logger'
22
+ require 'yaml'
23
+ require 'pp'
24
+ require 'socket'
25
+ require 'pathname'
26
+ require 'tempfile'
27
+ require 'fileutils'
28
+ require 'tmpdir'
29
+ require 'drb/drb'
30
+ #
31
+ # depends - http://raa.ruby-lang.org
32
+ #
33
+ begin
34
+ require 'arrayfields'
35
+ rescue LoadError
36
+ abort "require arrayfields - http://raa.ruby-lang.org/project/arrayfields/"
37
+ end
38
+ begin
39
+ require 'sqlite'
40
+ rescue LoadError
41
+ abort "require sqlite - http://raa.ruby-lang.org/project/sqlite-ruby/"
42
+ end
43
+ begin
44
+ require 'posixlock'
45
+ rescue LoadError
46
+ abort "require posixlock - http://raa.ruby-lang.org/project/posixlock/"
47
+ end
48
+ begin
49
+ require 'lockfile'
50
+ rescue LoadError
51
+ abort "require lockfile - http://raa.ruby-lang.org/project/lockfile/"
52
+ end
53
+ #
54
+ # rq support libs
55
+ #
56
+ require LIBDIR + 'util'
57
+ require LIBDIR + 'logging'
58
+ require LIBDIR + 'configfile'
59
+ require LIBDIR + 'sleepcycle'
60
+ require LIBDIR + 'refresher'
61
+ require LIBDIR + 'qdb'
62
+ require LIBDIR + 'jobqueue'
63
+ require LIBDIR + 'job'
64
+ require LIBDIR + 'jobrunner'
65
+ require LIBDIR + 'jobrunnerdaemon'
66
+ require LIBDIR + 'usage'
67
+ require LIBDIR + 'mainhelper'
68
+ require LIBDIR + 'creator'
69
+ require LIBDIR + 'submitter'
70
+ require LIBDIR + 'lister'
71
+ require LIBDIR + 'statuslister'
72
+ require LIBDIR + 'deleter'
73
+ require LIBDIR + 'updater'
74
+ require LIBDIR + 'querier'
75
+ require LIBDIR + 'executor'
76
+ require LIBDIR + 'configurator'
77
+ require LIBDIR + 'snapshotter'
78
+ require LIBDIR + 'locker'
79
+ require LIBDIR + 'backer'
80
+ require LIBDIR + 'feeder'
81
+ #}}}
82
+ end # module rq
83
+ $__rq__ = __FILE__
84
+ end
@@ -0,0 +1,2 @@
1
+ rdoc -a -d -F -S -m README -I jpg README lib/rq.rb lib/*/* bin/rq
2
+ #INSTALL DESIGN TUTORIAL TODO BUGS DISCLAIMER LISCENSE DEPENDS VERSION
data/rq ADDED
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ RUBYLIB=lib ./bin/rq $@
@@ -0,0 +1,36 @@
1
+ require 'date'
2
+ Gem::Specification.new do |s|
3
+ s.name = %q{rq}
4
+ s.version = "0.1.7"
5
+ s.date = Date.today.to_s
6
+ s.summary = %q{rq is an __experimental__ tool used to manage nfs mounted work queues}
7
+ s.description =<<DESCRIPTION
8
+ rq is an __experimental__ tool used to manage nfs mounted work
9
+ queues. multiple instances of rq running from multiples hosts can
10
+ work from these queues to distribute processing load to 'n' nodes - bringing
11
+ many dozens of otherwise powerful cpus to their knees with a single blow.
12
+ clearly this software should be kept out of the hands of radicals, SETI
13
+ enthusiasts, and one mr. jeff safran.
14
+
15
+ rq operates in one of the modes create, submit, feed, list,
16
+ delete, query, snapshot, or help. depending on the mode of operation and
17
+ the options used the meaning of mode_args may change, sometime wildly and
18
+ unpredictably (i jest, of course).
19
+ DESCRIPTION
20
+ s.author = %q{-a}
21
+ s.email = %q{ara.t.howard@noaa.gov}
22
+ s.homepage = %q{http://www.codeforpeople.com/lib/ruby/rq/}
23
+ s.files = Dir.glob('**/*')
24
+ s.require_path = %q{lib}
25
+ s.autorequire = %q{rq}
26
+ s.has_rdoc = true
27
+ s.rdoc_options = ["--main", "README"]
28
+ s.extra_rdoc_files = ["README"]
29
+ s.executables = %w{rq}
30
+ s.bindir = %q{bin}
31
+ s.platform = Gem::Platform::RUBY
32
+ s.add_dependency('arrayfields', '>= 0.0.0')
33
+ s.add_dependency('sqlite-ruby', '>= 0.0.0')
34
+ s.add_dependency('lockfile', '>= 0.0.0')
35
+ s.add_dependency('posixlock', '>= 0.0.0')
36
+ end
data/rq.help ADDED
@@ -0,0 +1,552 @@
1
+ NAME
2
+ rq v0.1.7
3
+
4
+ SYNOPSIS
5
+ rq (queue | export RQ_Q=q) mode [mode_args]* [options]*
6
+
7
+
8
+ DESCRIPTION
9
+ rq is an tool used to create instant linux clusters by managing nfs
10
+ mounted priority work queues. multiple instances of rq running from
11
+ multiples hosts can work from these queues to distribute processing load to n
12
+ nodes - bringing many dozens of otherwise powerful cpus to their knees with a
13
+ single blow. clearly this software should be kept out of the hands of free
14
+ radicals, seti enthusiasts, and one mr. j. safran.
15
+
16
+ the central concept of rq is that n nodes work in isolation to pull
17
+ jobs from an central nfs mounted work priority work queue in a synchronized
18
+ fashion. the nodes have absolutely no knowledge of each other and all
19
+ communication if done via the queue meaning that, so long as the queue is
20
+ available via nfs and a single node is running jobs from it, the system will
21
+ continue to process jobs. there is no centralized process whatsoever - all
22
+ nodes work to take jobs from the queue and run them as fast as possible. this
23
+ creates a system which load balances automatically and is robust in face of
24
+ node failures.
25
+
26
+ the first argument to any rq command is the name of the queue. this
27
+ name may be omitted if, and only if, the environment variable RQ_Q has been
28
+ set to contain the absolute path of target queue.
29
+
30
+ rq operates in one of the modes create, submit, list, status,
31
+ delete, update, query, execute, configure, snapshot, lock, backup, help, or
32
+ feed. depending on the mode of operation and the options used the meaning of
33
+ 'mode_args' may change.
34
+
35
+ MODES
36
+
37
+ the following mode abbreviations exist
38
+
39
+ c => create
40
+ s => submit
41
+ l => list
42
+ ls => list
43
+ t => status
44
+ d => delete
45
+ rm => delete
46
+ u => update
47
+ q => query
48
+ e => execute
49
+ C => configure
50
+ S => snapshot
51
+ L => lock
52
+ b => backup
53
+ h => help
54
+ f => feed
55
+
56
+ create, c :
57
+
58
+ create a queue. the queue must be located on an nfs mounted file system
59
+ visible from all nodes intended to run jobs from it.
60
+
61
+ examples :
62
+
63
+ 0) to create a queue
64
+ ~ > rq /path/to/nfs/mounted/q create
65
+ or simply
66
+ ~ > rq /path/to/nfs/mounted/q c
67
+
68
+
69
+ submit, s :
70
+
71
+ submit jobs to a queue to be proccesed by a feeding node. any 'mode_args'
72
+ are taken as the command to run. note that 'mode_args' are subject to shell
73
+ expansion - if you don't understand what this means do not use this feature
74
+ and pass jobs on stdin.
75
+
76
+ when running in submit mode a file may by specified as a list of commands to
77
+ run using the '--infile, -i' option. this file is taken to be a newline
78
+ separated list of commands to submit, blank lines and comments (#) are
79
+ allowed. if submitting a large number of jobs the input file method is
80
+ MUCH, more efficient. if no commands are specified on the command line rq
81
+ automatically reads them from STDIN. yaml formatted files are also allowed
82
+ as input (http://www.yaml.org/) - note that the output of nearly all rq
83
+ commands is valid yaml and may, therefore, be piped as input into the submit
84
+ command.
85
+
86
+ when submitting the '--priority, -p' option can be used here to determine
87
+ the priority of jobs. priorities may be any whole number - zero is the
88
+ default. note that submission of a high priority job will NOT supplant
89
+ currently running low priority jobs, but higher priority jobs WILL always
90
+ migrate above lower priority jobs in the queue in order that they be run as
91
+ soon as possible. constant submission of high priority jobs may create a
92
+ starvation situation whereby low priority jobs are never allowed to run.
93
+ avoiding this situation is the responsibility of the user. the only
94
+ guaruntee rq makes regarding job execution is that jobs are
95
+ executed in an 'oldest highest priority' order and that running jobs are
96
+ never supplanted.
97
+
98
+ examples :
99
+
100
+ 0) submit the job ls to run on some feeding host
101
+
102
+ ~ > rq q s ls
103
+
104
+ 1) submit the job ls to run on some feeding host, at priority 9
105
+
106
+ ~ > rq -p9 q s ls
107
+
108
+ 2) submit 42000 jobs (quietly) from a command file.
109
+
110
+ ~ > wc -l cmdfile
111
+ 42000
112
+ ~ > rq q s -q < cmdfile
113
+
114
+ 3) submit 42 priority 9 jobs from a command file.
115
+
116
+ ~ > wc -l cmdfile
117
+ 42
118
+ ~ > rq -p9 q s < cmdfile
119
+
120
+ 4) submit 42 priority 9 jobs from a command file, marking them as
121
+ 'important' using the '--tag, -t' option.
122
+
123
+ ~ > wc -l cmdfile
124
+ 42
125
+ ~ > rq -p9 -timportant q s < cmdfile
126
+
127
+ 5) re-submit all the 'important' jobs (see 'query' section below)
128
+
129
+ ~ > rq q query tag=important | rq q s
130
+
131
+ 6) re-submit all jobs which are already finished (see 'list' section
132
+ below)
133
+
134
+ ~ > rq q l f | rq q s
135
+
136
+
137
+ list, l, ls :
138
+
139
+ list mode lists jobs of a certain state or job id. state may be one of
140
+ pending, running, finished, dead, or all. any 'mode_args' that are numbers
141
+ are taken to be job id's to list.
142
+
143
+ states may be abbreviated to uniqueness, therefore the following shortcuts
144
+ apply :
145
+
146
+ p => pending
147
+ r => running
148
+ f => finished
149
+ d => dead
150
+ a => all
151
+
152
+ examples :
153
+
154
+ 0) show everything in q
155
+ ~ > rq q list all
156
+ or
157
+ ~ > rq q l all
158
+ or
159
+ ~ > export RQ_Q=q
160
+ ~ > rq l
161
+
162
+ 1) show q's pending jobs
163
+ ~ > rq q list pending
164
+
165
+ 2) show q's running jobs
166
+ ~ > rq q list running
167
+
168
+ 3) show q's finished jobs
169
+ ~ > rq q list finshed
170
+
171
+ 4) show job id 42
172
+ ~ > rq q l 42
173
+
174
+
175
+ status, t :
176
+
177
+ status mode shows the global state the queue. there are no 'mode_args'.
178
+ the meaning of each state is as follows:
179
+
180
+ pending => no feeder has yet taken this job
181
+ running => a feeder has taken this job
182
+ finished => a feeder has finished this job
183
+ dead => rq died while running a job, has restarted, and moved
184
+ this job to the dead state
185
+
186
+ note that rq cannot move jobs into the dead state unless it has
187
+ been restarted. this is because no node has any knowledge of other nodes
188
+ and cannot possibly know if a job was started on a node that died, or is
189
+ simply taking a very long time. only the node that dies, upon restart, can
190
+ determine that is has jobs that 'were started before it started' and move
191
+ these jobs into the dead state. normally only a machine crash would cause a
192
+ job to be placed into the dead state. dead jobs are never automatically
193
+ restarted, this is the responsibility of an operator.
194
+
195
+ examples :
196
+
197
+ 0) show q's status
198
+
199
+ ~ > rq q t
200
+
201
+
202
+ delete, d :
203
+
204
+ delete combinations of pending, running, finished, dead, or jobs specified
205
+ by jid. the delete mode is capable of parsing the output of list and query
206
+ modes, making it possible to create custom filters to delete jobs meeting
207
+ very specific conditions.
208
+
209
+ 'mode_args' are the same as for list. note that while it is possible to
210
+ delete a running job, but there is no way to actually STOP it mid execution
211
+ since the node doing the deleteing has no way to communicate this
212
+ information to the (probably) remote execution node. therefore you should
213
+ use the 'delete running' feature with care and only for housekeeping
214
+ purposes or to prevent future jobs from being scheduled.
215
+
216
+ examples :
217
+
218
+ 0) delete all pending, running, and finished jobs from a queue
219
+
220
+ ~ > rq q d all
221
+
222
+ 1) delete all pending jobs from a queue
223
+
224
+ ~ > rq q d p
225
+
226
+ 2) delete all finished jobs from a queue
227
+
228
+ ~ > rq q d f
229
+
230
+ 3) delete jobs via hand crafted filter program
231
+
232
+ ~ > rq q list | yaml_filter_prog | rq q d
233
+
234
+
235
+ update, u :
236
+
237
+ update assumes all leading arguments are jids to update with subsequent
238
+ key=value pairs. currently only the 'command', 'priority', and 'tag' fields
239
+ of pending jobs can be updated.
240
+
241
+ examples:
242
+
243
+ 0) update the priority of job 42
244
+
245
+ ~ > rq q update 42 priority=7
246
+
247
+ 1) update the priority of all pending jobs
248
+
249
+ ~ > rq q update pending priority=7
250
+
251
+ 2) query jobs with a command matching 'foobar' and update their command
252
+ to be 'barfoo'
253
+
254
+ ~ > rq q q "command like '%foobar%'" |\
255
+ rq q u command=barfoo
256
+
257
+
258
+ query, q :
259
+
260
+ query exposes the database more directly the user, evaluating the where
261
+ clause specified on the command line (or from STDIN). this feature can be
262
+ used to make a fine grained slection of jobs for reporting or as input into
263
+ the delete command. you must have a basic understanding of SQL syntax to
264
+ use this feature, but it is fairly intuitive in this limited capacity.
265
+
266
+ examples:
267
+
268
+ 0) show all jobs submitted within a specific 10 minute range
269
+
270
+ ~ > rq q query "started >= '2004-06-29 22:51:00' and started < '2004-06-29 22:51:10'"
271
+
272
+ 1) shell quoting can be tricky here so input on STDIN is also allowed to
273
+ avoid shell expansion
274
+
275
+ ~ > cat constraints.txt
276
+ started >= '2004-06-29 22:51:00' and
277
+ started < '2004-06-29 22:51:10'
278
+
279
+ ~ > rq q query < contraints.txt
280
+ or (same thing)
281
+
282
+ ~ > cat contraints.txt| rq q query
283
+
284
+ ** in general all but numbers will need to be surrounded by single quotes **
285
+
286
+ 2) this query output might then be used to delete those jobs
287
+
288
+ ~ > cat contraints.txt | rq q q | rq q d
289
+
290
+ 3) show all jobs which are either finished or dead
291
+
292
+ ~ > rq q q "state='finished' or state='dead'"
293
+
294
+ 4) show all jobs which have non-zero exit status
295
+
296
+ ~ > rq q query exit_status!=0
297
+
298
+ 5) if you plan to query groups of jobs with some common feature consider
299
+ using the '--tag, -t' feature of the submit mode which allows a user to
300
+ tag a job with a user defined string which can then be used to easily
301
+ query that job group
302
+
303
+ ~ > rq q submit --tag=my_jobs < joblist
304
+ ~ > rq q query tag=my_jobs
305
+
306
+
307
+ execute, e :
308
+
309
+ execute mode is to be used by expert users with a knowledge of sql syntax
310
+ only. it follows the locking protocol used by rq and then allows
311
+ the user to execute arbitrary sql on the queue. unlike query mode a write
312
+ lock on the queue is obtained allowing a user to definitively shoot
313
+ themselves in the foot. for details on a queue's schema the file
314
+ 'db.schema' in the queue directory should be examined.
315
+
316
+ examples :
317
+
318
+ 0) list all jobs
319
+
320
+ ~ > rq q execute 'select * from jobs'
321
+
322
+
323
+ configure, C :
324
+
325
+ this mode is not supported yet.
326
+
327
+
328
+ snapshot, p :
329
+
330
+ snapshot provides a means of taking a snapshot of the q. use this feature
331
+ when many queries are going to be run; for example when attempting to figure
332
+ out a complex pipeline command your test queries will not compete with the
333
+ feeders for the queue's lock. you should use this option whenever possible
334
+ to avoid lock competition.
335
+
336
+ examples:
337
+
338
+ 0) take a snapshot using default snapshot naming, which is made via the
339
+ basename of the q plus '.snapshot'
340
+
341
+ ~ > rq /path/to/nfs/q snapshot
342
+
343
+ 1) use this snapshot to chceck status
344
+
345
+ ~ > rq ./q.snapshot status
346
+
347
+ 2) use the snapshot to see what's running on which host
348
+
349
+ ~ > rq ./q.snapshot list running | grep `hostname`
350
+
351
+ note that there is also a snapshot option - this option is not the same as
352
+ the snapshot command. the option can be applied to ANY command. if in
353
+ effect then that command will be run on a snapshot of the database and the
354
+ snapshot then immediately deleted. this is really only useful if one were
355
+ to need to run a command against a very heavily loaded queue and did not
356
+ wish to wait to obtain the lock. eg.
357
+
358
+ 0) get the status of a heavily loaded queue
359
+
360
+ ~ > rq q t --snapshot
361
+
362
+ 1) same as above
363
+
364
+ ~ > rq q t -s
365
+
366
+
367
+ lock, L :
368
+
369
+ lock the queue and then execute an arbitrary shell command. lock mode uses
370
+ the queue's locking protocol to safely obtain a lock of the specified type
371
+ and execute a command on the user's behalf. lock type must be one of
372
+
373
+ (r)ead | (sh)ared | (w)rite | (ex)clusive
374
+
375
+ examples :
376
+
377
+ 0) get a read lock on the queue and make a backup
378
+
379
+ ~ > rq q L read -- cp -r q q.bak
380
+
381
+ (the '--' is needed to tell rq to stop parsing command line
382
+ options which allows the '-r' to be passed to the 'cp' command)
383
+
384
+
385
+ backup, b :
386
+
387
+ backup mode is exactly the same as getting a read lock on the queue and
388
+ making a copy of it. this mode is provided as a convenience.
389
+
390
+ 0) make a backup of the queue using default naming ( qname + timestamp + .bak )
391
+
392
+ ~ > rq q b
393
+
394
+ 1) make a backup of the queue as 'q.bak'
395
+
396
+ ~ > rq q b q.bak
397
+
398
+ help, h :
399
+
400
+ this message
401
+
402
+ examples :
403
+
404
+ 0) get this message
405
+
406
+ ~> rq q help
407
+ or
408
+ ~> rq help
409
+
410
+
411
+ feed, f :
412
+
413
+ take jobs from the queue and run them on behalf of the submitter as quickly
414
+ as possible. jobs are taken from the queue in an 'oldest highest priority'
415
+ first order.
416
+
417
+ feeders can be run from any number of nodes allowing you to harness the CPU
418
+ power of many nodes simoultaneously in order to more effectively clobber
419
+ your network, anoy your sysads, and set output raids on fire.
420
+
421
+ the most useful method of feeding from a queue is to do so in daemon mode so
422
+ that if the process loses it's controling terminal it will not exit when you
423
+ exit your terminal session. use the '--daemon, -d' option to accomplish
424
+ this. by default only one feeding process per host per queue is allowed to
425
+ run at any given moment. because of this it is acceptable to start a feeder
426
+ at some regular interval from a cron entry since, if a feeder is alreay
427
+ running, the process will simply exit and otherwise a new feeder will be
428
+ started. in this way you may keep feeder processing running even acroess
429
+ machine reboots without requiring sysad intervention to add an entry to the
430
+ machine's startup tasks.
431
+
432
+
433
+ examples :
434
+
435
+ 0) feed from a queue verbosely for debugging purposes, using a minimum and
436
+ maximum polling time of 2 and 4 respectively. you would NEVER specify
437
+ polling times this brief except for debugging purposes!!!
438
+
439
+ ~ > rq q feed -v4 -m2 -M4
440
+
441
+ 1) same as above, but viewing the executed sql as it is sent to the
442
+ database
443
+
444
+ ~ > RQ_SQL_DEBUG=1 rq q f -v4 -m2 -M4
445
+
446
+ 2) feed from a queue in daemon mode - logging to /home/ahoward/rq.log
447
+
448
+ ~ > rq q f -d -l/home/ahoward/rq.log
449
+
450
+ log rolling in daemon mode is automatic so your logs should never need
451
+ to be deleted to prevent disk overflow.
452
+
453
+ 3) use something like this sample crontab entry to keep a feeder running
454
+ forever - it attempts to (re)start every fifteen minutes but exits if
455
+ another process is already feeding.
456
+
457
+ #
458
+ # your crontab file - sample only
459
+ #
460
+
461
+ */15 * * * * /full/path/to/bin/rq /full/path/to/nfs/mounted/q f -d -l/home/username/cfq.log -q
462
+
463
+ the '--quiet, -q' here tells rq to exit quietly (no STDERR)
464
+ when another process is found to already be feeding so that no cron
465
+ message would be sent under these conditions.
466
+
467
+
468
+ NOTES
469
+ - realize that your job is going to be running on a remote host and this has
470
+ implications. paths, for example, should be absolute, not relative.
471
+ specifically the submitted job script must be visible from all hosts
472
+ currently feeding from a queue as must be the input and output
473
+ files/directories.
474
+
475
+ - jobs are currently run under the bash shell using the --login option.
476
+ therefore any settings in your .bashrc will apply - specifically your PATH
477
+ setting. you should not, however, rely on jobs running with any given
478
+ environment.
479
+
480
+ - you need to consider __CAREFULLY__ what the ramifications of having multiple
481
+ instances of your program all potentially running at the same time will be.
482
+ for instance, it is beyond the scope of rq to ensure multiple
483
+ instances of a given program will not overwrite each others output files.
484
+ coordination of programs is left entirely to the user.
485
+
486
+ - the list of finished jobs will grow without bound unless you sometimes
487
+ delete some (all) of them. the reason for this is that rq cannot
488
+ know when the user has collected the exit_status of a given job, and so
489
+ keeps this information in the queue forever until instructed to delete it.
490
+ if you have collected the exit_status of you job(s) it is not an error to
491
+ then delete that job from the finished list - the information is kept for
492
+ your informational purposes only. in a production system it would be normal
493
+ to periodically save, and then delete, all finished jobs.
494
+
495
+ ENVIRONMENT
496
+ RQ_Q: set to the full path of nfs mounted queue
497
+
498
+ the queue argument to all commands may be omitted if, and only if, the
499
+ environment variable 'RQ_Q' contains the full path to the q. eg.
500
+
501
+ ~ > export RQ_Q=/full/path/to/my/q
502
+
503
+ this feature can save a considerable amount of typing for those weak of
504
+ wrist.
505
+
506
+ DIAGNOSTICS
507
+ success : $? == 0
508
+ failure : $? != 0
509
+
510
+ AUTHOR
511
+ ara.t.howard@noaa.gov
512
+
513
+ BUGS
514
+ 0 < bugno && bugno <= 42
515
+
516
+ reports to ara.t.howard@noaa.gov
517
+
518
+ OPTIONS
519
+ --priority=priority, -p
520
+ modes <submit> : set the job(s) priority - lowest(0) .. highest(n) -
521
+ (default 0)
522
+ --tag=tag, -t
523
+ modes <submit> : set the job(s) user data tag
524
+ --infile=infile, -i
525
+ modes <submit> : infile
526
+ --quiet, -q
527
+ modes <submit, feed> : do not echo submitted jobs, fail silently if
528
+ another process is already feeding
529
+ --daemon, -d
530
+ modes <feed> : spawn a daemon
531
+ --max_feed=max_feed, -f
532
+ modes <feed> : the maximum number of concurrent jobs run
533
+ --retries=retries, -r
534
+ modes <feed> : specify transaction retries
535
+ --min_sleep=min_sleep, -m
536
+ modes <feed> : specify min sleep
537
+ --max_sleep=max_sleep, -M
538
+ modes <feed> : specify max sleep
539
+ --snapshot, -s
540
+ operate on snapshot of queue
541
+ --verbosity=verbostiy, -v
542
+ 0|fatal < 1|error < 2|warn < 3|info < 4|debug - (default info)
543
+ --log=path, -l
544
+ set log file - (default stderr)
545
+ --log_age=log_age
546
+ daily | weekly | monthly - what age will cause log rolling (default
547
+ nil)
548
+ --log_size=log_size
549
+ size in bytes - what size will cause log rolling (default nil)
550
+ --help, -h
551
+ this message
552
+