rask 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rask.rb CHANGED
@@ -7,60 +7,114 @@ require 'thread'
7
7
 
8
8
  require File.dirname(__FILE__) + '/rask/state_machine'
9
9
 
10
- #Authors:: mewlist / Hidenori Doi
11
- #Copyright:: Copyright (C) 2010 mewlist / Hidenori Doi
12
- #License:: The MIT License
10
+ # Authors:: mewlist / Hidenori Doi
11
+ # Copyright:: Copyright (C) 2010 mewlist / Hidenori Doi
12
+ # License:: The MIT License
13
+ #
14
+ # == Rask is terminatable task engine
15
+ # ==== sample code
16
+ # require 'rubygems'
17
+ # require 'rask'
13
18
  #
14
- #== Rask is terminatable task engine
19
+ # # task of count up to 10
20
+ # class CountupTask < Rask::Task
21
+ # # define statemachine states
22
+ # define_state :start, :initial => true # initial state
23
+ # define_state :running # run
24
+ # define_state :finish, :from => [:running] # finish (only from :running)
25
+ #
26
+ # def start # same name as state definition(define_state)
27
+ # @count = 0
28
+ # p "start"
29
+ # transition_to_running # transition to :running
30
+ # end
31
+ #
32
+ # def running
33
+ # p "running count => #{@count+=1}"
34
+ # transition_to_finish if @count>=10 # transition to :finish
35
+ # end
36
+ #
37
+ # def finish
38
+ # p "finished"
39
+ # destroy # destroy task myself
40
+ # end
41
+ # end
42
+ #
43
+ # Rask.insert CountupTask.new # insert the task
44
+ #
45
+ # Rask.daemon # run as a daemon
15
46
  #
16
47
  module Rask
17
48
 
49
+ # Authors:: mewlist / Hidenori Doi
50
+ # Copyright:: Copyright (C) 2010 mewlist / Hidenori Doi
51
+ # License:: The MIT License
18
52
  #
19
- #===Task base class
20
- #To define new Task you must inherit this base-class
21
- #* sample code
22
- # class NewTask < Rask::Task
23
- # define_state :initial, :initial => true
24
- # define_state :finish
25
- # def initial
26
- # transition :finish
27
- # end
28
- # def finish
29
- # destroy
30
- # end
31
- # end
53
+ # ==Task base class
54
+ # To define new Task you must inherit this base-class
55
+ # * Transition function is defined automatically, named transition_to_[state]
56
+ # * For this sample, transition_to_finish is defined.
57
+ # ====sample code
58
+ # class NewTask < Rask::Task
59
+ # define_state :initial, :initial => true
60
+ # define_state :finish
61
+ # def initial
62
+ # transition_to_finish
63
+ # end
64
+ # def finish
65
+ # destroy
66
+ # end
67
+ # end
68
+ #
32
69
  class Task
33
70
  include StateMachine
71
+ #
34
72
  attr_accessor :task_id
73
+ #
35
74
  attr_accessor :group
75
+ #
36
76
  attr_reader :state
37
77
 
38
78
  #
39
- #====If group option is given, the task is classified by group name.
79
+ # [_group]
80
+ # group name to classify.
81
+ # You can filter task group when call <b>Rask::task_ids / Rask::daemon</b> methods.
82
+ # === If group option is given, the task is classified by group name.
83
+ # ==== sample code
84
+ # Rask::insert NewTask.new('group_name')
85
+ # Rask::daemon(:group => 'group_name')
40
86
  #
41
- #==== _group
42
- # group name to classify
43
87
  def initialize(_group=nil)
44
88
  self.group = _group
45
89
  super()
46
90
  end
47
91
 
48
92
  #
49
- #====automatically callbacked from task engine.
93
+ # === automatically callbacked from task engine.
50
94
  #
51
95
  def run
96
+ return if read_only?
52
97
  if @state
53
98
  eval @state.to_s
54
99
  end
55
100
  end
56
101
 
57
102
  #
58
- #====Transition to new state. In the state function.
103
+ # === Transition to new state. In the state function.
59
104
  # Usually you should call generated transition_to_[state name] function
60
105
  def transition(to)
61
106
  @state = to
62
107
  end
63
108
 
109
+ #
110
+ def read_only
111
+ @read_only = true
112
+ end
113
+
114
+ #
115
+ def read_only?
116
+ @read_only == true
117
+ end
64
118
 
