active_job_channel 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +65 -32
- data/Rakefile +4 -6
- data/lib/active_job_channel/broadcaster.rb +52 -8
- data/lib/active_job_channel/channel.rb +14 -1
- data/lib/active_job_channel/engine.rb +2 -0
- data/lib/active_job_channel/version.rb +1 -1
- data/spec/dummy/app/assets/javascripts/application.js +1 -1
- data/spec/dummy/app/channels/application_cable/connection.rb +9 -0
- data/spec/dummy/app/controllers/front_controller.rb +1 -1
- data/spec/dummy/app/jobs/application_job.rb +3 -2
- data/spec/dummy/app/views/front/index.html.erb +0 -0
- data/spec/dummy/log/development.log +2351 -0
- data/spec/dummy/log/test.log +489 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/0t/0tejrFqWXI50Nk5h03pKrzRRTpSa9CD2-MmcGjC1dZI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/1T/1TTJ3TY7wBXzhvS0Tnk62v2jrjPoVI7pSQGHJJVYyvs.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/1w/1Wuwk1dBK3NQDz_c55vIsHRazPSL0j3A9TsporFDnXc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/2L/2LPxIl3YMznuR8K3qWClBN7cYkrPKOVMkT_RQktzDa0.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/2c/2cdVaBRkw1fktXRADGAFVl6IXiKE0zRrfq9E8BdpkoE.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/2j/2jsBEFjxpI9mgoh9KnIwUyIbc79e6KGAP7Eg_o917tY.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3h/3He84eXCmvSIkgIN9Lwua6gBtl-IT-OInwD14ALNux4.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3l/3lI7QHJYJ-cFmLwHYDucw9MU813-JaOBjoNRZ5tknjA.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3v/3vCIBAd9ejRDHSdlE95q_OM_CIqmAO45TJHKnk_G-ps.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4r/4r-50M4p_5L3R45mEoON7TLkD8HZdA66BheutvIEk_Q.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/59/59gq16Ydq4pK_fqn2PQthAB7yPTLtlZYAB5F7vHki4g.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/59/59vvsILoKoFeWiuplQOdlUk89oC_77WcQ0p5ledvTiE.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/5s/5sR7_TAwQKd_Jr6J0s5V74RGPIgbR-9S9y0bOjPIAfk.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/6E/6eW6n154upbD0wIld8-torTQfQQdHcpAQVPCmTkO-Ms.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/6K/6kejUHzcbzTmAW8AM3HXjgEd3DgvPpHRCAsJy8V8a8w.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/6P/6p9TzLwDjZbYc1kmw6l1JEIN-q6Ro9d7VJx7iY-UO40.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/6a/6ahukXUYrbt30MCkbkfla3JlrLkO5Cv5FmOFYvxZpTs.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/6t/6ty212kvMsWZsxC1nyjugItdSlbM3bP-L7EE-0oRcbg.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7a/7aIyAED7jZHA_p7ZqToxx2O1F5sqcYIgFXLoZWEMWVE.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8h/8hlDlNMesbnOsyljy8ciU1R45hAp7BOyebqCe_Dmy_Y.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8j/8jAuYQzZIhRKZxHVubNbhlU1WQnD8fI60PqmG69Da7Q.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8w/8w9YqUUADUiny_kog6ZTLNlY5Ia8ywmVInNmI45-bLk.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/9B/9BlzJuWy7Qc5Qufw2B01zF_Cq71nkZfG-9rmgwCtKOM.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/9a/9aE7wF6_y4j98FycX155lKpJAQxPqysXQqBel9xXKdQ.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/A4/A4N4KZTnvHrZo5cpyYUminUKO82ucW4G1HTPzXYCDnU.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AH/AHOUi3TIgivdm9HG3l_6Ms9TDg2ZH8HhUN9DflFPT_Q.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ar/ArkKH805v2j4YvEK_fJ20wzvt92hlEyLQt9l_MPyCYI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/B0/B0YM5EsqVpuXiSFZvaaWTLDm-KsL8L0WGMaFquRdGMA.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/BE/BEnAsncgltZzyd5iczHx5EI9-dS3dETH55TiSuiGGZY.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/BO/BOjcf8tuEvpDlQt2vpb7SjXoezM9fUc-pW76Iub5bD8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/BS/BSY4TP5wBI4XcYCAes1TUcJQ20USCBrvjPVOHx1zvOY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/BY/BY_FLwd7Tbcf3ABQuWlJZOB87K0BVWtJaJwEf6TJBxw.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/C7/c7_j9vpOp9_1Sn7xKAHvWVImMLb1slk94ICEkURiZ04.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Fm/fmsz2sflSkcF4bILqyaSU93RnxNYSU9JUKtO5lOM2_4.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/HH/HHkyK2aHiljUNkNNQSH6y3f7XX-5BeuCv0Kxfs27J2w.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Hd/HdRTrM_GRYHyBl9OMca3EB5UDvWbnmZJt3tPn4ltZ3Q.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Km/KmyH84dp9P6zgt6Up2IGn1jBH7e2eoDAKlNqbB7ZI1w.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/LE/Le2izv3CUcPoFgzJNPKebBh4mx3tsAbqfziAcM--0Jc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/MB/mBni0KSvr3gZ9hy31uEB8y-cxFVfMYletrPUbEevpBo.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/MX/MXoiOs93U88XCQkqYZKUjQRw6FMZblU5tSDPB7uLBpU.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Mp/Mpb9smslW1sntnjWAo0Jj8p48SaTZvrmaXtn0jhJuoY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/QI/QI1z63uCSktHwJUcpH6NJVElFZuT_9pB_OlD5HodGj4.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Qd/QdoaSQXuW_lEPqzgbsM2vvL_OnxqiLolqXXavy0cbHU.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Qj/Qju3ME6idrmJvEDULzK9Ga-yB3vb3uit61o7d8U4pxY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Qv/QvNzvJ0z2f0g6T68rMYY0mBHvDEY4b6y51ig7FBGnhc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/RT/RToGI6FYOn83Ol7mQkO7rXU9junxziC8SD9blspQHvI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Rh/Rh85ei2qt1M3nUMP4DSJ_ReSlWH-fKVvdM38WMexziE.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/S6/S6c4svFhyIwvn-E9psdhX9o3J6LrGO90i0yjhjVGLCc.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/SZ/sZ37jm0vG8qR7mVLa0ESUv_9aIj1htK75GY3SSH8lJE.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/T0/T0589roQFbIQ46mHgBS6Io8dkK0kB9V37_bd9qvz93E.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/TD/TDZKALyUNeJcvFiBwpqswmFh80HmV5_BOZwHEcqUEns.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/UA/Uai8hEmMi8rbYvYI8JThbWEnHzGMBoG6H-BctClUimI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/V6/V6FcA646DCNVnSE9Nu3fXKQo9Q2J2WRt8dT1_4maork.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/VJ/VJESfxh6YudYFQX7sMTuhouFREwsvuH26MK9VzGRbFk.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/X8/X88B6qT5FPk5lkChVEuX-NrygcrY6yEWrlkoQn3pydk.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ZL/ZLZ8FZv8d7C_dOlCVAymsTsXpgKcDOqSW4Buwznp-P0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/aC/aCQFgafIBdW4sAbl3zP2eIXomYtcAjsxtP-axKLfjsI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/aN/ANg46pcHZWfKw7-6-xO7KUf3pIVG4X-K8cxbNz3TA_U.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/aS/ASl4pPHP0cI1fbKThnKW7tHiljs9BPghL1cH5TRd1NM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/at/atJ-zc9WEL1sfZIPwn5VKyOE1Xj1Elcb_SfFCv6X-2g.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cf/cfx8zJt2SKc6mq2Y7LWAfLksfWfvmj3n3y79lBivTOA.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/dC/DcYBsE96__IImw5qMnEw-gsUknWyL-5AXtAmEA9kJao.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/dJ/dJcI-obDHqGKKaoueMqxT2LHukjWmkZWAGrolNDZmtE.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/eo/eomwhFjYfscOWWCOx36ll25vcnbvDsGjSCi-lGxU5es.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fS/fSint2O7kkrERf0lOcWnc3OfYEA0C_SNKUn-ePwzi7g.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gg/ggCbDjYcMGY7XG7WjxWpXBxtQcHupXe5IvK-rd2ihzE.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/hU/hUioZNvWcr7KgF6nZq2TMjWJpGoe6f8t-yCJjpDYzWY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/hX/hXp80was0drGYRYoN1t7BgDsGHc6gWBGnpcIiT-vp04.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/iI/IifRBP1kh7hYmQ-pKBYjgJlrCQPyF3SQzToIc7Ib7Bc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jO/jONWUKSndBxDtySWgfbmWbz2a6PZv3NokqUwyuaYhV8.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jQ/JQCL-XQumSUnU_FWWDnZMQhNft5eHNtpbwJwmr4NRx0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/j_/j_6qhjBV6XZ21Ec2MQr364UZFIqLFY1gOmvs1pg8oNE.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jl/jlX-dbDS-3GwaRefW6WKQOpxuq3_AZ_0JYDdrVp_-CA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ka/kaaPoa_lbFCq3fCc-w1lZlOKNLoSxRmlg86adlemgOY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/kh/KhlvIiIT2SwuhVL_8T_eMNwngN3cr6chsyVu_tcSYSo.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m1/m1eqvANKO4Xm8wU5I2uzQ-wJJ2cl3V6gwSc_cgSomgs.cache +2 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/mJ/mJOrgB3Dd9IMbnn9DBOF-HA25ZsEUNP9cRFP80n9pIc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/n_/n_xYqQYhwEMQknb3jFQnjlxxBE9TzMNHCdJ-bEyZFIw.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/nx/nxTv3sKVUQZADJyM3dPaVmUA78MIsMLD_K279yN_GsI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/of/ofn6dcEb4U1pVYywTAYMKSY73DmtQHt4yvICGJybvNA.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oy/OYSsdyEPkUTpuee4CHcJ3iI1ghXD_GnIKCOphpFl2Qc.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pV/PvxGgTLpBrfhgIkEVinMbpHRoHZdZSmAWxHz11iW_Jw.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/qF/QfaMLhxgXWtXUVFrL2WY2_05lAXMj-AJB6SPkY7TonM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/qP/qPmv5snMrDw830S6hSICDcnIy7kVEWoFKXhGKT38lG4.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/qo/QOrltHJWzwDAoiEmwirDLJoNrye18oZdXZlOO2jqRAA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sh/shOFa_chENx_8ZRXPbkq_ENgRJWo93wDCtBNf785Pf4.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/t9/t9tHOHjkct3cOW0zvjpzyFwhtqbNCoCD7-1jlEOUAuE.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/tM/tMQLE8jDSktbBK8uvyxHDupucBBJbOd1mgm7Krwjvr4.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ta/taVz5vyapnXqxTrIk1HqFwqmlZpzBRAVoZ0YbQaKSYg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/tj/tjR80-67cxOLvwYRkfETCNmP0_tEIpv8E2bA-3VNQJ0.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ty/tyY1gR1OJrgsKgAAi71a-iULjg3sNO6w64GdrY5FwRY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/vt/vtKkabQbVjJocImgz6J_pG6mykSy1Oavu3AVzeG4o4k.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wC/WCVq1-ri3g7K1RPaGXIxmb5RtGRaOaOURAvqVG4zNdk.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/y3/y3lnguc4mqfDo_4Yovado1gkGRML6dhGMmQUjiXoOZM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/y9/y9m2TDwskcclVVOGMioQd1_gSx2n69HPQLxQI_OvrNQ.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/yC/yCekKqDJnr2rziXNXI99RG9RlU_7TV2PoH03KObhWtU.cache +0 -0
- data/spec/jobs/application_job_spec.rb +6 -6
- data/spec/spec_helper.rb +1 -1
- metadata +190 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '058d0b861b22420aa23b79986d3d73bb01cbe27d7279ef706382edb7a4d47ba5'
|
4
|
+
data.tar.gz: 79aaf5fbd4416e22a93c9a14353ef41c7d6965d58670d4815e3af6f86b88f726
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f12183f81a90854fb76a584d93b96ef6e656f41b4ff0926ef6a242b275b14fe3e6172abd830264ee425732016fafc4b448476b3b32ba15d76f4f7c900b8ea96
|
7
|
+
data.tar.gz: b5e178a2ed8ac074fd4350d9f884373e142aa0ea73712570e3e10d86efc196f70eb4b083d604e78d8a4aec277b844d91bdb8aa2217634ed8274ff49813416bd0
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# ActiveJobChannel
|
2
|
+
Use ActionCable to alert front-end users of finished ActiveJobs
|
3
3
|
|
4
4
|
## Installation
|
5
5
|
1. Install in your Gemfile
|
@@ -8,15 +8,60 @@ Uses `ActionCable` to alert front-end users of finished `ActiveJobs`
|
|
8
8
|
gem 'active_job_channel'
|
9
9
|
```
|
10
10
|
|
11
|
-
|
11
|
+
## Setup
|
12
|
+
1. [Create ActionCable Connection](#create-actioncable-connection-optional) (optional)
|
13
|
+
2. [Enable ActiveJobChannel for a job](#enable-activejobchannel-for-a-job)
|
14
|
+
3. [Handle ActiveJobChannel broadcasts](#handle-activejobchannel-broadcasts)
|
15
|
+
|
16
|
+
### Create ActionCable Connection (optional)
|
17
|
+
|
18
|
+
You can skip this step if you're not concerned with authorizing or brodcasting
|
19
|
+
privately to ActionCable connections
|
20
|
+
|
21
|
+
1. Setup an [ActionCable subscription adapter](http://edgeguides.rubyonrails.org/action_cable_overview.html#subscription-adapter)
|
12
22
|
* Note: A persisted subscription adapter is required for handling notifications
|
13
|
-
from background
|
23
|
+
from background ActiveJob processes. Currently only PostgreSQL and Redis
|
14
24
|
are supported.
|
25
|
+
2. Follow the [official guide for setting up an ActionCable Connection](http://guides.rubyonrails.org/action_cable_overview.html#server-side-components-connections)
|
26
|
+
3. If you would like notifications broadcast privately to ActionCable
|
27
|
+
connections, set up a connection identifier for your connection using
|
28
|
+
`identified_by`. The identifier you use will also need to be passed to your
|
29
|
+
job.
|
30
|
+
|
31
|
+
### Enable ActiveJobChannel for a job
|
32
|
+
1. For each job you'd like to be notified about, call `active_job_channel` in
|
33
|
+
its class
|
34
|
+
2. To broadcast notifications privately, set the identifier you configured in
|
35
|
+
your ActionCable Connection setup to either the instance variable
|
36
|
+
`@ajc_identifier` or the method `ajc_identifier`
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
class MyJob < ActiveJob::Base
|
40
|
+
active_job_channel
|
41
|
+
|
42
|
+
def perform(current_user)
|
43
|
+
@ajc_identifier = current_user
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# def ajc_identifier
|
49
|
+
# User.find_by(key: value)
|
50
|
+
# end
|
51
|
+
end
|
52
|
+
```
|
15
53
|
|
16
|
-
|
17
|
-
`ApplicationCable::Connection`](http://guides.rubyonrails.org/action_cable_overview.html#server-side-components-connections)
|
54
|
+
#### Configuration
|
18
55
|
|
19
|
-
|
56
|
+
##### global_broadcast
|
57
|
+
|
58
|
+
Notifications will be broadcast to `ajc_identifier` by default. To broadcast
|
59
|
+
all notifications for a job to all ActionCable connections, pass
|
60
|
+
`{ global_broadcast: true }` to `active_job_channel`.
|
61
|
+
|
62
|
+
### Handle ActiveJobChannel broadcasts
|
63
|
+
|
64
|
+
1. Include `active_job_channel.js` in your layouts
|
20
65
|
|
21
66
|
```ruby
|
22
67
|
javascript_include_tag 'active_job_channel'
|
@@ -28,40 +73,28 @@ Uses `ActionCable` to alert front-end users of finished `ActiveJobs`
|
|
28
73
|
//= require active_job_channel
|
29
74
|
```
|
30
75
|
|
31
|
-
|
32
|
-
For each job you'd like to be notified about, enable `active_job_channel`
|
76
|
+
2. Customize the callbacks for broadcasted notifications:
|
33
77
|
|
34
|
-
```
|
35
|
-
|
36
|
-
active_job_channel
|
37
|
-
end
|
38
|
-
```
|
78
|
+
```javascript
|
79
|
+
//= require notifyjs
|
39
80
|
|
40
|
-
|
41
|
-
|
42
|
-
|
81
|
+
ActiveJobChannel.onJobSuccess = function(job) { $.notify(job.name + ' succeeded!') };
|
82
|
+
ActiveJobChannel.onJobFailure = function(job) { $.notify(job.name + ' failed!') };
|
83
|
+
```
|
43
84
|
|
44
|
-
|
45
|
-
|
46
|
-
//= require active_job_channel
|
85
|
+
`job` has the attributes `name` and `status`. A failed `job` includes an
|
86
|
+
`error` attribute. `status` is one of `success` or `failure`.
|
47
87
|
|
48
|
-
ActiveJobChannel.received = function(data) {
|
49
|
-
var status = data.status;
|
50
|
-
var job_name = data.job_name;
|
51
|
-
if (status === 'success') { $.notify(job_name + ' succeeded!') }
|
52
|
-
else if (status === 'failure') { $.notify(job_name + ' failed!') }
|
53
|
-
}
|
54
|
-
```
|
55
88
|
|
56
89
|
## Caveats
|
57
|
-
|
90
|
+
ActiveJobChannel depends on ActiveJob and ActionCable, and, as such, is
|
58
91
|
subject to their limitations:
|
59
92
|
|
60
93
|
* A persisted [subscription adapter](http://guides.rubyonrails.org/action_cable_overview.html#subscription-adapter)
|
61
|
-
is required for
|
62
|
-
|
63
|
-
* Because
|
64
|
-
|
94
|
+
is required for ActionCable to handle notifications from background
|
95
|
+
ActiveJob processes
|
96
|
+
* Because ActiveJob does not know when a job has permanently failed,
|
97
|
+
ActiveJobChannel sends notfications for each failure, retried or final
|
65
98
|
|
66
99
|
## Todo
|
67
100
|
- Better default front-end notification behavior
|
data/Rakefile
CHANGED
@@ -1,22 +1,20 @@
|
|
1
|
-
#!/usr/bin/env rake
|
2
|
-
|
3
1
|
begin
|
4
2
|
require 'bundler/setup'
|
5
3
|
rescue LoadError
|
6
4
|
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
5
|
end
|
8
6
|
|
9
|
-
APP_RAKEFILE = File.expand_path(
|
7
|
+
APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
|
10
8
|
load 'rails/tasks/engine.rake'
|
11
9
|
|
12
10
|
Bundler::GemHelper.install_tasks
|
13
11
|
|
14
|
-
Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
|
12
|
+
Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each { |f| load f }
|
15
13
|
|
16
14
|
require 'rspec/core'
|
17
15
|
require 'rspec/core/rake_task'
|
18
16
|
|
19
17
|
desc 'Run all specs in spec directory (excluding plugin specs)'
|
20
|
-
RSpec::Core::RakeTask.new(:spec
|
18
|
+
RSpec::Core::RakeTask.new(:spec)
|
21
19
|
|
22
|
-
task :
|
20
|
+
task default: :spec
|
@@ -1,10 +1,30 @@
|
|
1
1
|
module ActiveJobChannel
|
2
2
|
module Broadcaster
|
3
|
+
class NoIdentifierError < NameError
|
4
|
+
MESSAGE = 'ActiveJobChannel expects an ActionCable Connection ' \
|
5
|
+
'identifier to broadcast to. The identifier should be made available ' \
|
6
|
+
'in your job via a method or an instance variable, either named ' \
|
7
|
+
'`ajc_identifier`. For details about setting up an identifier in ' \
|
8
|
+
'your ActionCable Connection, visit http://guides.rubyonrails.org/' \
|
9
|
+
"action_cable_overview.html#connection-setup\n\nTo broadcast " \
|
10
|
+
'globally without an identifier, pass in ' \
|
11
|
+
'`{ global_broadcast: true } ` to `active_job_channel` as part of an ' \
|
12
|
+
'options hash.'.freeze
|
13
|
+
|
14
|
+
def initialize(msg = MESSAGE)
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
3
19
|
module ClassMethods
|
4
|
-
def active_job_channel
|
20
|
+
def active_job_channel(options = {})
|
21
|
+
class_attribute :ajc_config
|
22
|
+
self.ajc_config = { global_broadcast: false }
|
23
|
+
self.ajc_config.merge!(options)
|
24
|
+
|
5
25
|
after_perform :broadcast_success
|
6
26
|
rescue_from '::StandardError' do |exception|
|
7
|
-
broadcast_failure
|
27
|
+
broadcast_failure(exception)
|
8
28
|
raise exception
|
9
29
|
end
|
10
30
|
|
@@ -13,17 +33,41 @@ module ActiveJobChannel
|
|
13
33
|
end
|
14
34
|
|
15
35
|
module InstanceMethods
|
16
|
-
|
17
|
-
|
18
|
-
|
36
|
+
private
|
37
|
+
|
38
|
+
attr_writer :ajc_identifier
|
39
|
+
|
40
|
+
def ajc_channel_name
|
41
|
+
if ajc_config[:global_broadcast]
|
42
|
+
::ActiveJobChannel::Channel::CHANNEL_NAME
|
43
|
+
else
|
44
|
+
[::ActiveJobChannel::Channel::CHANNEL_NAME, ajc_identifier].
|
45
|
+
compact.
|
46
|
+
join('#')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def ajc_identifier
|
51
|
+
raise NoIdentifierError if ajc_identifier_missing?
|
52
|
+
@ajc_identifier
|
53
|
+
end
|
54
|
+
|
55
|
+
def ajc_identifier_missing?
|
56
|
+
!ajc_config[:global_broadcast] && @ajc_identifier.nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
def broadcast_failure(exception)
|
60
|
+
ActionCable.server.broadcast(
|
61
|
+
ajc_channel_name,
|
19
62
|
status: 'failure',
|
20
|
-
job_name: self.class.to_s
|
63
|
+
job_name: self.class.to_s,
|
64
|
+
error: exception.inspect
|
21
65
|
)
|
22
66
|
end
|
23
67
|
|
24
68
|
def broadcast_success
|
25
|
-
|
26
|
-
|
69
|
+
ActionCable.server.broadcast(
|
70
|
+
ajc_channel_name,
|
27
71
|
status: 'success',
|
28
72
|
job_name: self.class.to_s
|
29
73
|
)
|
@@ -1,7 +1,20 @@
|
|
1
1
|
module ActiveJobChannel
|
2
2
|
class Channel < ::ActionCable::Channel::Base
|
3
|
+
CHANNEL_NAME = 'active_job_channel'.freeze
|
4
|
+
|
3
5
|
def subscribed
|
4
|
-
stream_from
|
6
|
+
stream_from CHANNEL_NAME
|
7
|
+
stream_from private_stream if connection.connection_identifier.present?
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def global_stream
|
13
|
+
stream_from CHANNEL_NAME
|
14
|
+
end
|
15
|
+
|
16
|
+
def private_stream
|
17
|
+
[CHANNEL_NAME, connection.connection_identifier].join('#')
|
5
18
|
end
|
6
19
|
end
|
7
20
|
end
|
File without changes
|