backgroundrb-rails3 1.1
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.
- data/.autotest +17 -0
- data/ChangeLog +50 -0
- data/Gemfile +11 -0
- data/LICENSE +4 -0
- data/MIT-LICENSE +20 -0
- data/README +22 -0
- data/Rakefile +128 -0
- data/TODO.org +5 -0
- data/app/controller/backgroundrb_status_controller.rb +6 -0
- data/backgroundrb-rails3.gemspec +219 -0
- data/config/backgroundrb.yml +11 -0
- data/doc/Rakefile +5 -0
- data/doc/config.yaml +2 -0
- data/doc/content/advanced/advanced.txt +76 -0
- data/doc/content/advanced/advanced.yaml +4 -0
- data/doc/content/bugs/bugs.txt +20 -0
- data/doc/content/bugs/bugs.yaml +5 -0
- data/doc/content/community/community.txt +36 -0
- data/doc/content/community/community.yaml +5 -0
- data/doc/content/content.txt +168 -0
- data/doc/content/content.yaml +5 -0
- data/doc/content/faq/faq.txt +41 -0
- data/doc/content/faq/faq.yaml +5 -0
- data/doc/content/rails/rails.txt +182 -0
- data/doc/content/rails/rails.yaml +5 -0
- data/doc/content/scheduling/scheduling.txt +166 -0
- data/doc/content/scheduling/scheduling.yaml +5 -0
- data/doc/content/workers/workers.txt +178 -0
- data/doc/content/workers/workers.yaml +5 -0
- data/doc/layouts/default/default.erb +56 -0
- data/doc/layouts/default/default.yaml +4 -0
- data/doc/lib/default.rb +7 -0
- data/doc/output/Assets/BG-Ad-Top.png +0 -0
- data/doc/output/Assets/BG-Body.png +0 -0
- data/doc/output/Assets/BG-Feed.png +0 -0
- data/doc/output/Assets/BG-Menu-Hover.png +0 -0
- data/doc/output/Assets/BG-Menu.png +0 -0
- data/doc/output/Assets/BG-Sidebar-Bottom.png +0 -0
- data/doc/output/Assets/Button-Feed.png +0 -0
- data/doc/output/images/bg-ad-top.png +0 -0
- data/doc/output/images/bg-body.png +0 -0
- data/doc/output/images/bg-feed.gif +0 -0
- data/doc/output/images/bg-footer.jpg +0 -0
- data/doc/output/images/bg-header.jpg +0 -0
- data/doc/output/images/bg-menu-hover.png +0 -0
- data/doc/output/images/bg-menu.png +0 -0
- data/doc/output/images/bg-sidebar-bottom.gif +0 -0
- data/doc/output/images/button-feed.png +0 -0
- data/doc/output/images/icon-comment.png +0 -0
- data/doc/output/images/more_icon.gif +0 -0
- data/doc/output/style.css +299 -0
- data/doc/page_defaults.yaml +13 -0
- data/doc/tasks/default.rake +3 -0
- data/doc/templates/default/default.txt +1 -0
- data/doc/templates/default/default.yaml +4 -0
- data/examples/backgroundrb.yml +25 -0
- data/examples/foo_controller.rb +48 -0
- data/examples/god_worker.rb +7 -0
- data/examples/worker_tests/god_worker_test.rb +8 -0
- data/examples/workers/error_worker.rb +17 -0
- data/examples/workers/foo_worker.rb +38 -0
- data/examples/workers/god_worker.rb +7 -0
- data/examples/workers/model_worker.rb +13 -0
- data/examples/workers/renewal_worker.rb +11 -0
- data/examples/workers/rss_worker.rb +26 -0
- data/examples/workers/server_worker.rb +31 -0
- data/examples/workers/world_worker.rb +12 -0
- data/examples/workers/xmpp_worker.rb +7 -0
- data/init.rb +7 -0
- data/install.rb +1 -0
- data/know_issues.org +5 -0
- data/lib/backgroundrb.rb +1 -0
- data/lib/backgroundrb/bdrb_client_helper.rb +8 -0
- data/lib/backgroundrb/bdrb_cluster_connection.rb +156 -0
- data/lib/backgroundrb/bdrb_config.rb +43 -0
- data/lib/backgroundrb/bdrb_conn_error.rb +29 -0
- data/lib/backgroundrb/bdrb_connection.rb +179 -0
- data/lib/backgroundrb/bdrb_job_queue.rb +79 -0
- data/lib/backgroundrb/bdrb_result.rb +19 -0
- data/lib/backgroundrb/bdrb_start_stop.rb +146 -0
- data/lib/backgroundrb/rails_worker_proxy.rb +181 -0
- data/lib/backgroundrb/railtie.rb +48 -0
- data/lib/generators/backgroundrb/bdrb_migration/USAGE +12 -0
- data/lib/generators/backgroundrb/bdrb_migration/bdrb_migration_generator.rb +15 -0
- data/lib/generators/backgroundrb/bdrb_migration/templates/migration.rb +27 -0
- data/lib/generators/backgroundrb/worker/USAGE +16 -0
- data/lib/generators/backgroundrb/worker/templates/unit_test.rb +12 -0
- data/lib/generators/backgroundrb/worker/templates/worker.rb +7 -0
- data/lib/generators/backgroundrb/worker/worker_generator.rb +14 -0
- data/lib/tasks/backgroundrb_tasks.rake +103 -0
- data/release_notes.org +48 -0
- data/release_points.org +46 -0
- data/script/backgroundrb +52 -0
- data/script/bdrb_test_helper.rb +99 -0
- data/script/load_worker_env.rb +31 -0
- data/script/monitrc +25 -0
- data/server/backgroundrb_server.rb +12 -0
- data/server/lib/bdrb_result_storage.rb +62 -0
- data/server/lib/bdrb_server_helper.rb +24 -0
- data/server/lib/bdrb_thread_pool.rb +127 -0
- data/server/lib/cron_trigger.rb +197 -0
- data/server/lib/invalid_dump_error.rb +4 -0
- data/server/lib/log_worker.rb +25 -0
- data/server/lib/master_proxy.rb +140 -0
- data/server/lib/master_worker.rb +187 -0
- data/server/lib/meta_worker.rb +432 -0
- data/server/lib/trigger.rb +34 -0
- data/test/bdrb_client_test_helper.rb +5 -0
- data/test/bdrb_test_helper.rb +35 -0
- data/test/client/backgroundrb.yml +17 -0
- data/test/client/test_bdrb_client_helper.rb +13 -0
- data/test/client/test_bdrb_cluster_connection.rb +162 -0
- data/test/client/test_bdrb_config.rb +20 -0
- data/test/client/test_bdrb_connection.rb +29 -0
- data/test/client/test_bdrb_job_queue.rb +63 -0
- data/test/client/test_worker_proxy.rb +130 -0
- data/test/server/test_cron_trigger.rb +281 -0
- data/test/server/test_master_proxy.rb +54 -0
- data/test/server/test_master_worker.rb +157 -0
- data/test/server/test_meta_worker.rb +281 -0
- data/test/server/test_result_storage.rb +14 -0
- data/test/socket_mocker.rb +34 -0
- data/test/workers/bar_worker.rb +10 -0
- data/test/workers/foo_worker.rb +10 -0
- data/uninstall.rb +1 -0
- metadata +345 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Built-in
|
|
2
|
+
filters_pre: [ "redcloth" ]
|
|
3
|
+
# Custom
|
|
4
|
+
title: "Rails Integration of BackgrounDRb"
|
|
5
|
+
sidebar_items: [["Introduction", "#introduction"], ["Async Task", "#async_task"], ["Sync Task", "#sync_task"], ["Worker Results", "#worker_results"], ["Persistent Tasks", "#persistent_task"], ["New Worker", "#new_worker"], ["Worker Info", "#worker_info"], ["Clustering", "#clustering"]]
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<div id="content">
|
|
2
|
+
|
|
3
|
+
%(entry-title)<a name="timer_scheduling"> Timer Based Scheduling </a>%
|
|
4
|
+
|
|
5
|
+
Simple tasks in the workers can be scheduled using @add_timer@ or @add_periodic_timer@ methods.
|
|
6
|
+
For example:
|
|
7
|
+
|
|
8
|
+
<pre class="multiline">class HelloWorker < BackgrounDRb::MetaWorker
|
|
9
|
+
set_worker_name :hello_worker
|
|
10
|
+
|
|
11
|
+
def create(args = nil)
|
|
12
|
+
# time argument is in seconds
|
|
13
|
+
add_periodic_timer(10) { expire_sessions }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def expire_sessions
|
|
17
|
+
# expire user sessions
|
|
18
|
+
end
|
|
19
|
+
end </pre>
|
|
20
|
+
|
|
21
|
+
Similarly one can use @add_timer@ to fire oneshot task execution.
|
|
22
|
+
|
|
23
|
+
%(entry-title)<a name="unix_scheduling"> Unix Scheduler </a>%
|
|
24
|
+
|
|
25
|
+
_BackgrounDRb_ supports normal unix styled schedules which can be configured
|
|
26
|
+
from @backgroundrb.yml@ file. A sample configuration looks like:
|
|
27
|
+
|
|
28
|
+
<pre class="multiline">:backgroundrb:
|
|
29
|
+
:ip: 0.0.0.0
|
|
30
|
+
:port: 11006
|
|
31
|
+
:schedules:
|
|
32
|
+
:foo_worker:
|
|
33
|
+
:foobar:
|
|
34
|
+
:trigger_args:
|
|
35
|
+
:start: <%= Time.now + 5.seconds %>
|
|
36
|
+
:end: <%= Time.now + 10.minutes %>
|
|
37
|
+
:repeat_interval: <%= 1.minute %> </pre>
|
|
38
|
+
|
|
39
|
+
Above scheduler option schedules method @foobar@ defined inside @foo_worker@ to start
|
|
40
|
+
executing by 5 seconds delay and stop after 10 minutes. Method should periodically execute
|
|
41
|
+
every 1 minute between that time period. *Never in any scheduling option, you should schedule @create@
|
|
42
|
+
method/task*
|
|
43
|
+
|
|
44
|
+
%(entry-title)<a name="cron_scheduling"> Cron Scheduling </a>%
|
|
45
|
+
|
|
46
|
+
_BackgrounDRb_ also supports Cron based ccheduling.
|
|
47
|
+
You can use a configuration file for cron scheduling of workers. The method specified in the configuration
|
|
48
|
+
file would be called periodically. You should accommodate for the fact that the time gap between periodic
|
|
49
|
+
invocation of a method should be more than the time that is actually required to execute the method.
|
|
50
|
+
If a method takes longer time than the time window specified, your method invocations will lag
|
|
51
|
+
perpetually.
|
|
52
|
+
|
|
53
|
+
A Sample Configuration file for Cron based Scheduling looks like:
|
|
54
|
+
|
|
55
|
+
<pre class="multiline">
|
|
56
|
+
:backgroundrb:
|
|
57
|
+
:ip: 0.0.0.0
|
|
58
|
+
:port: 11006
|
|
59
|
+
:schedules:
|
|
60
|
+
:foo_worker:
|
|
61
|
+
:barbar:
|
|
62
|
+
:trigger_args: */10 * * * * *
|
|
63
|
+
:data: Hello World </pre>
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
Above scheduler will schedule invocation of @barbar@ method inside @foo_worker@ at every 10 seconds.
|
|
67
|
+
You can also schedule invocation of multiple methods in same worker at different intervals, just use
|
|
68
|
+
following as an example configuration file.
|
|
69
|
+
|
|
70
|
+
<pre class="multiline">
|
|
71
|
+
:backgroundrb:
|
|
72
|
+
:ip: 0.0.0.0
|
|
73
|
+
:port: 11006
|
|
74
|
+
:schedules:
|
|
75
|
+
:foo_worker:
|
|
76
|
+
:barbar:
|
|
77
|
+
:trigger_args: */10 * * * * *
|
|
78
|
+
:data: Hello World
|
|
79
|
+
:some_task: # execute some_method in foo_worker every 2nd hour
|
|
80
|
+
:trigger_args: 0 * */2 * * *
|
|
81
|
+
:data: Hello World </pre>
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
p(sub-title). A Word about Cron Scheduler
|
|
85
|
+
|
|
86
|
+
Note that the initial field in the BackgrounDRb cron trigger specifies
|
|
87
|
+
seconds, not minutes as with Unix-cron.
|
|
88
|
+
|
|
89
|
+
The fields (which can be an asterisk, meaning all valid patterns) are:
|
|
90
|
+
|
|
91
|
+
<pre class="boxed">sec[0,59] min[0,59], hour[0,23], day[1,31], month[1,12], weekday[0,6], year</pre>
|
|
92
|
+
|
|
93
|
+
The syntax pretty much follows Unix-cron. The following will trigger
|
|
94
|
+
on the first hour and the thirtieth minute every day:
|
|
95
|
+
|
|
96
|
+
<pre class="boxed">0 30 1 * * * *</pre>
|
|
97
|
+
|
|
98
|
+
The following will trigger the specified method every 10 seconds:
|
|
99
|
+
|
|
100
|
+
<pre class="boxed">*/10 * * * * * *</pre>
|
|
101
|
+
|
|
102
|
+
The following will trigger the specified method every 1 hour:
|
|
103
|
+
|
|
104
|
+
<pre class="boxed">0 0 * * * * *</pre>
|
|
105
|
+
|
|
106
|
+
For each field you can use a comma-separated list. The following would
|
|
107
|
+
trigger on the 5th, 16th and 23rd minute every hour:
|
|
108
|
+
|
|
109
|
+
<pre class="boxed"> 5,16,23 * * * * *</pre>
|
|
110
|
+
|
|
111
|
+
Fields also support ranges, using a dash between values. The following
|
|
112
|
+
triggers from 8th through the 17th hour, at five past the hour:
|
|
113
|
+
|
|
114
|
+
<pre class="boxed"> 5 8-17 * * * *</pre>
|
|
115
|
+
|
|
116
|
+
Finally, fields support repeat interval syntax. The following triggers
|
|
117
|
+
every five minutes, every other hour after the sixth hour:
|
|
118
|
+
|
|
119
|
+
<pre class="boxed"> */5 6/2 * * * *</pre>
|
|
120
|
+
|
|
121
|
+
Here is a more complex example: months 0,2,4,5,6,8,10,12, every day
|
|
122
|
+
and hour, minutes 1,2,3,4,6,20, seconds: every 5th second counting
|
|
123
|
+
from the 28th second plus the 59th second:
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
<pre class="boxed">28/5,59 1-4,6,20 */1 * 5,0/2 * *</pre>
|
|
127
|
+
|
|
128
|
+
Note that if you specify an asterisk in the first field (seconds)
|
|
129
|
+
it will trigger every second for the subsequent match.
|
|
130
|
+
|
|
131
|
+
%(entry-title)<a name="restart_on_schedule"> Restart worker on schedule </a>%
|
|
132
|
+
|
|
133
|
+
Usually when your worker is scheduled to execute at longer intervals, it
|
|
134
|
+
doesn't make sense to have worker around, when its doing nothing. Since, scheduling
|
|
135
|
+
via configuration file requires that your worker must be loaded when _BackgrounDRb_ starts,
|
|
136
|
+
your worker is always around, even when doing nothing.
|
|
137
|
+
|
|
138
|
+
You can reuse worker in processing requests from rails, but if its not possible
|
|
139
|
+
and you rather want worker to start afresh each time, scheduler detects a firetime, you can use
|
|
140
|
+
following syntax to autostart workers on scheduled time:
|
|
141
|
+
|
|
142
|
+
<pre class="multiline">class HelloWorker < BackgrounDRb::MetaWorker
|
|
143
|
+
set_worker_name :hello_worker
|
|
144
|
+
reload_on_schedule true
|
|
145
|
+
|
|
146
|
+
def create(args = nil)
|
|
147
|
+
# this method is called, when worker is loaded for the first time
|
|
148
|
+
end
|
|
149
|
+
end </pre>
|
|
150
|
+
|
|
151
|
+
In above worker @reload_on_schedule true@ makes sure that your worker is restarted on
|
|
152
|
+
scheduled time. This feature is only available in version 1.0.3 onwards.
|
|
153
|
+
|
|
154
|
+
%(entry-title)<a name="schedule_at"> Schedule one shot execution of task at specified time </a>%
|
|
155
|
+
|
|
156
|
+
<p><b> Only available for tasks persisted to database table </b></p>
|
|
157
|
+
|
|
158
|
+
If you are using job queue table and want one shot execution of a task scheduled at a particular time. You can use:
|
|
159
|
+
|
|
160
|
+
<pre class="multiline">MiddleMan(:hello_worker).enq_some_task(:arg => "hello_world",
|
|
161
|
+
:job_key => "boy",:scheduled_at => Time.now + 30.minutes)</pre>
|
|
162
|
+
|
|
163
|
+
Which will schedule specified task to be executed after 30 minutes from now.
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
</div>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Built-in
|
|
2
|
+
filters_pre: [ "redcloth" ]
|
|
3
|
+
# Custom
|
|
4
|
+
title: "Scheduling Tasks using BackgrounDRb"
|
|
5
|
+
sidebar_items: [["Timers", "#timer_scheduling"], ["Unix Scheduler", "#unix_scheduling"], ["Cron Scheduler", "#cron_scheduling"], ["Restart on Schedule", "#restart_on_schedule"], ["Schedule At", "#schedule_at"]]
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
<div id="content">
|
|
2
|
+
|
|
3
|
+
%(entry-title)<a name="introduction"> Workers </a>%
|
|
4
|
+
|
|
5
|
+
Workers are your building blocks of Asynchronous Task Processing. An empty auto generated worker looks like this:
|
|
6
|
+
|
|
7
|
+
<pre class="multiline">class BillingWorker < BackgrounDRb::MetaWorker
|
|
8
|
+
set_worker_name :billing_worker
|
|
9
|
+
def create(args = nil)
|
|
10
|
+
# method gets called, when new instance of worker is created.
|
|
11
|
+
end
|
|
12
|
+
end </pre>
|
|
13
|
+
|
|
14
|
+
@set_worker_name@ will set the worker name which can be later used while invoking tasks on the worker.
|
|
15
|
+
@create@ method gets called when worker is loaded for the first time. If you are starting your worker
|
|
16
|
+
from rails, you can pass arguments to @create@ method using:
|
|
17
|
+
|
|
18
|
+
<pre class="multiline">MiddleMan.new_worker(:worker => :billing_worker,\
|
|
19
|
+
:worker_key => user_session,:data => current_user.id) </pre>
|
|
20
|
+
|
|
21
|
+
p(sub-title). Using Workers
|
|
22
|
+
|
|
23
|
+
You can invoke random tasks on workers from rails or you can schedule them using config file. Look into
|
|
24
|
+
"Scheduling":/scheduling/index.html section for scheduling and "Rails Integration":/rails/index.html section
|
|
25
|
+
for invoking worker tasks from rails.
|
|
26
|
+
|
|
27
|
+
p(sub-title). Inbuilt instance methods available in your workers:
|
|
28
|
+
|
|
29
|
+
*(content_list) @cache@ : Can be used to store random results from worker which can be later retrieved from rails. For example:
|
|
30
|
+
<pre class="boxed"> cache[key] = some_data </pre>
|
|
31
|
+
* @add_timer@ : Look in scheduler section
|
|
32
|
+
* @add_periodic_timer@ : Look in scheduler section
|
|
33
|
+
* @thread_pool@ : Look below
|
|
34
|
+
* @connect@: Look in "Advanced":/advanced/index.html section. Used to connect to external TCP/IP servers.
|
|
35
|
+
* @start_server@: Look in "Advanced":/advanced/index.html section. Used to start TCP/IP server from worker.
|
|
36
|
+
* @send_data@: Can be used to send objects to master process. You can ignore this method.
|
|
37
|
+
* @job_key@: When you invoke a task from rails by passing a job_key, that job_key can be accessed in workers with @job_key@. For example:
|
|
38
|
+
From rails:
|
|
39
|
+
<pre class="boxed"> MiddleMan.worker(:foo_worker).async_some_task(:arg => urls,
|
|
40
|
+
:job_key => current_user[:id])</pre>
|
|
41
|
+
Now this @job_key@ can be accessed inside workers with:
|
|
42
|
+
<pre class="multiline">class FooWorker < BackgrounDRb::MetaWorker
|
|
43
|
+
def some_task urls
|
|
44
|
+
.. do some work with urls ..
|
|
45
|
+
cache[job_key] = result
|
|
46
|
+
end
|
|
47
|
+
end</pre>
|
|
48
|
+
|
|
49
|
+
p(sub-title). Options via class methods :
|
|
50
|
+
|
|
51
|
+
Following class methods are available for further tuning of workers:
|
|
52
|
+
|
|
53
|
+
*(content_list) @pool_size@ : Can be used to control thread pool size. Accepts pool size as integer value.
|
|
54
|
+
* @set_no_auto_load@ : Can be used to disable auto loading of workers when _BackgrounDRb_ starts. Accepts true or false.
|
|
55
|
+
* @reload_on_schedule@ : Can be used to enable reloading of worker at scheduled execution time. Accepts true or false.
|
|
56
|
+
* @set_worker_name@ : Can be used to set worker name. Accepts symbol as worker name.
|
|
57
|
+
|
|
58
|
+
Following snippet demonstrates their usages:
|
|
59
|
+
|
|
60
|
+
<pre class="multiline">class HelloWorker < BackgrounDRb::MetaWorker
|
|
61
|
+
set_worker_name :hello_worker
|
|
62
|
+
reload_on_schedule true
|
|
63
|
+
pool_size 10
|
|
64
|
+
end</pre>
|
|
65
|
+
|
|
66
|
+
When @reload_on_schedule@ is true, worker won't be loaded while _BackgrounDRb_ starts and hence you don't need
|
|
67
|
+
@set_no_auto_load@ option there.
|
|
68
|
+
|
|
69
|
+
%(entry-title)<a name="thread_pool"> Using Thread Pool </a>%
|
|
70
|
+
|
|
71
|
+
Remember _BackgrounDRb_ follows event model of network programming, but sad truth of life is not all networking
|
|
72
|
+
libraries follow this model and hence they make use of blocking IO and threads. BackgrounDRb allows you to run
|
|
73
|
+
all such tasks concurrently in threads which are internally managed by BackgrounDRb thread pool.
|
|
74
|
+
|
|
75
|
+
Each worker has access to object @thread_pool@ which can be used to run task in a thread concurrently.
|
|
76
|
+
|
|
77
|
+
<pre class="boxed">thread_pool.defer(:scrap_wikipedia,scrap_url) </pre>
|
|
78
|
+
|
|
79
|
+
So whatever code you write within @scrap_wikipedia@ method is going to run concurrently.
|
|
80
|
+
|
|
81
|
+
*WARNING*: Many of the Ruby libraries out there aren't thread safe and they may not
|
|
82
|
+
work as advertised when used from threads(example: Mechanize,Scrubyt)
|
|
83
|
+
|
|
84
|
+
%(entry-title)<a name="result_caching"> Result Caching </a>%
|
|
85
|
+
|
|
86
|
+
<b>Update : </b> <em>Using MemCache to store result objects is strongly recommended. Inbuilt cache works, but may give
|
|
87
|
+
unpredictable results. Also, using Memcache serves as an out of process cache, which can be queried at any time.
|
|
88
|
+
If your worker is doing some processing, inbuilt cache may not return result until worker picks up that request.</em>
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
All workers can cache results using @cache@ attribute. This result object can be then
|
|
92
|
+
queried from rails using @ask_result@. For example:
|
|
93
|
+
|
|
94
|
+
<pre class="multiline">class ProgressWorker < BackgrounDRb::MetaWorker
|
|
95
|
+
set_worker_name :progress_worker
|
|
96
|
+
def create
|
|
97
|
+
@counter = 0
|
|
98
|
+
add_periodic_timer(2) { increment_counter }
|
|
99
|
+
end
|
|
100
|
+
def increment_counter
|
|
101
|
+
@counter += 1
|
|
102
|
+
cache[some_key] = counter
|
|
103
|
+
end
|
|
104
|
+
end</pre>
|
|
105
|
+
|
|
106
|
+
And using @MiddleMan@ proxy, you can keep querying the status of progress bar :
|
|
107
|
+
|
|
108
|
+
<pre class="boxed">MiddleMan.worker(:progress_worker).ask_result(some_key)</pre>
|
|
109
|
+
|
|
110
|
+
By default, @cache@ is a worker local hash like object, which is used for storing results.
|
|
111
|
+
But if you plan to store lots of objects in cache from your worker, it may not be an
|
|
112
|
+
optimal solution. You can easily replace in-worker cache with memcache.
|
|
113
|
+
|
|
114
|
+
You need to change @backgroundrb.yml@ file like this, for using memcache for object caching:
|
|
115
|
+
|
|
116
|
+
<pre class="multiline">:backgroundrb:
|
|
117
|
+
:ip: 0.0.0.0
|
|
118
|
+
:port: 11006
|
|
119
|
+
:result_storage: memcache
|
|
120
|
+
|
|
121
|
+
:memcache: "10.0.0.1:11211,10.0.0.2:11211" </pre>
|
|
122
|
+
|
|
123
|
+
Everything else remains the same.
|
|
124
|
+
|
|
125
|
+
%(entry-title)<a name="persistent_job">Persistent Task Queue </a>%
|
|
126
|
+
|
|
127
|
+
BackgrounDRb now have out of box support for persistent job queues which are persisted to the
|
|
128
|
+
database. API to add a task in the job_queue is pretty simple:
|
|
129
|
+
|
|
130
|
+
<pre class="boxed">MiddleMan(:hello_worker).enq_some_task(:arg => "hello_world",:job_key => "boy")</pre>
|
|
131
|
+
|
|
132
|
+
So in your hello worker:
|
|
133
|
+
|
|
134
|
+
<pre class="multiline">
|
|
135
|
+
class HelloWorker
|
|
136
|
+
def some_task args
|
|
137
|
+
.. do some work ..
|
|
138
|
+
persistent_job.finish! #=> marks the job as finished. totally thread safe
|
|
139
|
+
end
|
|
140
|
+
end</pre>
|
|
141
|
+
|
|
142
|
+
@persistent_job@ is a thread local variable and will refer to currently
|
|
143
|
+
running queued task can be used from thread pool as well. For example:
|
|
144
|
+
|
|
145
|
+
<pre class="multiline">
|
|
146
|
+
class HelloWorker
|
|
147
|
+
def some_task args
|
|
148
|
+
thread_pool.defer(:fetch_url,args)
|
|
149
|
+
end
|
|
150
|
+
def fetch_url tags
|
|
151
|
+
.. runs in thread ..
|
|
152
|
+
.. fetch tasks ..
|
|
153
|
+
persistent_job.finish!
|
|
154
|
+
end
|
|
155
|
+
end</pre>
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
%(entry-title)<a name="worker_testing">Testing Workers </a>%
|
|
159
|
+
|
|
160
|
+
_BackgrounDRb_ comes with a baked in mechanism to write test cases. First make sure that you
|
|
161
|
+
have bdrb_test_helper.rb in the test directory of your rails app (run @rake backgroundrb:setup@, if you dont have one).
|
|
162
|
+
|
|
163
|
+
Just put your worker test cases in test/unit directory of your rails application and require the helper. Now, you should be good to go.
|
|
164
|
+
|
|
165
|
+
<pre class="multiline">require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")
|
|
166
|
+
require "god_worker"
|
|
167
|
+
context "When god worker starts" do
|
|
168
|
+
setup do
|
|
169
|
+
god_worker = GodWorker.new
|
|
170
|
+
end
|
|
171
|
+
end </pre>
|
|
172
|
+
|
|
173
|
+
All above helper file does is that it stubs out, relevant worker methods, which really need network IO.
|
|
174
|
+
There can be methods added, which aren't stubbed, for all such methods you are encouraged to stub them and send
|
|
175
|
+
the patch to the backgroundrb mailing list.
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
</div>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Built-in
|
|
2
|
+
filters_pre: [ "redcloth" ]
|
|
3
|
+
# Custom
|
|
4
|
+
title: "Using BackgrounDRb workers"
|
|
5
|
+
sidebar_items: [["Introduction", "#introduction"], ["Thread Pool", "#thread_pool"], ["Result Caching", "#result_caching"], ["Persistent Jobs", "#persistent_job"], ["Worker Testing", "#worker_testing"]]
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
3
|
+
<head>
|
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
|
5
|
+
<title>BackgrounDRb - <%= @page.title %></title>
|
|
6
|
+
<link rel="stylesheet" href="/style.css" type="text/css" media="screen" />
|
|
7
|
+
</head>
|
|
8
|
+
|
|
9
|
+
<body>
|
|
10
|
+
|
|
11
|
+
<div id="wrapper">
|
|
12
|
+
<div id="header">
|
|
13
|
+
<h1> BackgrounDRb </h1>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div id="menu">
|
|
17
|
+
<ul>
|
|
18
|
+
<li><a href="/"> Intro </a></li>
|
|
19
|
+
<li><a href="/scheduling/"> Scheduling </a></li>
|
|
20
|
+
<li><a href="/workers/"> Workers </a></li>
|
|
21
|
+
<li><a href="/rails/"> Rails Integration </a></li>
|
|
22
|
+
<li><a href="/advanced/"> Advanced </a></li>
|
|
23
|
+
<li><a href="/manual/index.html"> Manual </a></li>
|
|
24
|
+
<li><a href="/community/"> Community </a></li>
|
|
25
|
+
<li><a href="/faq"> FAQs </a></li>
|
|
26
|
+
</ul>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div id="sidebar">
|
|
30
|
+
<div id="feed">
|
|
31
|
+
<!-- <a class="feed-button" href="#"> </a> -->
|
|
32
|
+
</div>
|
|
33
|
+
<ul>
|
|
34
|
+
<% if @page.sidebar_items %>
|
|
35
|
+
<% for menu_item in @page.sidebar_items %>
|
|
36
|
+
<li><a href="<%= menu_item[1] %>"> <%= menu_item[0] %> </a></li>
|
|
37
|
+
<% end %>
|
|
38
|
+
<% end %>
|
|
39
|
+
</ul>
|
|
40
|
+
|
|
41
|
+
<div id="sidebar-bottom"> </div>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<%= @page.content %>
|
|
45
|
+
|
|
46
|
+
<div id="footer">
|
|
47
|
+
<div id="footer-valid">
|
|
48
|
+
<a href="http://validator.w3.org/check/referer">xhtml</a> ::
|
|
49
|
+
<span align="right"> Created with <a href="http://nanoc.stoneship.org/"> Nanoc </a> </span>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
</div> <!-- end of wrapper div tag -->
|
|
55
|
+
</body>
|
|
56
|
+
</html>
|
data/doc/lib/default.rb
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|