65
119
  #
66
120
  def destroy
@@ -84,15 +138,16 @@ module Rask
84
138
  @@locker = Mutex::new
85
139
 
86
140
  #
87
- #====Set base storage directory
88
- #default is '/tmp/rask'
141
+ # === Set base storage directory
142
+ # default :: /tmp/rask
89
143
  #
90
144
  def self.base_directory=(new_directory)
91
145
  @@base_dir = new_directory
92
146
  end
93
147
 
94
148
  #
95
- #====Set max count of worker thread
149
+ # === Set max count of worker thread
150
+ # default :: 5
96
151
  #
97
152
  def self.thread_max_count=(count)
98
153
  @@thread_max_count = count
@@ -109,8 +164,10 @@ module Rask
109
164
  end
110
165
 
111
166
  #
112
- #====Insert new task
113
- # Rask::insert NewTask.new
167
+ # === Insert a new task. The task will be controlled under Rask daemon process.
168
+ # ==== sample code
169
+ # Rask::insert NewTask.new
170
+ #
114
171
  def self.insert(task)
115
172
  initialize_storage
116
173
  task_id = "#{safe_class_name(task.class.name)}-#{task.group.to_s}-#{Time.now.to_i}-#{Time.now.usec}"
@@ -128,10 +185,12 @@ module Rask
128
185
  def self.run(task_id)
129
186
  f = File.open(task_path(task_id), 'r+') rescue return
130
187
  f.flock(File::LOCK_EX)
131
-
132
188
  task = Marshal.restore(f)
133
- yield task
134
-
189
+ if block_given?
190
+ yield task
191
+ else
192
+ task.run
193
+ end
135
194
  f.truncate(0)
136
195
  f.pos = 0
137
196
  Marshal.dump(task, f)
@@ -140,6 +199,14 @@ module Rask
140
199
  FileUtils.rm(task_path(task_id)) if task.destroy?
141
200
  end
142
201
 
202
+ #
203
+ def self.run_all(options = { :class=>nil, :group=>nil })
204
+ Rask.task_ids(options).each { |task_id| run(task_id) }
205
+ end
206
+
207
+ #
208
+ # === Get the task instance to observe.
209
+ # You can use the instance for only the purpose of observation.
143
210
  #
144
211
  def self.read(task_id)
145
212
  f = File.open(task_path(task_id), 'r+') rescue return
@@ -147,11 +214,15 @@ module Rask
147
214
  task = Marshal.restore(f)
148
215
  f.flock(File::LOCK_UN)
149
216
  f.close
217
+ task.read_only = true
150
218
  task
151
219
  end
152
220
 
153
221
  #
154
- #====Get all file path of task list
222
+ # === Get task_id list.
223
+ # [options]
224
+ # class :: Only the instance of specified class.
225
+ # group :: Only the instance of specified group. see also Task::initialize
155
226
  #
156
227
  def self.task_ids(options = { :class=>nil, :group=>nil })
157
228
  target = @@base_dir
@@ -173,30 +244,20 @@ module Rask
173
244
  end
174
245
 
175
246
  #
176
- def self.initialize_storage
177
- unless File.exists? @@base_dir
178
- FileUtils.makedirs @@base_dir
179
- end
180
- end
181
-
182
- #
183
- #====force destroy the task
247
+ # === force destroy the task
184
248
  #
185
249
  def self.destroy(task)
186
250
  FileUtils.rm(task_path(task.task_id)) if File.exists? task_path(task.task_id)
187
251
  end
188
252
 
189
253
  #
190
- def self.safe_class_name(c)
191
- c.gsub(/[:]/,'@')
192
- end
193
-
194
- #
195
- #====Start daemon process
196
- #It is possible to specify the the task group.
197
- # Rask.daemon(:group=>'TaskGroup')
254
+ # === Start a daemon process
255
+ # [options]
256
+ # class :: Only the instance of specified class.
257
+ # group :: Only the instance of specified group. see also Task::initialize.
258
+ # sleep :: Polling interval daemon process.
198
259
  #
199
- def self.daemon(options = {})
260
+ def self.daemon(options = {:class=>nil, :group=>nil, :sleep=>0.1})
200
261
  options = { :sleep=>0.1 }.merge(options)
201
262
  print "daemon start\n"
202
263
  exit if fork
@@ -219,7 +280,7 @@ module Rask
219
280
  end
