backgroundrb-rails3 1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. data/.autotest +17 -0
  2. data/ChangeLog +50 -0
  3. data/Gemfile +11 -0
  4. data/LICENSE +4 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README +22 -0
  7. data/Rakefile +128 -0
  8. data/TODO.org +5 -0
  9. data/app/controller/backgroundrb_status_controller.rb +6 -0
  10. data/backgroundrb-rails3.gemspec +219 -0
  11. data/config/backgroundrb.yml +11 -0
  12. data/doc/Rakefile +5 -0
  13. data/doc/config.yaml +2 -0
  14. data/doc/content/advanced/advanced.txt +76 -0
  15. data/doc/content/advanced/advanced.yaml +4 -0
  16. data/doc/content/bugs/bugs.txt +20 -0
  17. data/doc/content/bugs/bugs.yaml +5 -0
  18. data/doc/content/community/community.txt +36 -0
  19. data/doc/content/community/community.yaml +5 -0
  20. data/doc/content/content.txt +168 -0
  21. data/doc/content/content.yaml +5 -0
  22. data/doc/content/faq/faq.txt +41 -0
  23. data/doc/content/faq/faq.yaml +5 -0
  24. data/doc/content/rails/rails.txt +182 -0
  25. data/doc/content/rails/rails.yaml +5 -0
  26. data/doc/content/scheduling/scheduling.txt +166 -0
  27. data/doc/content/scheduling/scheduling.yaml +5 -0
  28. data/doc/content/workers/workers.txt +178 -0
  29. data/doc/content/workers/workers.yaml +5 -0
  30. data/doc/layouts/default/default.erb +56 -0
  31. data/doc/layouts/default/default.yaml +4 -0
  32. data/doc/lib/default.rb +7 -0
  33. data/doc/output/Assets/BG-Ad-Top.png +0 -0
  34. data/doc/output/Assets/BG-Body.png +0 -0
  35. data/doc/output/Assets/BG-Feed.png +0 -0
  36. data/doc/output/Assets/BG-Menu-Hover.png +0 -0
  37. data/doc/output/Assets/BG-Menu.png +0 -0
  38. data/doc/output/Assets/BG-Sidebar-Bottom.png +0 -0
  39. data/doc/output/Assets/Button-Feed.png +0 -0
  40. data/doc/output/images/bg-ad-top.png +0 -0
  41. data/doc/output/images/bg-body.png +0 -0
  42. data/doc/output/images/bg-feed.gif +0 -0
  43. data/doc/output/images/bg-footer.jpg +0 -0
  44. data/doc/output/images/bg-header.jpg +0 -0
  45. data/doc/output/images/bg-menu-hover.png +0 -0
  46. data/doc/output/images/bg-menu.png +0 -0
  47. data/doc/output/images/bg-sidebar-bottom.gif +0 -0
  48. data/doc/output/images/button-feed.png +0 -0
  49. data/doc/output/images/icon-comment.png +0 -0
  50. data/doc/output/images/more_icon.gif +0 -0
  51. data/doc/output/style.css +299 -0
  52. data/doc/page_defaults.yaml +13 -0
  53. data/doc/tasks/default.rake +3 -0
  54. data/doc/templates/default/default.txt +1 -0
  55. data/doc/templates/default/default.yaml +4 -0
  56. data/examples/backgroundrb.yml +25 -0
  57. data/examples/foo_controller.rb +48 -0
  58. data/examples/god_worker.rb +7 -0
  59. data/examples/worker_tests/god_worker_test.rb +8 -0
  60. data/examples/workers/error_worker.rb +17 -0
  61. data/examples/workers/foo_worker.rb +38 -0
  62. data/examples/workers/god_worker.rb +7 -0
  63. data/examples/workers/model_worker.rb +13 -0
  64. data/examples/workers/renewal_worker.rb +11 -0
  65. data/examples/workers/rss_worker.rb +26 -0
  66. data/examples/workers/server_worker.rb +31 -0
  67. data/examples/workers/world_worker.rb +12 -0
  68. data/examples/workers/xmpp_worker.rb +7 -0
  69. data/init.rb +7 -0
  70. data/install.rb +1 -0
  71. data/know_issues.org +5 -0
  72. data/lib/backgroundrb.rb +1 -0
  73. data/lib/backgroundrb/bdrb_client_helper.rb +8 -0
  74. data/lib/backgroundrb/bdrb_cluster_connection.rb +156 -0
  75. data/lib/backgroundrb/bdrb_config.rb +43 -0
  76. data/lib/backgroundrb/bdrb_conn_error.rb +29 -0
  77. data/lib/backgroundrb/bdrb_connection.rb +179 -0
  78. data/lib/backgroundrb/bdrb_job_queue.rb +79 -0
  79. data/lib/backgroundrb/bdrb_result.rb +19 -0
  80. data/lib/backgroundrb/bdrb_start_stop.rb +146 -0
  81. data/lib/backgroundrb/rails_worker_proxy.rb +181 -0
  82. data/lib/backgroundrb/railtie.rb +48 -0
  83. data/lib/generators/backgroundrb/bdrb_migration/USAGE +12 -0
  84. data/lib/generators/backgroundrb/bdrb_migration/bdrb_migration_generator.rb +15 -0
  85. data/lib/generators/backgroundrb/bdrb_migration/templates/migration.rb +27 -0
  86. data/lib/generators/backgroundrb/worker/USAGE +16 -0
  87. data/lib/generators/backgroundrb/worker/templates/unit_test.rb +12 -0
  88. data/lib/generators/backgroundrb/worker/templates/worker.rb +7 -0
  89. data/lib/generators/backgroundrb/worker/worker_generator.rb +14 -0
  90. data/lib/tasks/backgroundrb_tasks.rake +103 -0
  91. data/release_notes.org +48 -0
  92. data/release_points.org +46 -0
  93. data/script/backgroundrb +52 -0
  94. data/script/bdrb_test_helper.rb +99 -0
  95. data/script/load_worker_env.rb +31 -0
  96. data/script/monitrc +25 -0
  97. data/server/backgroundrb_server.rb +12 -0
  98. data/server/lib/bdrb_result_storage.rb +62 -0
  99. data/server/lib/bdrb_server_helper.rb +24 -0
  100. data/server/lib/bdrb_thread_pool.rb +127 -0
  101. data/server/lib/cron_trigger.rb +197 -0
  102. data/server/lib/invalid_dump_error.rb +4 -0
  103. data/server/lib/log_worker.rb +25 -0
  104. data/server/lib/master_proxy.rb +140 -0
  105. data/server/lib/master_worker.rb +187 -0
  106. data/server/lib/meta_worker.rb +432 -0
  107. data/server/lib/trigger.rb +34 -0
  108. data/test/bdrb_client_test_helper.rb +5 -0
  109. data/test/bdrb_test_helper.rb +35 -0
  110. data/test/client/backgroundrb.yml +17 -0
  111. data/test/client/test_bdrb_client_helper.rb +13 -0
  112. data/test/client/test_bdrb_cluster_connection.rb +162 -0
  113. data/test/client/test_bdrb_config.rb +20 -0
  114. data/test/client/test_bdrb_connection.rb +29 -0
  115. data/test/client/test_bdrb_job_queue.rb +63 -0
  116. data/test/client/test_worker_proxy.rb +130 -0
  117. data/test/server/test_cron_trigger.rb +281 -0
  118. data/test/server/test_master_proxy.rb +54 -0
  119. data/test/server/test_master_worker.rb +157 -0
  120. data/test/server/test_meta_worker.rb +281 -0
  121. data/test/server/test_result_storage.rb +14 -0
  122. data/test/socket_mocker.rb +34 -0
  123. data/test/workers/bar_worker.rb +10 -0
  124. data/test/workers/foo_worker.rb +10 -0
  125. data/uninstall.rb +1 -0
  126. metadata +345 -0
