backgroundrb-rails3 1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/doc/Rakefile
ADDED
data/doc/config.yaml
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
<div id="content">
|
2
|
+
|
3
|
+
%(entry-title)<a name="advanced"> Advanced Stuff </a>%
|
4
|
+
|
5
|
+
Each worker comes with an Event loop of its own and can potentially do lots of fancy stuff. Two noteworthy methods are:
|
6
|
+
|
7
|
+
<pre class="multiline">connect(ip,port,Handler)
|
8
|
+
start_server(ip,port,Handler) </pre>
|
9
|
+
|
10
|
+
If you are familiar with the EventMachine or Twisted style of network programming, the above methods allow you to
|
11
|
+
start tcp servers inside your workers or let you connect to external tcp servers. For Each accepted client or
|
12
|
+
connected socket, an instance of Handler class would be created and integrated with main event loop.
|
13
|
+
This can be used for worker to worker communication between backgroundrb servers running on two machines.
|
14
|
+
|
15
|
+
p(sub-title). @BackgrounDRb::MetaWorker#connect@ :
|
16
|
+
|
17
|
+
@connect@ lets you connect to an external TCP Server and integrates the connection within reactor loop
|
18
|
+
of worker. For example:
|
19
|
+
|
20
|
+
<pre class="multiline">class TimeClient
|
21
|
+
def receive_data(p_data)
|
22
|
+
worker.get_external_data(p_data)
|
23
|
+
end
|
24
|
+
|
25
|
+
def post_init
|
26
|
+
p "***************** : connection completed"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class FooWorker < BackgrounDRb::MetaWorker
|
31
|
+
set_worker_name :foo_worker
|
32
|
+
def create(args = nil)
|
33
|
+
external_connection = nil
|
34
|
+
connect("localhost",11009,TimeClient) { |conn| external_connection = conn }
|
35
|
+
end
|
36
|
+
def get_external_data(p_data)
|
37
|
+
puts "And external data is : #{p_data}"
|
38
|
+
end
|
39
|
+
end </pre>
|
40
|
+
|
41
|
+
p(sub-title). @BackgrounDRb::MetaWorker#start_server@ :
|
42
|
+
|
43
|
+
Above method allows you to start a tcp server from your worker, all the accepted connections are integrated with event loop of worker.
|
44
|
+
|
45
|
+
<pre class="multiline"> class TimeServer
|
46
|
+
|
47
|
+
def receive_data(p_data)
|
48
|
+
end
|
49
|
+
|
50
|
+
def post_init
|
51
|
+
add_periodic_timer(2) { say_hello_world }
|
52
|
+
end
|
53
|
+
|
54
|
+
def connection_completed
|
55
|
+
end
|
56
|
+
|
57
|
+
def say_hello_world
|
58
|
+
p "***************** : invoking hello world #{Time.now}"
|
59
|
+
send_data("Hello World\n")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class ServerWorker < BackgrounDRb::MetaWorker
|
64
|
+
set_worker_name :server_worker
|
65
|
+
def create(args = nil)
|
66
|
+
# start the server when worker starts
|
67
|
+
start_server("0.0.0.0",11009,TimeServer) do |client_connection|
|
68
|
+
client_connection.say_hello_world
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end </pre>
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
</div>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<div id="content">
|
2
|
+
|
3
|
+
%(entry-title)<a name="trac">Submit Bug Report or Patch </a>%
|
4
|
+
|
5
|
+
_BackgrounDRb_ causing trouble, or you have a potential fix? Why not submit the bug report "here":http://backgroundrb.devjavu.com/report/ .
|
6
|
+
You can also submit potential patches that fix known bugs or add exciting features to the above trac url.
|
7
|
+
|
8
|
+
Also, if you are using older version of _BackgrounDRb_ and having a problem, why not upgrade to latest code from git, your bug
|
9
|
+
might have been fixed there.
|
10
|
+
|
11
|
+
%(entry-title)<a name="known_bugs">Known Problems </a>%
|
12
|
+
|
13
|
+
Since _BackgrounDRb_ has feature of thread pools, which allows users to execute tasks
|
14
|
+
concurrently, we are using @allow_concurrency = true@ in @ActiveRecord@ model objects.
|
15
|
+
This has been known to create some issues with Oracle database Adapters. If you are sure of
|
16
|
+
what you are doing and don't need thread pool feature, you can go ahead and remove @allow_concurrency = true@
|
17
|
+
from _BackgrounDRb_ code and it should work.
|
18
|
+
|
19
|
+
</div>
|
20
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<div id="content">
|
2
|
+
|
3
|
+
%(entry-title)<a name="people"> People </a>%
|
4
|
+
|
5
|
+
_BackgrounDRb_ has been brought to you by, "Hemant Kumar":http://gnufied.org with help of folks
|
6
|
+
from Ruby and Ruby on Rails community. _BackgrounDRb_ was an original idea of "Ezra Zygmuntowicz":http://brainspl.at .
|
7
|
+
|
8
|
+
Today it pulls in ideas from "EventMachine":http://eventmachine.rubyforge.org , "Twisted":http://twistedmatrix.com .
|
9
|
+
I am eternally grateful to following people ( in no particular order ):
|
10
|
+
|
11
|
+
*(content_list) Francis Cianfrocca : For EventMachine
|
12
|
+
* Matz : For creating Ruby
|
13
|
+
* Dale Cook : For Documentation
|
14
|
+
* "Jason LaPier":http://offtheline.net : for initial testing and bug reports.
|
15
|
+
* Kevin Russell : For Letting me work on his Mac machine all day and night and helping out with Mac OSX issues.
|
16
|
+
* Richard Stallman: For giving us free software and Emacs.
|
17
|
+
|
18
|
+
|
19
|
+
%(entry-title)<a name="mailing_list"> Mailing List </a>%
|
20
|
+
|
21
|
+
You can join BackgrounDRb mailing list "here":http://rubyforge.org/mailman/listinfo/backgroundrb-devel .
|
22
|
+
Its a perfect place for discussing new ideas, asking questions, submitting patches and stuff.
|
23
|
+
|
24
|
+
%(entry-title)<a name="irc"> IRC Help </a>%
|
25
|
+
|
26
|
+
You can also try #backgroundrb on freenode for help.
|
27
|
+
|
28
|
+
%(entry-title)<a name="contribute"> Contribute </a>%
|
29
|
+
|
30
|
+
Your contributions/feedback is most welcome. We have very simple rule for giving new coders
|
31
|
+
commit access. If you submit one patch which is accepted for inclusion in the _BackgrounDRb_
|
32
|
+
code repository, you are elligible for commit access. Create an account on "Github":http://github.com/
|
33
|
+
and let me (gethemant at gmail dot com) know your login handle.
|
34
|
+
|
35
|
+
</div>
|
36
|
+
|
@@ -0,0 +1,168 @@
|
|
1
|
+
<div id="content">
|
2
|
+
|
3
|
+
%(entry-title)<a name="introduction"> Introduction </a>%
|
4
|
+
|
5
|
+
*BackgrounDRb* is a Ruby job server and scheduler. Its main intent is to be
|
6
|
+
used with Ruby on Rails applications for offloading long-running tasks.
|
7
|
+
Since a Rails application blocks while serving a request it is best to
|
8
|
+
move long-running tasks off into a background process that is divorced
|
9
|
+
from http request/response cycle.
|
10
|
+
|
11
|
+
%(entry-title)<a name="installation"> Installation </a>%
|
12
|
+
|
13
|
+
p(sub-title). Installing the dependencies :
|
14
|
+
|
15
|
+
As of version 1.0.4 _BackgrounDRb_ depends on _chronic_ and _packet_ gems. Thus lets get
|
16
|
+
started by installing these two gems:
|
17
|
+
|
18
|
+
<pre class="boxed">sudo gem install chronic packet </pre>
|
19
|
+
|
20
|
+
Please note that, this version of _BackgrounDRb_ needs packet version 0.1.7 or greater, so make
|
21
|
+
sure you have that.
|
22
|
+
|
23
|
+
p(sub-title). Getting the code from Subversion :
|
24
|
+
|
25
|
+
<pre class="boxed"> svn co http://svn.devjavu.com/backgroundrb/trunk </pre>
|
26
|
+
|
27
|
+
p(sub-title). Installing from Git:
|
28
|
+
|
29
|
+
As of version 1.0.4 __BackgrounDRb__ development has moved to <a href="http://github.com/gnufied/backgroundrb/tree/master">github</a>. Above SVN url
|
30
|
+
will always mirror stable releases from Git. However to enjoy latest and greatest of features
|
31
|
+
you can install the plugin from git:
|
32
|
+
|
33
|
+
<pre class="multiline">
|
34
|
+
git clone git://github.com/gnufied/backgroundrb.git </pre>
|
35
|
+
|
36
|
+
<p style="text-decoration: line-through;"> Also for running git version of BackgrounDRb you will need, git version of packet.</p>
|
37
|
+
|
38
|
+
p(sub-title). Installation using Piston
|
39
|
+
|
40
|
+
<pre class="boxed">piston import http://svn.devjavu.com/backgroundrb/trunk/ backgroundrb </pre>
|
41
|
+
|
42
|
+
%(entry-title)<a name="configuration"> Configuration </a>%
|
43
|
+
|
44
|
+
After getting the plugin, you must copy it into your vendor/plugins and
|
45
|
+
then configure it for use. _BackgrounDRb_ comes with a rake task for
|
46
|
+
automating plugin configuration. Before running rake task, remove if
|
47
|
+
any old @backgroundrb@ or @load_worker_env.rb@ script is there in script folder of your rails
|
48
|
+
app after that run, following command from root directory of your
|
49
|
+
rails application:
|
50
|
+
|
51
|
+
<pre class="boxed">rake backgroundrb:setup </pre>
|
52
|
+
|
53
|
+
Above Command does following things :
|
54
|
+
|
55
|
+
*(content_list) Creates a config file @backgroundrb.yml@ in config directory of your rails application.
|
56
|
+
* Creates @RAILS_ROOT/lib/workers@ directory for keeping BackgrounDRb workers in one place.
|
57
|
+
* Creates @RAILS_ROOT/test/bdrb_test_helper.rb@ as a test helper for your workers
|
58
|
+
* Creates migration required for creating persistent job queue table.
|
59
|
+
|
60
|
+
After above make sure, that generated migration is ran using:
|
61
|
+
|
62
|
+
<pre class="boxed">rake db:migrate </pre>
|
63
|
+
|
64
|
+
p(sub-title). Configuration Options
|
65
|
+
|
66
|
+
A default @backgroundrb.yml@ file looks like this:
|
67
|
+
|
68
|
+
<pre class="multiline">
|
69
|
+
:backgroundrb:
|
70
|
+
:port: 11006
|
71
|
+
:ip: 0.0.0.0 </pre>
|
72
|
+
|
73
|
+
However, various other configuration options are available. For example, to load @production@
|
74
|
+
environment in your workers:
|
75
|
+
|
76
|
+
<pre class="multiline">
|
77
|
+
:backgroundrb:
|
78
|
+
:port: 11006
|
79
|
+
:ip: 0.0.0.0
|
80
|
+
:environment: production </pre>
|
81
|
+
|
82
|
+
|
83
|
+
Following file demonstrates other available configuration options:
|
84
|
+
|
85
|
+
<pre class="multiline">
|
86
|
+
---
|
87
|
+
:backgroundrb:
|
88
|
+
:port: 11006 # port to start listen
|
89
|
+
:ip: localhost # host to listen
|
90
|
+
:environment: production # rails environment to load
|
91
|
+
:log: foreground # foreground mode,print log messages on console
|
92
|
+
:debug_log: false # disable log workers and other logging
|
93
|
+
:persistent_disabled: false # turn this off if your application doesn't use backgroundrb's persistent/enqueued tasks system
|
94
|
+
:persistent_delay: 10 # the time (seconds) between each time backgroundrb checks the database for enqueued tasks
|
95
|
+
:schedules: # optional task scheduling
|
96
|
+
: # look in scheduling section </pre>
|
97
|
+
|
98
|
+
%(entry-title)<a name="worker"> Workers </a>%
|
99
|
+
|
100
|
+
Once you are set with initial configuration, you can proceed to create worker and start
|
101
|
+
_BackgrounDRb_ server. To generate a worker:
|
102
|
+
|
103
|
+
<pre class="boxed"> ./script/generate worker billing </pre>
|
104
|
+
|
105
|
+
Output will look something like:
|
106
|
+
|
107
|
+
<pre class="multiline">exists lib/workers/
|
108
|
+
create lib/workers/billing_worker.rb </pre>
|
109
|
+
|
110
|
+
And generated worker will look like:
|
111
|
+
|
112
|
+
<pre class="multiline">class BillingWorker < BackgrounDRb::MetaWorker
|
113
|
+
set_worker_name :billing_worker
|
114
|
+
def create(args = nil)
|
115
|
+
# method gets called, when new instance of worker is created.
|
116
|
+
end
|
117
|
+
end </pre>
|
118
|
+
|
119
|
+
|
120
|
+
You can define worker specific initialization in @create@ method. Tasks that are to be executed
|
121
|
+
in this worker should be defined as seperate methods. For example:
|
122
|
+
|
123
|
+
<pre class="multiline">class BillingWorker < BackgrounDRb::MetaWorker
|
124
|
+
set_worker_name :billing_worker
|
125
|
+
def create(args = nil)
|
126
|
+
# this method is called, when worker is loaded for the first time
|
127
|
+
end
|
128
|
+
|
129
|
+
def charge_customer(customer_id = nil)
|
130
|
+
logger.info 'charging customer now'
|
131
|
+
end
|
132
|
+
end </pre>
|
133
|
+
|
134
|
+
%(entry-title)<a name="invoking_tasks"> Invoking Tasks </a>%
|
135
|
+
|
136
|
+
Task @charge_customer@ defined in @BillingWorker@ can be invoked in several ways. To beging with
|
137
|
+
it can be invoked from rails or can be scheduled to execute at particular interval using
|
138
|
+
cron like syntax.
|
139
|
+
|
140
|
+
p(sub-title). Invoking Task from Rails :
|
141
|
+
|
142
|
+
In your Rails controllers you have access to proxy class @MiddleMan@ which can be used
|
143
|
+
to interact with BackgrounDRb server, either from Rails controllers/Models or from Rails console.
|
144
|
+
For example to invoke @charge_customer@ method asychronously one can use:
|
145
|
+
|
146
|
+
<pre class="boxed">MiddleMan.worker(:billing_worker).async_charge_customer(:arg => current_customer.id) </pre>
|
147
|
+
|
148
|
+
Above code can be also executed from Rails console.
|
149
|
+
|
150
|
+
p(sub-title). Start the BackgrounDRb server :
|
151
|
+
|
152
|
+
You can use:
|
153
|
+
|
154
|
+
<pre class="boxed">./script/backgroundrb start </pre>
|
155
|
+
|
156
|
+
For more options:
|
157
|
+
|
158
|
+
<pre class="boxed">./script/backgroundrb --help </pre>
|
159
|
+
|
160
|
+
As documented above, you can use @backgroundrb.yml@ file to load different rails environments, however you can use:
|
161
|
+
|
162
|
+
<pre class="boxed">./script/backgroundrb -e development </pre>
|
163
|
+
|
164
|
+
</div>
|
165
|
+
|
166
|
+
|
167
|
+
|
168
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<div id="content">
|
2
|
+
|
3
|
+
%(entry-title)<a name="faq"> Frequently asked Questions </a>%
|
4
|
+
|
5
|
+
*(content_list) *How does it work with ActiveRecord in multi-threaded environment?*<br/>
|
6
|
+
You can use _BackgrounDRb_'s inbuilt thread pool for executing tasks
|
7
|
+
concurrently. We are using @allow_concurrency = true@ for @ActiveRecord@
|
8
|
+
models, which is known to create problem with Oracle database adapters, if
|
9
|
+
you are using Oracle db, you can turn it off, by removing @allow_concurrency = true@.
|
10
|
+
* *Whats the deal with persistent job queues?*<br />
|
11
|
+
Well, its used for persisting tasks to the table, so as later
|
12
|
+
then can be inspected for status and results. Before using this feature.You should
|
13
|
+
run @rake backgroundrb:setup@ and run @rake db:migrate@ for creation of required
|
14
|
+
table.
|
15
|
+
* *My worker dies silently*<br />
|
16
|
+
First,make sure you have logging enabled (Meaning, you are not using @:debug_log false@
|
17
|
+
in your config file).Second, if a worker dies, the backtrace should be written to the
|
18
|
+
file @RAILS_ROOT/log/backgroundrb_debug_xxxx.log@. Third, You should not pass
|
19
|
+
entire @ActiveRecord@ model's around, this could cause hard to debug problems.AR objects
|
20
|
+
don't serialize well across tcp sockets. If none of this helps, hit us on the mailing list.
|
21
|
+
* *Master server died silently*<br/>
|
22
|
+
If _BackgrounDRb_ master server dies, its definetely a bug in _BackgrounDRb_, exception
|
23
|
+
should be still logged in same @RAILS_ROOT/log/backgroundrb_debug_xxxx.log@ file. Copy
|
24
|
+
the exception and file a bug report.
|
25
|
+
* *Where do I file bug reports?* <br />
|
26
|
+
You can submit bug reports at: "http://backgroundrb.devjavu.com/report/":http://backgroundrb.devjavu.com/report/.
|
27
|
+
* *Result caching is not working properly* <br />
|
28
|
+
Switch to memcache for storing results. More information "here:"http://localhost:3000/workers/#result_caching.
|
29
|
+
* *Dynamically started workers through @new_worker@ are not working* <br />
|
30
|
+
Use, the worker key that was used for accessing dynamically started workers.
|
31
|
+
* *BackgrounDRb server is not starting*<br />
|
32
|
+
Make sure, you have latest version of chronic and packet gems installed.After
|
33
|
+
that, clone the git repository (or download a snapshot from github) and run
|
34
|
+
@rake backgroundrb:setup@. If you are upgrading make sure, that older
|
35
|
+
autogenerated scripts namely, @load_worker_env.rb@ and @backgroundrb@
|
36
|
+
are removed from script directory of your rails application before running
|
37
|
+
rake task.If you are upgrading to 1.1, check if @scheduled_at@ column
|
38
|
+
is there in @bdrb_job_queues@ table.
|
39
|
+
|
40
|
+
</div>
|
41
|
+
|
@@ -0,0 +1,182 @@
|
|
1
|
+
<div id="content">
|
2
|
+
|
3
|
+
%(entry-title)<a name="introduction"> Introduction </a>%
|
4
|
+
|
5
|
+
BackgrounDRb offers seamless integration with rails. You can invoke random tasks defined in your
|
6
|
+
workers from rails. You can pass arguments, collect results, monitor status of workers and other
|
7
|
+
stuff.
|
8
|
+
|
9
|
+
%(entry-title)<a name="async_task"> Invoke a task asynchronously on a worker </a>%
|
10
|
+
|
11
|
+
Let's say, you have following worker code:
|
12
|
+
|
13
|
+
<pre class="multiline">class FooWorker < BackgrounDRb::MetaWorker
|
14
|
+
set_worker_name :foo_worker
|
15
|
+
def create(args = nil)
|
16
|
+
# this method is called, when worker is loaded for the first time
|
17
|
+
end
|
18
|
+
|
19
|
+
def some_task args
|
20
|
+
# perform a long running task
|
21
|
+
end
|
22
|
+
end
|
23
|
+
</pre>
|
24
|
+
|
25
|
+
And you want to invoke @some_task@ method with appropriate arguments from rails.
|
26
|
+
Following snippet will invoke method @some_task@ with argument @data@ in @foo_worker@. Also, method will
|
27
|
+
be invoked asynchronously and Rails won't wait for result from BackgrounDRb server.
|
28
|
+
|
29
|
+
<pre class="multiline">worker = MiddleMan.worker(:foo_worker)
|
30
|
+
worker.async_some_task(:arg => data) </pre>
|
31
|
+
|
32
|
+
It should be noted that, since @some_task@ method is being
|
33
|
+
executed asynchronously, don't expect any meaningful return values from method invocation.
|
34
|
+
If you want to invoke a method on worker and collect results returned by it, you
|
35
|
+
should read next section (Invoke method and collect results).
|
36
|
+
|
37
|
+
When you invoke @MiddleMan.worker(:foo_worker)@ it returns a worker proxy, hence you can combine above two lines in
|
38
|
+
one as follows:
|
39
|
+
|
40
|
+
<pre class="multiline">MiddleMan.worker(:foo_worker,<optional_worker_key>).
|
41
|
+
async_some_task(:arg => data) </pre>
|
42
|
+
|
43
|
+
Above snippet also demonstrates that, if your worker was started with a @worker_key@ you can use it to
|
44
|
+
get correct worker proxy.
|
45
|
+
|
46
|
+
%(entry-title)<a name="sync_task"> Synchronous Task invocation (Invoke task and wait for results) </a>%
|
47
|
+
|
48
|
+
Following snippet will invoke method @some_task@ with argument @data@ in @foo_worker@. Also, method will block
|
49
|
+
until BackgrounDRb server returns a result.
|
50
|
+
|
51
|
+
<pre class="multiline">worker = MiddleMan.worker(:foo_worker)
|
52
|
+
result = worker.some_task(:arg => data) </pre>
|
53
|
+
|
54
|
+
Since, now you are expecting a return value from your worker method, new worker code will look like:
|
55
|
+
|
56
|
+
<pre class="multiline">class FooWorker < BackgrounDRb::MetaWorker
|
57
|
+
set_worker_name :foo_worker
|
58
|
+
def create(args = nil)
|
59
|
+
# this method is called, when worker is loaded for the first time
|
60
|
+
end
|
61
|
+
|
62
|
+
def some_task args
|
63
|
+
billing_result = UserPayment.bill!
|
64
|
+
return billing_result
|
65
|
+
end
|
66
|
+
end
|
67
|
+
</pre>
|
68
|
+
|
69
|
+
As illustrated above, you can use @worker_key@ or make them in single line too.
|
70
|
+
|
71
|
+
%(entry-title)<a name="worker_results"> Retrieve Cached Worker results </a>%
|
72
|
+
|
73
|
+
If you are using @cache@ in your worker code to store result objects, you can retrieve them from
|
74
|
+
rails using:
|
75
|
+
|
76
|
+
<pre class="boxed">status_obj = MiddleMan.worker(:foo_worker).ask_result(cache_key) </pre>
|
77
|
+
|
78
|
+
You must use @worker_key@ if *worker was started with a worker_key*.
|
79
|
+
|
80
|
+
From controller, you can also reset result stored for a particular worker, with particular cache key.
|
81
|
+
This is only applicable, if you are using memcache for storing results.
|
82
|
+
|
83
|
+
<pre class="multiline">
|
84
|
+
MiddleMan.worker(:foo_worker).reset_memcache_result(cache_key) # or
|
85
|
+
MiddleMan.worker(:foo_worker,"worker_key").reset_memcache_result(cache_key)
|
86
|
+
</pre>
|
87
|
+
|
88
|
+
%(entry-title)<a name="persistent_task"> Enqueue task to the persistent job queue : </a>%
|
89
|
+
|
90
|
+
Jobs executed via synchronous and asynchronous APIs are fine, but these tasks are usually
|
91
|
+
kept in memory(and hence they are fast) and hence aren't entirely failsafe.
|
92
|
+
|
93
|
+
To solve this _BackgrounDRb_ also lets you add jobs to a persistent job queue, which is
|
94
|
+
automatically picked by responsible worker and invoked. To use this:
|
95
|
+
|
96
|
+
<pre class="boxed">MiddleMan(:hello_worker).enq_some_task(:arg => "hello_world",:job_key => "boy")</pre>
|
97
|
+
|
98
|
+
With _BackgrounDRb_ version >= 1.1, you can also schedule a persistent task to be executed at a particular time,
|
99
|
+
|
100
|
+
<pre class="multiline">MiddleMan(:hello_worker).enq_some_task(:arg => "hello_world",
|
101
|
+
:job_key => "boy",:scheduled_at => (Time.now + 1.hour))</pre>
|
102
|
+
|
103
|
+
Above line will add specified task to the job queue and set to be invoked at specified time. For more information
|
104
|
+
about scheduling see scheduling section.
|
105
|
+
|
106
|
+
|
107
|
+
%(entry-title)<a name="new_worker"> Start a new worker from controller </a>%
|
108
|
+
|
109
|
+
To start a worker from rails:
|
110
|
+
|
111
|
+
<pre class="multiline">used_job_key = MiddleMan.new_worker(:worker => :foo_worker,\
|
112
|
+
:worker_key => "my_secret_job_key") </pre>
|
113
|
+
|
114
|
+
Worker key passed here, while starting the worker can be used later for invoking tasks on started
|
115
|
+
worker or for accessing cached result objects and stuff like that.
|
116
|
+
|
117
|
+
Important thing to be kept in mind is, when you are creating a worker using above approach, you
|
118
|
+
must use a unique @worker_key@ while starting the worker. Also, while invoking any of the other methods
|
119
|
+
like @ask_result@, @worker_info@ or one of the worker methods, you must user same @worker_key@.
|
120
|
+
|
121
|
+
%(entry-title)<a name="worker_info"> Worker Info </a>%
|
122
|
+
|
123
|
+
You can get worker specific information using:
|
124
|
+
|
125
|
+
<pre class="boxed">MiddleMan.worker(:foo_worker).worker_info </pre>
|
126
|
+
|
127
|
+
The return value will look something like:
|
128
|
+
|
129
|
+
<pre class="boxed">{:worker=>:foo_worker, :status=>:running, :worker_key=>"hello"} </pre>
|
130
|
+
|
131
|
+
Information about all currently running workers can be obtained using:
|
132
|
+
|
133
|
+
<pre class="boxed">MiddleMan.all_worker_info </pre>
|
134
|
+
|
135
|
+
Return value will look like:
|
136
|
+
|
137
|
+
<pre class="multiline">{"0.0.0.0:11006"=>nil, "0.0.0.0:11008"=>
|
138
|
+
[{:worker_key=>"", :status=>:running, :worker=>:log_worker},
|
139
|
+
{:worker_key=>"", :status=>:running, :worker=>:foo_worker}]}</pre>
|
140
|
+
|
141
|
+
%(entry-title)<a name="clustering"> BackgrounDRb Clustering </a>%
|
142
|
+
|
143
|
+
By using following option in your @backgroundrb.yml@ you can cluster more than
|
144
|
+
one backgroundrb server.
|
145
|
+
|
146
|
+
|
147
|
+
<pre class="multiline">:backgroundrb:
|
148
|
+
:ip: 0.0.0.0
|
149
|
+
:port: 11006
|
150
|
+
:environment: production
|
151
|
+
:client: "10.0.0.1:11006,10.0.0.2:11007"</pre>
|
152
|
+
|
153
|
+
|
154
|
+
So what happens here is, now BackgrounDRb client will talk to bdrb
|
155
|
+
servers running on both @10.0.0.1:11006@ and @10.0.0.2:11007@. So when you invoke
|
156
|
+
a task like this:
|
157
|
+
|
158
|
+
<pre class="boxed">MiddleMan.worker(:foo_worker).async_some_task(:arg => data) </pre>
|
159
|
+
|
160
|
+
Your task gets executed in round robin manner in specified servers by default.
|
161
|
+
Also, once a server goes down, it will automatically stop participating in clustering and
|
162
|
+
when it comes back, it will be automatically start participating in clustering.
|
163
|
+
|
164
|
+
|
165
|
+
In addition to default round robin task distribution, you can override this behaviour
|
166
|
+
by passing additional @:host@ option while invoking task from rails.For example:
|
167
|
+
|
168
|
+
|
169
|
+
<pre class="multiline">
|
170
|
+
# run method 'some_task' on all backgroundrb servers
|
171
|
+
MiddleMan.worker(:hello_worker).async_some_task(:arg => data,
|
172
|
+
:job_key => session[:user_id],:host => :all)
|
173
|
+
|
174
|
+
# run method 'some_task' on only locally configured server
|
175
|
+
MiddleMan.worker(:hello_worker).async_some_task(:arg => data,
|
176
|
+
:job_key => session[:user_id],:host => :local)
|
177
|
+
|
178
|
+
# run the task on specified server
|
179
|
+
MiddleMan.worker(:hello_worker).async_some_task(:arg => data,:job_key => \
|
180
|
+
session[:user_id],:host => "10.0.0.2:11210")
|
181
|
+
</pre>
|
182
|
+
</div>
|