220
281
  if d != nil
221
282
  # print "#{d}\n"
222
- run(d) { |task| task.run }
283
+ run(d)
223
284
  @@locker.synchronize do
224
285
  @@processing.delete(d)
225
286
  end
@@ -249,15 +310,28 @@ module Rask
249
310
  end
250
311
  end
251
312
 
313
+ private
314
+
315
+ #
316
+ def self.initialize_storage
317
+ unless File.exists? @@base_dir
318
+ FileUtils.makedirs @@base_dir
319
+ end
320
+ end
321
+
322
+ #
323
+ def self.safe_class_name(c)
324
+ c.gsub(/[:]/,'@')
325
+ end
326
+
252
327
  #
253
328
  def self.safe_exit
254
- print "daemon terminated"
255
329
  @@terminated = true
256
330
  while @@thread_count > 0
257
331
  sleep(0.1)
258
332
  end
259
333
  FileUtils.rm(pid_path) if File.exist?(pid_path)
260
- print "done \n"
334
+ print "safely daemon terminated. \n"
261
335
  exit
262
336
  end
263
337
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rask
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - mewlist / Hidenori Doi
@@ -53,11 +53,8 @@ files:
53
53
  - doc/images/zoom.png
54
54
  - doc/index.html
55
55
  - doc/Rask.html
56
- - doc/Rask/StateMachine.html
57
- - doc/Rask/StateMachine/ClassMethods.html
58
56
  - doc/Rask/Task.html
59
57
  - doc/lib/rask_rb.html
60
- - doc/lib/rask/state_machine_rb.html
61
58
  - doc/created.rid
62
59
  - README.rdoc
63
60
  - History.txt
