sidekiq-job_monitor 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +138 -0
- data/app/assets/javascripts/sidekiq-job_monitor.coffee +9 -6
- data/lib/sidekiq/job_monitor/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b1d3e4b21e888c43304c1353a7cd44d9bd9fb7f
|
4
|
+
data.tar.gz: a4b8740f91c16aeb23fccf94f0c47c980857bb28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3549b4f766d1742c3222f316797c5ba60ac519579beb2b21a05ab752114fce74450ebca64284feeacd5c6d87666fc7415eb9992a016fb88a7a858592f5e22deb
|
7
|
+
data.tar.gz: b7810de4b7c3030f9feff07e38c28bc6ba68daddb2d3d993c819737ee8d3423ac781cc097c1a47fc5ca3f218f93c69a13dd0cd257ea936f0d1b6335c20e98120
|
data/README.md
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
# Sidekiq Job Monitor
|
2
|
+
|
3
|
+
This gem allows you to easily monitor your jobs progression from your client.
|
4
|
+
|
5
|
+
This is often useful when the user has to wait for a specific job to complete
|
6
|
+
to access some produced data.
|
7
|
+
|
8
|
+
The original use case was to allow users to see a "work in progress" modal
|
9
|
+
while a big document was being generated, and then redirect them to download
|
10
|
+
it when the job has completed.
|
11
|
+
|
12
|
+
The gem plugs into Sidekiq's job processor as a middleware to track the
|
13
|
+
job progress and make it available through an JSON endpoint.
|
14
|
+
|
15
|
+
There's also a simple javascript client that allows you to hook into the
|
16
|
+
complete and failed events.
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Add to your Gemfile and `bundle install`:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
gem 'sidekiq-job_monitor'
|
24
|
+
```
|
25
|
+
|
26
|
+
Mount the engine in your routes.rb :
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
mount Sidekiq::JobMonitor::Engine => '/job-monitor', as: :job_monitor
|
30
|
+
```
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
The supported workflow for the gem is the following :
|
35
|
+
|
36
|
+
1. The user requests a document that need time to be processed
|
37
|
+
2. The server enqueues a sidekiq job in high priority queue and returns a waiting message in the form of a modal (for instance)
|
38
|
+
3. The client polls the server to know when the job is done
|
39
|
+
4. When the job is done, the server returns data to the client so that it can take some action to deliver the document
|
40
|
+
|
41
|
+
### 1. Requesting the document
|
42
|
+
|
43
|
+
Add a link to the job starting endpoint as a remote link :
|
44
|
+
|
45
|
+
```erb
|
46
|
+
<%= link_to 'Download report', build_report_path(@report), remote: true, data: { :'job-monitor-link' => true }
|
47
|
+
```
|
48
|
+
|
49
|
+
Initialize the javascript client and make it handle the main events :
|
50
|
+
|
51
|
+
```javascript
|
52
|
+
$(function() {
|
53
|
+
$('[data-job-monitor-link]').each(function(i, el) {
|
54
|
+
$(el).sidekiqJobMonitor({
|
55
|
+
onStart: function($el) {
|
56
|
+
// If you return a modal box from the server, initialize it
|
57
|
+
$el.appendTo('body').modal();
|
58
|
+
// Handle the "complete" event and redirect the user to a target
|
59
|
+
// URL where it will be able to download the document
|
60
|
+
$el.on('complete', function(e, monitor, data) {
|
61
|
+
window.location.href = data.url;
|
62
|
+
});
|
63
|
+
// You can also stop monitoring the progress, for instance when the
|
64
|
+
// modal is closed :
|
65
|
+
$el.on('hide', function() {
|
66
|
+
$el.trigger('stop');
|
67
|
+
});
|
68
|
+
}
|
69
|
+
});
|
70
|
+
});
|
71
|
+
});
|
72
|
+
```
|
73
|
+
|
74
|
+
### 2. The server enqueues a sidekiq job in high priority queue and returns a waiting message
|
75
|
+
|
76
|
+
Enqueue a job with a worker as usual, and store the Job ID in the controller
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
class ReportsController
|
80
|
+
def build
|
81
|
+
@job_id = MyReportWorker.perform_async(params[:id])
|
82
|
+
render layout: false
|
83
|
+
end
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
Render a modal and return the monitoring URL as the main returned node's
|
88
|
+
`[data-monitor-url]` attribute, with the URL returned by `job_monitor.job_progress_path(job_id)` :
|
89
|
+
|
90
|
+
```erb
|
91
|
+
<div class="modal" data-monitor-url="<%= job_monitor.job_progress_path(@job_id) %>">
|
92
|
+
<!-- Snip -->
|
93
|
+
Please wait ...
|
94
|
+
<!-- Snip -->
|
95
|
+
</div>
|
96
|
+
```
|
97
|
+
|
98
|
+
### 3. The client polls the server to know when the job is done
|
99
|
+
|
100
|
+
This part is already covered by the javascript code we wrote in step 1.
|
101
|
+
|
102
|
+
All you need is the correct plugin initialization and returning the
|
103
|
+
`data-monitor-url` attribute on the main returned node.
|
104
|
+
|
105
|
+
### 4. The client polls the server to know when the job is done
|
106
|
+
|
107
|
+
When the job is done, a javascript `complete` event is triggered on the modal.
|
108
|
+
We already handled that in step 1.
|
109
|
+
|
110
|
+
All we need now is to provide the `url` field in the data object returned by
|
111
|
+
the server upon job completion.
|
112
|
+
|
113
|
+
To do so, we add the `#monitoring_data` method to our worker class.
|
114
|
+
This method takes the exact same arguments as the `#perform` method, plus
|
115
|
+
the current job state (pending, processing, complete or failed) as the last
|
116
|
+
argument.
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
class MyReportWorker
|
120
|
+
include Sidekiq::Worker
|
121
|
+
|
122
|
+
def perform(report_id)
|
123
|
+
# Your worker logic here as usual ...
|
124
|
+
end
|
125
|
+
|
126
|
+
def monitoring_data(report_id, state)
|
127
|
+
# Pseudo logic to get the desired URL
|
128
|
+
{ url: Report.find(report_id).document_url } if state == 'complete'
|
129
|
+
end
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
Those fields will be added to the data hash returned by the server as JSON
|
134
|
+
and passed to the `complete` event callback as the last argument.
|
135
|
+
|
136
|
+
## Licence
|
137
|
+
|
138
|
+
This project rocks and uses MIT-LICENSE.
|
@@ -4,9 +4,10 @@ class Sidekiq.JobMonitor
|
|
4
4
|
constructor: (markup, options = {}) ->
|
5
5
|
@$el = $(markup)
|
6
6
|
@monitorURL = @$el.data('monitor-url')
|
7
|
-
|
8
|
-
$('body').trigger('start', [this])
|
7
|
+
@monitor()
|
9
8
|
options.onStart?(@$el)
|
9
|
+
@$el.on('stop', @stopMonitoring)
|
10
|
+
$('body').trigger('start', [this])
|
10
11
|
|
11
12
|
monitorProgress: =>
|
12
13
|
$.getJSON(@monitorURL)
|
@@ -17,7 +18,10 @@ class Sidekiq.JobMonitor
|
|
17
18
|
if data.state is 'complete'
|
18
19
|
@jobComplete(data)
|
19
20
|
else
|
20
|
-
|
21
|
+
@monitor()
|
22
|
+
|
23
|
+
monitor: ->
|
24
|
+
@monitorTimer = setTimeout(@monitorProgress, 1000)
|
21
25
|
|
22
26
|
jobComplete: (data) ->
|
23
27
|
console.log "trigger completion : ", this, data
|
@@ -26,9 +30,8 @@ class Sidekiq.JobMonitor
|
|
26
30
|
jobFailed: =>
|
27
31
|
@$el.trigger('failed', [this])
|
28
32
|
|
29
|
-
|
30
|
-
|
31
|
-
@$el.trigger(eventName, args)
|
33
|
+
stopMonitoring: =>
|
34
|
+
clearTimeout(@monitorTimer) if @monitorTimer
|
32
35
|
|
33
36
|
$.fn.sidekiqJobMonitor = (options = {}) ->
|
34
37
|
@each (i, el) ->
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-job_monitor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- vala
|
@@ -46,6 +46,7 @@ extensions: []
|
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
48
|
- MIT-LICENSE
|
49
|
+
- README.md
|
49
50
|
- Rakefile
|
50
51
|
- app/assets/javascripts/sidekiq-job_monitor.coffee
|
51
52
|
- app/assets/javascripts/sidekiq_job_monitor/application.js
|