@@ -0,0 +1,11 @@
1
+ ## YAML Template.
2
+ :backgroundrb:
3
+ :ip: 0.0.0.0
4
+ :port: 11006
5
+
6
+ :schedules:
7
+ :foo_worker:
8
+ :worker_method: foobar
9
+ :trigger_args: */5 * * * * * *
10
+
11
+
data/doc/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ Dir['tasks/**/*.rake'].sort.each { |rakefile| load rakefile }
2
+
3
+ task :default do
4
+ puts 'This is an example rake task.'
5
+ end
data/doc/config.yaml ADDED
@@ -0,0 +1,2 @@
1
+ output_dir: "output"
2
+ data_source: "filesystem"
@@ -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,4 @@
1
+ filters_pre: [ "redcloth" ]
2
+ # Custom
3
+ title: "Advanced Stuff"
4
+
@@ -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,5 @@
1
+ # Built-in
2
+ filters_pre: [ "redcloth" ]
3
+ # Custom
4
+ title: "Report Bugs"
5
+ sidebar_items: [["Trac", "#trac"], ["KnownBugs", "#known_bugs"]]
@@ -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,5 @@
1
+ # Built-in
2
+ filters_pre: [ "redcloth" ]
3
+ # Custom
4
+ title: "Join the BackgrounDRb Community"
5
+ sidebar_items: [["People", "people"], ["MailingList", "#mailing_list"], ["IRC", "#irc"], ["Contribute", "#contribute"]]
@@ -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,5 @@
1
+ # Built-in
2
+ filters_pre: [ "redcloth" ]
3
+ # Custom
4
+ title: "Introduction BackgrounDRb"
5
+ sidebar_items: [["Introduction", "#introduction"], ["Installation", "#installation"], ["Configuration", "#configuration"], ["Workers", "#create_worker"]]
@@ -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,5 @@
1
+ # Built-in
2
+ filters_pre: [ "redcloth" ]
3
+ # Custom
4
+ title: "FAQs"
5
+ sidebar_items: [["Trac", "#trac"], ["KnownBugs", "#known_bugs"]]
@@ -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>