@@ -1,379 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
- <head>
6
- <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
7
-
8
- <title>Module: Rask::StateMachine</title>
9
-
10
- <link rel="stylesheet" href="../rdoc.css" type="text/css" media="screen" />
11
-
12
- <script src="../js/jquery.js" type="text/javascript"
13
- charset="utf-8"></script>
14
- <script src="../js/thickbox-compressed.js" type="text/javascript"
15
- charset="utf-8"></script>
16
- <script src="../js/quicksearch.js" type="text/javascript"
17
- charset="utf-8"></script>
18
- <script src="../js/darkfish.js" type="text/javascript"
19
- charset="utf-8"></script>
20
-
21
- </head>
22
- <body class="module">
23
-
24
- <div id="metadata">
25
- <div id="file-metadata">
26
- <div id="file-list-section" class="section">
27
- <h3 class="section-header">In Files</h3>
28
- <div class="section-body">
29
- <ul>
30
-
31
- <li><a href="../lib/rask/state_machine_rb.html?TB_iframe=true&amp;height=550&amp;width=785"
32
- class="thickbox" title="lib/rask/state_machine.rb">lib/rask/state_machine.rb</a></li>
33
-
34
- </ul>
35
- </div>
36
- </div>
37
-
38
-
39
- </div>
40
-
41
- <div id="class-metadata">
42
-
43
- <!-- Parent Class -->
44
-
45
-
46
- <!-- Namespace Contents -->
47
-
48
- <div id="namespace-list-section" class="section">
49
- <h3 class="section-header">Namespace</h3>
50
- <ul class="link-list">
51
-
52
- <li><span class="type">MODULE</span> <a href="StateMachine/ClassMethods.html">Rask::StateMachine::ClassMethods</a></li>
53
-
54
- </ul>
55
- </div>
56
-
57
-
58
- <!-- Method Quickref -->
59
-
60
- <div id="method-list-section" class="section">
61
- <h3 class="section-header">Methods</h3>
62
- <ul class="link-list">
63
-
64
- <li><a href="#M000006">::included</a></li>
65
-
66
- <li><a href="#M000000">::new</a></li>
67
-
68
- <li><a href="#M000004">#destroy</a></li>
69
-
70
- <li><a href="#M000005">#destroy?</a></li>
71
-
72
- <li><a href="#M000001">#initial_state</a></li>
73
-
74
- <li><a href="#M000003">#transition</a></li>
75
-
76
- </ul>
77
- </div>
78
-
79
-
80
- <!-- Included Modules -->
81
-
82
- </div>
83
-
84
- <div id="project-metadata">
85
-
86
-
87
-
88
- <div id="classindex-section" class="section project-section">
89
- <h3 class="section-header">Class Index
90
- <span class="search-toggle"><img src="../images/find.png"
91
- height="16" width="16" alt="[+]"
92
- title="show/hide quicksearch" /></span></h3>
93
- <form action="#" method="get" accept-charset="utf-8" class="initially-hidden">
94
- <fieldset>
95
- <legend>Quicksearch</legend>
96
- <input type="text" name="quicksearch" value=""
97
- class="quicksearch-field" />
98
- </fieldset>
99
- </form>
100
-
101
- <ul class="link-list">
102
-
103
- <li><a href="../Rask.html">Rask</a></li>
104
-
105
- <li><a href="../Rask/StateMachine.html">Rask::StateMachine</a></li>
106
-
107
- <li><a href="../Rask/StateMachine/ClassMethods.html">Rask::StateMachine::ClassMethods</a></li>
108
-
109
- <li><a href="../Rask/Task.html">Rask::Task</a></li>
110
-
111
- </ul>
112
- <div id="no-class-search-results" style="display: none;">No matching classes.</div>
113
- </div>
114
-
115
-
116
- </div>
117
- </div>
118
-
119
- <div id="documentation">
120
- <h1 class="module">Rask::StateMachine</h1>
121
-
122
- <div id="description">
123
-
124
- </div>
125
-
126
- <!-- Constants -->
127
-
128
-
129
- <!-- Attributes -->
130
-
131
- <div id="attribute-method-details" class="method-section section">
132
- <h3 class="section-header">Attributes</h3>
133
-
134
-
135
- <div id="state-attribute-method" class="method-detail">
136
- <a name="state"></a>
137
-
138
- <a name="state="></a>
139
-
140
- <div class="method-heading attribute-method-heading">
141
- <span class="method-name">state</span><span
142
- class="attribute-access-type">[RW]</span>
143
- </div>
144
-
145
- <div class="method-description">
146
-
147
- <p class="missing-docs">(Not documented)</p>
148
-
149
- </div>
150
- </div>
151
-
152
- </div>
153
-
154
-
155
- <!-- Methods -->
156
-
157
- <div id="public-class-method-details" class="method-section section">
158
- <h3 class="section-header">Public Class Methods</h3>
159
-
160
-
161
- <div id="included-method" class="method-detail ">
162
- <a name="M000006"></a>
163
-
164
- <div class="method-heading">
165
-
166
- <span class="method-name">included</span><span
167
- class="method-args">(base)</span>
168
- <span class="method-click-advice">click to toggle source</span>
169
-
170
- </div>
171
-
172
- <div class="method-description">
173
-
174
- <p class="missing-docs">(Not documented)</p>
175
-
176
-
177
-
178
- <div class="method-source-code"
179
- id="included-source">
180
- <pre>
181
- <span class="ruby-comment cmt"># File lib/rask/state_machine.rb, line 47</span>
182
- 47: <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">included</span>(<span class="ruby-identifier">base</span>)
183
- 48: <span class="ruby-identifier">base</span>.<span class="ruby-identifier">extend</span>(<span class="ruby-constant">ClassMethods</span>)
184
- 49: <span class="ruby-keyword kw">end</span></pre>
185
- </div>
186
-
187
- </div>
188
-
189
-
190
- </div>
191
-
192
-
193
- <div id="new-method" class="method-detail ">
194
- <a name="M000000"></a>
195
-
196
- <div class="method-heading">
197
-
198
- <span class="method-name">new</span><span
199
- class="method-args">()</span>
200
- <span class="method-click-advice">click to toggle source</span>
201
-
202
- </div>
203
-
204
- <div class="method-description">
205
-
206
- <p class="missing-docs">(Not documented)</p>
207
-
208
-
209
-
210
- <div class="method-source-code"
211
- id="new-source">
212
- <pre>
213
- <span class="ruby-comment cmt"># File lib/rask/state_machine.rb, line 16</span>
214
- 16: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>
215
- 17: <span class="ruby-ivar">@state</span> = <span class="ruby-identifier">initial_state</span>
216
- 18: <span class="ruby-keyword kw">end</span></pre>
217
- </div>
218
-
219
- </div>
220
-
221
-
222
- </div>
223
-
224
-
225
- </div>
226
-
227
- <div id="public-instance-method-details" class="method-section section">
228
- <h3 class="section-header">Public Instance Methods</h3>
229
-
230
-
231
- <div id="destroy-method" class="method-detail ">
232
- <a name="M000004"></a>
233
-
234
- <div class="method-heading">
235
-
236
- <span class="method-name">destroy</span><span
237
- class="method-args">()</span>
238
- <span class="method-click-advice">click to toggle source</span>
239
-
240
- </div>
241
-
242
- <div class="method-description">
243
-
244
- <p class="missing-docs">(Not documented)</p>
245
-
246
-
247
-
248
- <div class="method-source-code"
249
- id="destroy-source">
250
- <pre>
251
- <span class="ruby-comment cmt"># File lib/rask/state_machine.rb, line 31</span>
252
- 31: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">destroy</span>
253
- 32: <span class="ruby-identifier">transition</span> <span class="ruby-keyword kw">nil</span>
254
- 33: <span class="ruby-keyword kw">end</span></pre>
255
- </div>
256
-
257
- </div>
258
-
259
-
260
- </div>
261
-
262
-
263
- <div id="destroy--method" class="method-detail ">
264
- <a name="M000005"></a>
265
-
266
- <div class="method-heading">
267
-
268
- <span class="method-name">destroy?</span><span
269
- class="method-args">()</span>
270
- <span class="method-click-advice">click to toggle source</span>
271
-
272
- </div>
273
-
274
- <div class="method-description">
275
-
276
- <p class="missing-docs">(Not documented)</p>
277
-
278
-
279
-
280
- <div class="method-source-code"
281
- id="destroy--source">
282
- <pre>
283
- <span class="ruby-comment cmt"># File lib/rask/state_machine.rb, line 36</span>
284
- 36: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">destroy?</span>
285
- 37: <span class="ruby-ivar">@state</span> <span class="ruby-operator">==</span> <span class="ruby-keyword kw">nil</span>
286
- 38: <span class="ruby-keyword kw">end</span></pre>
287
- </div>
288
-
289
- </div>
290
-
291
-
292
- </div>
293
-
294
-
295
- <div id="initial-state-method" class="method-detail ">
296
- <a name="M000001"></a>
297
-
298
- <div class="method-heading">
299
-
300
- <span class="method-name">initial_state</span><span
301
- class="method-args">()</span>
302
- <span class="method-click-advice">click to toggle source</span>
303
-
304
- </div>
305
-
306
- <div class="method-description">
307
-
308
- <p class="missing-docs">(Not documented)</p>
309
-
310
-
311
-
312
- <div class="method-source-code"
313
- id="initial-state-source">
314
- <pre>
315
- <span class="ruby-comment cmt"># File lib/rask/state_machine.rb, line 21</span>
316
- 21: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initial_state</span>
317
- 22: <span class="ruby-keyword kw">nil</span>
318
- 23: <span class="ruby-keyword kw">end</span></pre>
319
- </div>
320
-
321
- </div>
322
-
323
-
324
- </div>
325
-
326
-
327
- <div id="transition-method" class="method-detail ">
328
- <a name="M000003"></a>
329
-
330
- <div class="method-heading">
331
-
332
- <span class="method-name">transition</span><span
333
- class="method-args">(to)</span>
334
- <span class="method-click-advice">click to toggle source</span>
335
-
336
- </div>
337
-
338
- <div class="method-description">
339
-
340
- <p class="missing-docs">(Not documented)</p>
341
-
342
-
343
-
344
- <div class="method-source-code"
345
- id="transition-source">
346
- <pre>
347
- <span class="ruby-comment cmt"># File lib/rask/state_machine.rb, line 26</span>
348
- 26: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">transition</span>(<span class="ruby-identifier">to</span>)
349
- 27: <span class="ruby-ivar">@state</span> = <span class="ruby-identifier">to</span>
350
- 28: <span class="ruby-keyword kw">end</span></pre>
351
- </div>
352
-
353
- </div>
354
-
355
-
356
- </div>
357
-
358
-
359
- </div>
360
-
361
-
362
- </div>
363
-
364
-
365
- <div id="rdoc-debugging-section-dump" class="debugging-section">
366
-
367
- <p>Disabled; run with --debug to generate this.</p>
368
-
369
- </div>
370
-
371
- <div id="validator-badges">
372
- <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
373
- <p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
374
- Rdoc Generator</a> 1.1.6</small>.</p>
375
- </div>
376
-
377
- </body>
378
- </html>
379
-