active_waiter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +93 -0
  4. data/Rakefile +1 -0
  5. data/app/assets/javascripts/active_waiter/application.js +16 -0
  6. data/app/assets/stylesheets/active_waiter/application.css +15 -0
  7. data/app/controllers/active_waiter/application_controller.rb +4 -0
  8. data/app/controllers/active_waiter/jobs_controller.rb +36 -0
  9. data/app/helpers/active_waiter/application_helper.rb +4 -0
  10. data/app/views/active_waiter/jobs/_reload.html.erb +3 -0
  11. data/app/views/active_waiter/jobs/error.html.erb +6 -0
  12. data/app/views/active_waiter/jobs/link_to.html.erb +12 -0
  13. data/app/views/active_waiter/jobs/progress.html.erb +6 -0
  14. data/app/views/active_waiter/jobs/show.html.erb +6 -0
  15. data/app/views/layouts/active_waiter/application.html.erb +24 -0
  16. data/config/routes.rb +4 -0
  17. data/lib/active_waiter.rb +25 -0
  18. data/lib/active_waiter/engine.rb +5 -0
  19. data/lib/active_waiter/job.rb +28 -0
  20. data/lib/active_waiter/version.rb +3 -0
  21. data/lib/tasks/waiter_tasks.rake +4 -0
  22. data/test/active_waiter/job_test.rb +40 -0
  23. data/test/controllers/active_waiter/jobs_controller_test.rb +87 -0
  24. data/test/dummy/README.rdoc +28 -0
  25. data/test/dummy/Rakefile +6 -0
  26. data/test/dummy/app/assets/javascripts/application.js +13 -0
  27. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  28. data/test/dummy/app/controllers/application_controller.rb +5 -0
  29. data/test/dummy/app/helpers/application_helper.rb +2 -0
  30. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  31. data/test/dummy/bin/bundle +3 -0
  32. data/test/dummy/bin/rails +4 -0
  33. data/test/dummy/bin/rake +4 -0
  34. data/test/dummy/bin/setup +29 -0
  35. data/test/dummy/config.ru +4 -0
  36. data/test/dummy/config/application.rb +31 -0
  37. data/test/dummy/config/boot.rb +5 -0
  38. data/test/dummy/config/environment.rb +5 -0
  39. data/test/dummy/config/environments/development.rb +41 -0
  40. data/test/dummy/config/environments/production.rb +79 -0
  41. data/test/dummy/config/environments/test.rb +44 -0
  42. data/test/dummy/config/initializers/assets.rb +11 -0
  43. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  44. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  45. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  46. data/test/dummy/config/initializers/inflections.rb +16 -0
  47. data/test/dummy/config/initializers/mime_types.rb +4 -0
  48. data/test/dummy/config/initializers/session_store.rb +3 -0
  49. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  50. data/test/dummy/config/locales/en.yml +23 -0
  51. data/test/dummy/config/routes.rb +4 -0
  52. data/test/dummy/config/secrets.yml +22 -0
  53. data/test/dummy/log/test.log +6847 -0
  54. data/test/dummy/public/404.html +67 -0
  55. data/test/dummy/public/422.html +67 -0
  56. data/test/dummy/public/500.html +66 -0
  57. data/test/dummy/public/favicon.ico +0 -0
  58. data/test/dummy/tmp/cache/53A/930/waiter%3Ahello +1 -0
  59. data/test/dummy/tmp/cache/54D/5C0/result%3Ahello +1 -0
  60. data/test/dummy/tmp/cache/623/7D0/progress%3Ahello +1 -0
  61. data/test/dummy/tmp/cache/815/000/active_waiter%3Ahello +2 -0
  62. data/test/dummy/tmp/cache/BC3/BB0/result%3A5476b414-8387-40bf-ae81-16f86a204581 +1 -0
  63. data/test/dummy/tmp/cache/BC6/630/result%3Adb3970e5-755d-4810-b660-d0b236826957 +1 -0
  64. data/test/dummy/tmp/cache/C32/BF0/result%3Af72e8b8d-512c-4819-a041-44877487cd7e +1 -0
  65. data/test/dummy/tmp/cache/C54/560/result%3Aa9598b7d-67f5-4253-a0c4-2035e567b4bc +1 -0
  66. data/test/dummy/tmp/cache/C61/C50/result%3A976614ea-ea80-4087-b8cc-e5f73f776503 +1 -0
  67. data/test/dummy/tmp/cache/C62/DE0/result%3A50288cd0-9cf2-4c5b-96b9-0458cf56e548 +1 -0
  68. data/test/dummy/tmp/cache/C74/C10/result%3Ae5bb8515-3939-4ef4-968b-a7f7d9d79273 +1 -0
  69. data/test/dummy/tmp/cache/C87/CE0/result%3A4af5f188-795f-476e-acbf-51208e17f030 +1 -0
  70. data/test/dummy/tmp/cache/C99/C60/progress%3A5476b414-8387-40bf-ae81-16f86a204581 +1 -0
  71. data/test/dummy/tmp/cache/C9C/6E0/progress%3Adb3970e5-755d-4810-b660-d0b236826957 +1 -0
  72. data/test/dummy/tmp/cache/CAE/6D0/result%3Abd42513f-7484-4dac-a91f-e00e398fd811 +1 -0
  73. data/test/dummy/tmp/cache/CB3/BF0/result%3Afda8e964-d054-48d8-8c0c-100d5736ae6b +1 -0
  74. data/test/dummy/tmp/cache/CB9/930/result%3A55536147-f9cd-42ba-8df2-f1b62f6af737 +1 -0
  75. data/test/dummy/tmp/cache/CC0/260/result%3A16ff29ac-f5ad-4397-a60f-64ae9917d573 +1 -0
  76. data/test/dummy/tmp/cache/CE4/110/result%3A35ee268a-c31f-4f47-87ee-cc1fa8622e13 +1 -0
  77. data/test/dummy/tmp/cache/D08/CA0/progress%3Af72e8b8d-512c-4819-a041-44877487cd7e +1 -0
  78. data/test/dummy/tmp/cache/D2A/610/progress%3Aa9598b7d-67f5-4253-a0c4-2035e567b4bc +1 -0
  79. data/test/dummy/tmp/cache/D2B/DC0/result%3Ad20d41eb-75cf-4bc0-b338-eb14e6e0e3d2 +1 -0
  80. data/test/dummy/tmp/cache/D33/5A0/result%3A16b07abb-16b1-4e4d-92b9-3dfd8bda18e2 +1 -0
  81. data/test/dummy/tmp/cache/D37/D00/progress%3A976614ea-ea80-4087-b8cc-e5f73f776503 +1 -0
  82. data/test/dummy/tmp/cache/D38/E90/progress%3A50288cd0-9cf2-4c5b-96b9-0458cf56e548 +1 -0
  83. data/test/dummy/tmp/cache/D4A/CC0/progress%3Ae5bb8515-3939-4ef4-968b-a7f7d9d79273 +1 -0
  84. data/test/dummy/tmp/cache/D5D/D90/progress%3A4af5f188-795f-476e-acbf-51208e17f030 +1 -0
  85. data/test/dummy/tmp/cache/D6C/2A0/result%3Afc8752e1-ead1-433f-af5c-f5c86cd2b1e3 +1 -0
  86. data/test/dummy/tmp/cache/D74/9E0/result%3A91eb5c23-5fc6-4c4f-a183-ccb1edeee859 +1 -0
  87. data/test/dummy/tmp/cache/D84/780/progress%3Abd42513f-7484-4dac-a91f-e00e398fd811 +1 -0
  88. data/test/dummy/tmp/cache/D89/CA0/progress%3Afda8e964-d054-48d8-8c0c-100d5736ae6b +1 -0
  89. data/test/dummy/tmp/cache/D8F/9E0/progress%3A55536147-f9cd-42ba-8df2-f1b62f6af737 +1 -0
  90. data/test/dummy/tmp/cache/D96/310/progress%3A16ff29ac-f5ad-4397-a60f-64ae9917d573 +1 -0
  91. data/test/dummy/tmp/cache/DBA/1C0/progress%3A35ee268a-c31f-4f47-87ee-cc1fa8622e13 +1 -0
  92. data/test/dummy/tmp/cache/E01/E70/progress%3Ad20d41eb-75cf-4bc0-b338-eb14e6e0e3d2 +1 -0
  93. data/test/dummy/tmp/cache/E09/650/progress%3A16b07abb-16b1-4e4d-92b9-3dfd8bda18e2 +1 -0
  94. data/test/dummy/tmp/cache/E42/350/progress%3Afc8752e1-ead1-433f-af5c-f5c86cd2b1e3 +1 -0
  95. data/test/dummy/tmp/cache/E4A/A90/progress%3A91eb5c23-5fc6-4c4f-a183-ccb1edeee859 +1 -0
  96. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/-FKgYemgnLPloA8L9_uc-qSP9Csz8KJeFy9-9tNbTYE.cache +0 -0
  97. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/-htuxusII34GUEa1Y1dhHlPMREKFFP0I9an-0fPai1Y.cache +1 -0
  98. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/0Lwyq9p8qx-NPHj2mBzAXHqSLjbAHDtNbuEcaVsLptI.cache +1 -0
  99. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/0e8ZJThcO34GZamk_QI5PgGHebcQ_Pg-lz0uqaXHT4E.cache +1 -0
  100. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/12TsG6XcaV1lKbmxnQVLDp8rypRI35yC0kFTDEj-sBs.cache +0 -0
  101. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/1JbLVPcYaKgFjstM5eOonLAWxk_zH78g94H5Y_zoHaY.cache +0 -0
  102. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/1eZUUEinxr0XtcAQd2B4BuriiH8qNhiC0CttyzvyRCY.cache +2 -0
  103. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/1i1op13Ae3Pv4k56iSw0YYG1lOQbc3XOBK3M_74-INY.cache +0 -0
  104. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/1k7k_fcUk4-GoIHaNQHejiRVZl-Pnd7vFXtQSTJGOho.cache +1 -0
  105. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/29tZrgfzuQRuwLaDKo1dFqObg71vcVS6kAK_QUP-MRE.cache +0 -0
  106. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/2KG4HBSny8fUdnEqQVLHtl23H1QLtJLhqxrHD340nrc.cache +0 -0
  107. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/2LUFqOewM3gnSHBnnPjlZCvuLOt2pIESv58AQV__tFo.cache +0 -0
  108. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/35hQ1jprgNu7eqmxxZIEldbtZXA7SK8F4B0jgYHdl-Q.cache +0 -0
  109. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/4EbIxUrr6TrMPFW6Oo6PAq9UGP8F6FTQQCLXXdoSC7A.cache +1 -0
  110. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/4rba5VAhpWBaRrigVIoX3CMVH_mr5S0J1HOhSA1fDQA.cache +1 -0
  111. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/5GH1Olvcwf17EORgb5bg_80CxlVWqdDw0dLCIdDsWgk.cache +2 -0
  112. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/5kF0rdn73jq7uGVfOkWCPEBcG4ZuxVlPySU7dGvT9PI.cache +0 -0
  113. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/6Yn3BKylqtbKOzQ9C4PQ5zE0ZhFna75Q4nQv2y0UpgQ.cache +2 -0
  114. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/7AuLNboANu8sU933nvR-LmFqEaIA2TE6qgVWDl7MfOU.cache +0 -0
  115. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/ASrpInr95Fmk3jRbvXIv6pt3614NTBV0qzwJZ9ccyII.cache +0 -0
  116. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/B42UCwrGRs5FidWNj3E_UVOJZNiGpMEzZTheP7lo8Ps.cache +0 -0
  117. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/BuowtxnNzNFEmv6-Xj9DnLTC5Wg0_MXHBvrawKMOhLI.cache +1 -0
  118. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/C5Q9UkNcSexVplLeGzOXZr7Y2PXFwkXLIxYkWRvaNMY.cache +1 -0
  119. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/CMOXd13SQ0QgIVsZR3YQeHh3O8Flqgzy-JsjAMOzC_w.cache +1 -0
  120. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/C__9PeOYhrXzvcJuD4LBB7zfGKFtltFa79hylHbWTXw.cache +1 -0
  121. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/DodvXIBv4hgxwicUQdrUH7nu0904rqnKgWTgx2kbHI4.cache +1 -0
  122. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/E8041y9C4S50ps7cHRzwXZGBtxW86O52h_mWkRAeIJA.cache +1 -0
  123. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/El1vW7N-xrMuF8JBdzfXaGmrBhfZcL2fN6ZISaFVfYw.cache +0 -0
  124. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Fzx-E_HUicjxUBt89DMz0WBFKFtCzo6x7eN7sLMdXxc.cache +0 -0
  125. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/G-lodG1Jka671AODJnGT2D_KpCDYMF23db8C-Ha4GJk.cache +0 -0
  126. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/GKf1Y0SlVRCvDyThY-zOzdxO2HqIAoEjrYQNxuqpIzI.cache +1 -0
  127. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/IXeCSGIZR6GzJ9FdCIKJrhEaFk80fguISCBirw3jC34.cache +1 -0
  128. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/IbJ7BoE7lzLfA0j5vC9WYFWJDilBSEJzcRscE8waoeM.cache +1 -0
  129. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/JSGYqW-UHL6e6RNTmfohq4-cry4P7TMWxaFwnVAVVxg.cache +0 -0
  130. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/JaYRkmobWLox6QvYvDet0yRB2bh_Y0gCTZX5pLIkmK4.cache +0 -0
  131. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Jn9oLambmcCsbyxuo-yOUhxeT_QrKjkkmC1RXO13AFM.cache +1 -0
  132. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/K5XMSe6izrRbQ9YN5FSSrShUn6JkCrheJrfYPnNkGMQ.cache +1 -0
  133. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/N5ZMYm5OswvLSgQ_AVMivRPNcsmnfelrUvHNLwtiQLU.cache +1 -0
  134. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Nw_SGAnCeXZPfX43BQoj5xalMKODjLSfAmeEey5yIgQ.cache +1 -0
  135. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Oxshe88CWlagLX7crM67D-Eritvs_WkP-obQrcgFAgA.cache +0 -0
  136. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/PRLOxeuiC_y0aNo0xmkcbOxY4KFVJOXzZF2eOvtosoo.cache +2 -0
  137. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/SL3Dd3REfpOyQp5wOrm1VEK2afLWvUot5TsIuEgdKz8.cache +1 -0
  138. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/SkvA-zkM5fiG_Z3m4xSBnOMN0t0MfDg2U61j6azwess.cache +0 -0
  139. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/TBNBkl_ZOLQDtv-gF1D9uvkq8bS6Gq_vZxAMHVTS050.cache +1 -0
  140. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/TUZA45lyJBN3k4Aue4bBuj0hy67ZU1LBHiGSlNBtQWI.cache +1 -0
  141. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/UQsWaS8SdBZawmxULjtQ4LKlQISQwQNvLaP-JZxDfwA.cache +0 -0
  142. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/VOp0pIv_pTt1jyD5JQn5Ee721CyQFQTGdnz4ODw38i4.cache +0 -0
  143. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/VzJx82ecMrJphuCCeiKWdDlGeylJJOwwaW09VFmZB3o.cache +1 -0
  144. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/W4U-CePEC2ibeKajQoPowD7fNNoNHOGQKaMrtYyHkoY.cache +2 -0
  145. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/W6SWsBkl4GgPWdz_vi7v9WtOuH3GLVJ6PaO_KoCsJ5Y.cache +0 -0
  146. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/XVCtbPtjn02Czn4Q63QqJFs2UBTG0J31UJis5NC53TA.cache +1 -0
  147. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/YzWqeojadVEyPKiS_1cXuTsQI_nBqoyudANUPEeT7iI.cache +0 -0
  148. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/c-ws04jyEpjpgrAM4OdXB0x0qW4Ep95GQK5fbF2T01Q.cache +2 -0
  149. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/d1tT5anqym_5U_MyM1RiPU8QzUSlrSpLlcLOwH97z-c.cache +0 -0
  150. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/dxjsm7OjfSnkDTyVe4gy-or9j9-Qs5A7ubSilTokIEI.cache +1 -0
  151. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/eqwweAC_8mWnErE-TujdV4BxweHy1WNLbWj2YidR-ZY.cache +1 -0
  152. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/gTt4YDzVktx4phYuvI3nYi03tVIdHtgz7xE0z7RCSgE.cache +1 -0
  153. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/h5QBK-or8YaALTEoyqFHZz2VeHEPDCHp73cpS6_tNDo.cache +0 -0
  154. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/hgNUJ9G6XRgrtvRqHLiLvK0QJr3q2tUlX5JeK2SLheM.cache +1 -0
  155. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/hhBSpRKMFrogXpJ1r8m53q-3gHdfEzh-HtSswRlFsrY.cache +1 -0
  156. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/hn9puRfcK2PWlIceCkiVNetEiEiZI_Xaq2mmYFpZMJc.cache +0 -0
  157. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/izPiTwUCbh9tpfMATrY5pCxFHFL43Uu0WOf_kGoMTNs.cache +1 -0
  158. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/k3IFF3lBYfhNvTJ0PAGS2rIgRVgqjIaOHEcaFCGXURM.cache +1 -0
  159. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/kLLMXTC-18NrDRsqntkF7ARIQvfhoxsA30wuspwxBTQ.cache +0 -0
  160. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/l0Csu8J1O507Eq8qu4LdcN__P6XPTn993bEXlWzBL3g.cache +1 -0
  161. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/lDkv8BcV-iihUA36K3Ab-62Gfk9ZYxpiDsx1QQLn3us.cache +3 -0
  162. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/lME5t2GT7fpXK4W11EYQWhLcGccGkaJYLdbsba2VPjg.cache +1 -0
  163. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/lQbWXQg4tKjoJ8PqCmsJ4ulo_8K4f6Q0k--85ma6W3M.cache +1 -0
  164. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/oRe84XQAcuwON-4A4JZ_8kwLG1VcUKHgXgoV_JDFQ28.cache +3 -0
  165. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/oTDuis4oHgPfw4tzdw_hYlQngc-fB51xu6-WN8m64u0.cache +1 -0
  166. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/oTtT66b4H6sUVGlcSiQzW3gyflWZAX5N8wkTJX_daz8.cache +0 -0
  167. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/p-yWOgy4KbA5EUfA7Q29zG7YO6SltgK2elQKrX5F2Gw.cache +1 -0
  168. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/p89pJmdIHJvvuTTbcO6MlN77ioNCEuT5SvpKRPiWEZQ.cache +1 -0
  169. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/ph5en-XzdEV6YDijatKQkcYBqeFzMb2JDIzs0Qc8EQo.cache +2 -0
  170. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/q4BTUSEQuQqrn5MVI602Bk8jfNEiIMiY9bwtc_3JyeY.cache +1 -0
  171. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/q87JrLqyTCkCQuUF--CLYabb86fA_x_QAOV9IwDbvh8.cache +0 -0
  172. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/qS92oIZtCKj1ab2uoPB6fm5AWt1VzSjhHu8MHse1gq0.cache +0 -0
  173. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/qehskb4sC2FPUhJlhZVDIWEFGyIJrfHJy-CfmphdFns.cache +0 -0
  174. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/sZS0qKF_2iAHdwVD393APebXubqHUsUtE69Q7r8f1yE.cache +1 -0
  175. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/ss9-Jy6X2CYapTa3-AmaqJHooTl__r4L-2AlSA7r064.cache +2 -0
  176. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/t6hRcxh4_1vIzOkNR8o3EdeaZVGSiAyoN3kQuaCo7SQ.cache +1 -0
  177. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/xGvF1Ontkjr6KFr90zUF-XMlQOapQmFbUn6Tx88mA6Q.cache +3 -0
  178. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/yD6dVn7E7d6dwJq8Vpkc8T_UEsSCKDHk-T7tZC5o0tk.cache +0 -0
  179. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/yEGgprrlwc4ukQ7E6vpuEu3-kOSQjKiXj-DsOzQSNXc.cache +0 -0
  180. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/yLOoNONzDnmCO_K_ZKrI0FRRjxXxITJLlEZNch9_PWs.cache +2 -0
  181. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/yS5gM0yLsgOKvJPwitPGmumYfB2zzWlEqZor91CJQbE.cache +0 -0
  182. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/yaK012jvbbVi8IYuzZg5oTLpFef3Nh7cVnw57TIbeXk.cache +1 -0
  183. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/zMFlf0XznowhcZypOSUD8pcejjdcSdiJ8OVbh0TsTiE.cache +2 -0
  184. data/test/integration/navigation_test.rb +10 -0
  185. data/test/test_helper.rb +20 -0
  186. metadata +463 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 40b620ca2093c8981a36cef260acdfbee3b40b02
4
+ data.tar.gz: 3d7e0355a38d34dc8849122b7abe827781d3adb5
5
+ SHA512:
6
+ metadata.gz: 8c0b232a90f377c2b832e47a2ada6c893debd0963b754350c5ccf6b2a0f5df4416e1cece8b029952f16a795080c541d2fa501028aa57f08117c4d7296b4dfab1
7
+ data.tar.gz: 76e3708ae6fe264d1e4172dacee1826820e3161b00cdd20ace53b52663dcc7c78fcb2ad1e2a4bf86ec3bfc2bf3398e0c6bed94a3ae153d61cd4f9c0f0702e5d1
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 choonkeat
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # ActiveWaiter
2
+
3
+ A simple mechanism allowing your users to wait for the completion of your `ActiveJob`
4
+
5
+ ## Scenario
6
+
7
+ You have an export PDF feature that you've implemented directly in the controller action.
8
+
9
+ As data grows, your HTTP request takes longer and starts timing out. So you decide to move the PDF generating code into a background job.
10
+
11
+ ``` ruby
12
+ def index
13
+ respond_to do |format|
14
+ format.html
15
+ format.pdf {
16
+ ExportPdfJob.perform_later(@things, current_user)
17
+ redirect_to :back, notice: "We'll email your PDF when it's done!"
18
+ }
19
+ end
20
+ end
21
+ ```
22
+
23
+
24
+ But how do you get that PDF into the hands of your users now? Email? Push notification? Manual reload?
25
+
26
+ > You have no PDF ready for download (yet). Please reload.
27
+
28
+
29
+ ## Solution
30
+
31
+ Let `ActiveWaiter` enqueue that job instead and redirect to it's progress tracking page.
32
+
33
+ ``` ruby
34
+ def index
35
+ respond_to do |format|
36
+ format.html
37
+ format.pdf {
38
+ # yay ActiveWaiter.enqueue
39
+ redirect_to active_waiter_path(ActiveWaiter.enqueue(ExportPdfJob, @things, current_user))
40
+ }
41
+ end
42
+ end
43
+ ```
44
+
45
+ ``` ruby
46
+ # routes.rb
47
+ mount ActiveWaiter::Engine => "/active_waiter(/:id)"
48
+ ```
49
+
50
+ ![active_waiter mov](https://cloud.githubusercontent.com/assets/473/7785141/c4667734-01b4-11e5-8974-3a3b00b3a4b6.gif)
51
+
52
+ And we need to add a bit of code into your `ActiveJob` class
53
+
54
+ - 1) add `include ActiveWaiter::Job`
55
+ - 2) return a `url` from your `perform` method to link to the result page (or file)
56
+
57
+ ``` ruby
58
+ class ExportPdfJob < ActiveJob::Base
59
+ queue_as :default
60
+
61
+ # (1)
62
+ include ActiveWaiter::Job
63
+
64
+ def perform(things, current_user)
65
+ count = things.count.to_f
66
+ files = []
67
+ things.each_with_index do |thing, index|
68
+ files << generate_pdf(thing)
69
+
70
+ # (a)
71
+ update_active_waiter percentage: (100 * (index+1) / count)
72
+ end
73
+
74
+ # (2)
75
+ upload(combine(files)).s3_url
76
+ rescue Exception => e
77
+
78
+ # (b)
79
+ update_active_waiter error: e.to_s
80
+ end
81
+
82
+ # (c)
83
+ def self.download?
84
+ true
85
+ end
86
+ end
87
+ ```
88
+
89
+ Optionally, you can also
90
+
91
+ - a) report progress while your job runs, using `update_active_waiter(percentage:)`
92
+ - b) report if there were any errors, using `update_active_waiter(error:)`
93
+ - c) indicate if you want the user to "download" the url manually or be redirected there automatically (default: redirect)
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,16 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require turbolinks
16
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module ActiveWaiter
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,36 @@
1
+ require_dependency "active_waiter/application_controller"
2
+
3
+ module ActiveWaiter
4
+ class JobsController < ApplicationController
5
+ def show
6
+ data = ActiveWaiter.read(params[:id])
7
+ return on_not_found(data) unless data.respond_to?(:[])
8
+ return on_error(data) if data[:error]
9
+ return on_redirect(data) if data[:redirect_to]
10
+ return on_link_to(data) if data[:link_to]
11
+ return on_progress(data) if data[:percentage]
12
+ end
13
+
14
+ protected
15
+
16
+ def on_not_found(data)
17
+ raise ActionController::RoutingError.new('Not Found')
18
+ end
19
+
20
+ def on_error(data)
21
+ render template: "active_waiter/jobs/error", status: :internal_server_error, locals: data
22
+ end
23
+
24
+ def on_redirect(data)
25
+ redirect_to data[:redirect_to]
26
+ end
27
+
28
+ def on_link_to(data)
29
+ render template: "active_waiter/jobs/link_to", locals: data
30
+ end
31
+
32
+ def on_progress(data)
33
+ render template: "active_waiter/jobs/progress", locals: data
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,4 @@
1
+ module ActiveWaiter
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ <script>
2
+ setTimeout(function() { Turbolinks.visit(window.location); }, 2000);
3
+ </script>
@@ -0,0 +1,6 @@
1
+ <div class="progress">
2
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100" style="width: 80%; min-width: 3em;">
3
+ <span class="glyphicon glyphicon-exclamation-sign"></span>
4
+ <span><%= error %></span>
5
+ </div>
6
+ </div>
@@ -0,0 +1,12 @@
1
+ <div class="progress">
2
+ <div class="progress-bar progress-bar-success active" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%; min-width: 3em;">
3
+ <span>100% Complete</span>
4
+ </div>
5
+ </div>
6
+ <p class="text-right">
7
+ <a href="<%= link_to %>" class="btn btn-primary">
8
+ Click to
9
+ Download
10
+ <span class="glyphicon glyphicon-download"></span>
11
+ </a>
12
+ <p>
@@ -0,0 +1,6 @@
1
+ <div class="progress">
2
+ <div class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="<%= percentage %>" aria-valuemin="0" aria-valuemax="100" style="width: <%= percentage %>%; min-width: 3em;">
3
+ <span><%= number_to_percentage(percentage, precision: 1, strip_insignificant_zeros: true) %> Complete</span>
4
+ </div>
5
+ </div>
6
+ <%= render partial: 'reload' %>
@@ -0,0 +1,6 @@
1
+ <div class="progress">
2
+ <div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" style="width: 50%; min-width: 3em;">
3
+ <span>Please wait&hellip;</span>
4
+ </div>
5
+ </div>
6
+ <%= render partial: 'reload' %>
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>ActiveWaiter</title>
5
+ <%= stylesheet_link_tag "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css", media: "all" %>
6
+ <%= stylesheet_link_tag "active_waiter/application", media: "all" %>
7
+ <%= javascript_include_tag "active_waiter/application" %>
8
+ <%= csrf_meta_tags %>
9
+ </head>
10
+ <body>
11
+ <div class="content">
12
+ <div class="container">
13
+ <div class="row">
14
+ <div class="col-sm-6 col-sm-offset-3">
15
+ <div class="header">
16
+ <h2/>
17
+ </div>
18
+ <%= yield %>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ </body>
24
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,4 @@
1
+ ActiveWaiter::Engine.routes.draw do
2
+ get '/:id' => 'jobs#show'
3
+ root to: 'jobs#show'
4
+ end
@@ -0,0 +1,25 @@
1
+ require "active_waiter/engine"
2
+ require "active_waiter/job"
3
+
4
+ module ActiveWaiter
5
+ class << self
6
+ def next_uuid
7
+ SecureRandom.uuid
8
+ end
9
+
10
+ def enqueue(klass, *arguments)
11
+ next_uuid.tap do |uid|
12
+ ActiveWaiter.write(uid, {})
13
+ klass.perform_later({ uid: uid }, *arguments)
14
+ end
15
+ end
16
+
17
+ def write(uid, value)
18
+ Rails.cache.write("active_waiter:#{uid}", value)
19
+ end
20
+
21
+ def read(uid)
22
+ Rails.cache.read("active_waiter:#{uid}")
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveWaiter
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace ActiveWaiter
4
+ end
5
+ end
@@ -0,0 +1,28 @@
1
+ module ActiveWaiter::Job
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ around_perform do |job, block|
6
+ @active_waiter_options = job.arguments.shift
7
+ begin
8
+ key = (self.class.try(:download?) ? :link_to : :redirect_to)
9
+ ::ActiveWaiter.write(@active_waiter_options[:uid], {
10
+ percentage: 100,
11
+ key => block.call,
12
+ })
13
+ rescue Exception
14
+ ::ActiveWaiter.write(@active_waiter_options[:uid], {
15
+ error: $!.to_s,
16
+ })
17
+ raise
18
+ end
19
+ end
20
+ end
21
+
22
+ def update_active_waiter(percentage: nil, error: nil)
23
+ ::ActiveWaiter.write(@active_waiter_options[:uid], {
24
+ percentage: percentage && [percentage, 99].min,
25
+ error: error,
26
+ })
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveWaiter
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :active_waiter do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ class DummyJob < ActiveJob::Base
4
+ include ActiveWaiter::Job
5
+
6
+ def perform(one, two, three: 3, four: [1,2,3,4])
7
+ [one, two, three, four].to_json
8
+ end
9
+ end
10
+
11
+ class ActiveWaiter::JobTest < Minitest::Test
12
+ include ActiveJob::TestHelper
13
+
14
+ def teardown
15
+ clear_enqueued_jobs
16
+ end
17
+
18
+ def test_normal
19
+ assert_equal expected_return_value, DummyJob.new.perform(*arguments)
20
+ end
21
+
22
+ def test_active_waiter_enqueue
23
+ ActiveWaiter.stub :next_uuid, uid = "hello" do
24
+ perform_enqueued_jobs do
25
+ assert_equal uid, ActiveWaiter.enqueue(DummyJob, *arguments)
26
+ assert_equal Hash(percentage: 100, redirect_to: expected_return_value), ActiveWaiter.read(uid)
27
+ end
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def arguments
34
+ ['a', 'b', four: ['a', 'b', 'c']]
35
+ end
36
+
37
+ def expected_return_value
38
+ ['a', 'b', 3, ['a', 'b', 'c']].to_json
39
+ end
40
+ end
@@ -0,0 +1,87 @@
1
+ require 'test_helper'
2
+ require 'minitest/mock'
3
+
4
+ class RedirectJob < ActiveJob::Base
5
+ include ActiveWaiter::Job
6
+
7
+ def perform
8
+ "http://other.com/12345"
9
+ end
10
+ end
11
+
12
+ class DownloadJob < RedirectJob
13
+ def self.download?
14
+ true
15
+ end
16
+ end
17
+
18
+ class ActiveWaiter::JobsControllerTest < ActionDispatch::IntegrationTest
19
+ include ActiveJob::TestHelper
20
+
21
+ def setup
22
+ @routes = ActiveWaiter::Engine.routes
23
+ end
24
+
25
+ def teardown
26
+ clear_enqueued_jobs
27
+ end
28
+
29
+ def test_show_non_existent
30
+ assert_raises ActionController::RoutingError do
31
+ get '/active_waiter', id: "nosuchjob"
32
+ end
33
+ end
34
+
35
+ def test_show_started
36
+ ActiveWaiter.stub :next_uuid, uid do
37
+ assert_equal uid, ActiveWaiter.enqueue(DownloadJob)
38
+ get '/active_waiter', id: uid
39
+ assert_equal 200, status
40
+ assert_match "Please wait", document_root_element.to_s
41
+ end
42
+ end
43
+
44
+ def test_show_error
45
+ ActiveWaiter.write(uid, error: "oops")
46
+ get '/active_waiter', id: uid
47
+ assert_equal 500, status
48
+ assert_match "oops", document_root_element.to_s
49
+ end
50
+
51
+ def test_show_progress
52
+ ActiveWaiter.write(uid, percentage: 42)
53
+ get '/active_waiter', id: uid
54
+ assert_equal 200, status
55
+ assert_match "42%", document_root_element.to_s
56
+ end
57
+
58
+ def test_show_completed
59
+ ActiveWaiter.stub :next_uuid, uid do
60
+ perform_enqueued_jobs do
61
+ assert_equal uid, ActiveWaiter.enqueue(DownloadJob)
62
+ get '/active_waiter', id: uid
63
+ assert_equal 200, status
64
+ link = document_root_element.css("a[href='http://other.com/12345']").first
65
+ assert link, "missing hyperlink to returned value"
66
+ assert_match "Click", link.text
67
+ end
68
+ end
69
+ end
70
+
71
+ def test_show_completed_redirect
72
+ ActiveWaiter.stub :next_uuid, uid do
73
+ perform_enqueued_jobs do
74
+ assert_equal uid, ActiveWaiter.enqueue(RedirectJob)
75
+ get '/active_waiter', id: uid
76
+ assert_equal 302, status
77
+ assert_equal "http://other.com/12345", response.location
78
+ end
79
+ end
80
+ end
81
+
82
+ private
83
+
84
+ def uid
85
+ "hello"
86
+ end
87
+ end