burstflow 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +1 -1
- data/README.md +29 -21
- data/burstflow.gemspec +4 -4
- data/db/schema.rb +11 -13
- data/lib/burstflow/job.rb +23 -26
- data/lib/burstflow/job/callbacks.rb +4 -9
- data/lib/burstflow/job/exception.rb +3 -1
- data/lib/burstflow/job/initialization.rb +3 -6
- data/lib/burstflow/job/state.rb +17 -13
- data/lib/burstflow/manager.rb +85 -86
- data/lib/burstflow/railtie.rb +5 -2
- data/lib/burstflow/version.rb +3 -1
- data/lib/burstflow/worker.rb +21 -21
- data/lib/burstflow/workflow.rb +164 -156
- data/lib/burstflow/workflow/builder.rb +67 -64
- data/lib/burstflow/workflow/callbacks.rb +10 -16
- data/lib/burstflow/workflow/configuration.rb +37 -36
- data/lib/burstflow/workflow/exception.rb +3 -1
- data/lib/generators/burstflow/install/install_generator.rb +11 -5
- data/spec/builder_spec.rb +26 -27
- data/spec/generators/install_generator_spec.rb +11 -7
- data/spec/job_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/workflow_spec.rb +128 -101
- metadata +4 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 4d68ef2fa6c3af3c066b65ae6213d3ac96216ea1eb66b849bb979759ed25c67b
         | 
| 4 | 
            +
              data.tar.gz: b7868f4aeca3863996bba8f256fa72b79f244375bc6c82c301386ca88b7f66f8
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 59e06e384d30bec993c880bce050f41dbc017cf1b0814855dca2d538ea270a79d9a9cb6a8f4601b47848f810cc768508e4a0c7aa5eade69717c194dc52b07526
         | 
| 7 | 
            +
              data.tar.gz: dfba34ed82a10b598dfac4539be6f0b8d6880061eb61ac85780c9fcd84f5f498e72ce9228c3bb088d83bba32bcda75d4238b03e070ea64eb3b9d334a88718636
         | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -2,25 +2,33 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            <!-- ## [](https://chaps.io) proudly made by [Chaps](https://chaps.io) -->
         | 
| 4 4 |  | 
| 5 | 
            -
             | 
| 5 | 
            +
            [](https://travis-ci.com/RnD-Soft/burstflow) [](https://badge.fury.io/rb/burstflow)
         | 
| 6 6 |  | 
| 7 | 
            -
             | 
| 7 | 
            +
            Burstflow is a parallel workflow runner using [ActiveRecord] and [ActiveJob](https://guides.rubyonrails.org/v4.2/active_job_basics.html) for scheduling and executing jobs.
         | 
| 8 8 |  | 
| 9 | 
            -
             | 
| 9 | 
            +
            This gem is higly inspired by [Gush](https://github.com/chaps-io/gush). But not tied to Reddis or Sidekiq like Gush.
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            ActiveRecord used as persisted store during workflow execution.
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            Additional features:
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            * **susped** and **resume** job(and whole workflow). For example if your job makes asynchronous request and will receive a response some time later. In this case, the job can send request and suspend until some external event resumes it eventually.
         | 
| 16 | 
            +
            * before/after callbacks on jobs level
         | 
| 17 | 
            +
            * before/after callbacks on workflow level
         | 
| 18 | 
            +
            * **Dynamic workflows**. Any job can produce another jobs while executing. This jobs has its parent as incomming jobs, and all parents outgoing jobs as own outgoings.
         | 
| 10 19 |  | 
| 11 | 
            -
            Another difference from Gush is **Dynamic workflows**. Any job can produce another jobs while executing. This jobs has its parent as incomming jobs, and all parents outgoing jobs as own outgoings.
         | 
| 12 20 |  | 
| 13 21 | 
             
            ## Installation
         | 
| 14 22 |  | 
| 15 23 | 
             
            ### 1. Add `burst` to Gemfile
         | 
| 16 24 |  | 
| 17 25 | 
             
            ```ruby
         | 
| 18 | 
            -
            gem ' | 
| 26 | 
            +
            gem 'burstflow', '~> 0.2.0'
         | 
| 19 27 | 
             
            ```
         | 
| 20 28 |  | 
| 21 29 | 
             
            ### 2. Run migrations
         | 
| 22 30 |  | 
| 23 | 
            -
             | 
| 31 | 
            +
            ```rake burstflow:install:migrations```
         | 
| 24 32 |  | 
| 25 33 | 
             
            ## Example
         | 
| 26 34 |  | 
| @@ -29,7 +37,7 @@ Here is a complete example of a workflow you can create: | |
| 29 37 |  | 
| 30 38 | 
             
            ```ruby
         | 
| 31 39 | 
             
            # app/workflows/sample_workflow.rb
         | 
| 32 | 
            -
            class SampleWorkflow <  | 
| 40 | 
            +
            class SampleWorkflow < Burstflow::Workflow
         | 
| 33 41 | 
             
              configure do |url_to_fetch_from|
         | 
| 34 42 | 
             
                run FetchJob1, params: { url: url_to_fetch_from }
         | 
| 35 43 | 
             
                run FetchJob2, params: { some_flag: true, url: 'http://url.com' }
         | 
| @@ -56,7 +64,7 @@ and this is how the graph will look like: | |
| 56 64 | 
             
            Let's start with the simplest workflow possible, consisting of a single job:
         | 
| 57 65 |  | 
| 58 66 | 
             
            ```ruby
         | 
| 59 | 
            -
            class SimpleWorkflow <  | 
| 67 | 
            +
            class SimpleWorkflow < Burstflow::Workflow
         | 
| 60 68 | 
             
              configure do 
         | 
| 61 69 | 
             
                run DownloadJob
         | 
| 62 70 | 
             
              end
         | 
| @@ -74,12 +82,12 @@ class SimpleWorkflow < Burst::Workflow | |
| 74 82 | 
             
            end
         | 
| 75 83 | 
             
            ```
         | 
| 76 84 |  | 
| 77 | 
            -
            We just told  | 
| 85 | 
            +
            We just told Burstflow to execute `SaveJob` right after `DownloadJob` finishes **successfully**.
         | 
| 78 86 |  | 
| 79 87 | 
             
            But what if your job must have multiple dependencies? That's easy, just provide an array to the `after` attribute:
         | 
| 80 88 |  | 
| 81 89 | 
             
            ```ruby
         | 
| 82 | 
            -
            class SimpleWorkflow <  | 
| 90 | 
            +
            class SimpleWorkflow < Burstflow::Workflow
         | 
| 83 91 | 
             
              configure do
         | 
| 84 92 | 
             
                run FirstDownloadJob
         | 
| 85 93 | 
             
                run SecondDownloadJob
         | 
| @@ -98,7 +106,7 @@ With this simple syntax you can build any complex workflows you can imagine! | |
| 98 106 | 
             
            `run` method also accepts `before:` attribute to define the opposite association. So we can write the same workflow as above, but like this:
         | 
| 99 107 |  | 
| 100 108 | 
             
            ```ruby
         | 
| 101 | 
            -
            class SimpleWorkflow <  | 
| 109 | 
            +
            class SimpleWorkflow < Burstflow::Workflow
         | 
| 102 110 | 
             
              configure do
         | 
| 103 111 | 
             
                run FirstDownloadJob, before: SaveJob
         | 
| 104 112 | 
             
                run SecondDownloadJob, before: SaveJob
         | 
| @@ -118,7 +126,7 @@ Workflows can accept any primitive arguments in their constructor, which then wi | |
| 118 126 | 
             
            Let's assume we are writing a book publishing workflow which needs to know where the PDF of the book is and under what ISBN it will be released:
         | 
| 119 127 |  | 
| 120 128 | 
             
            ```ruby
         | 
| 121 | 
            -
            class PublishBookWorkflow <  | 
| 129 | 
            +
            class PublishBookWorkflow < Burstflow::Workflow
         | 
| 122 130 | 
             
              configure do |url, isbn|
         | 
| 123 131 | 
             
                run FetchBook, params: { url: url }
         | 
| 124 132 | 
             
                run PublishBook, params: { book_isbn: isbn }, after: FetchBook
         | 
| @@ -136,7 +144,7 @@ and that's basically it for defining workflows, see below on how to define jobs: | |
| 136 144 |  | 
| 137 145 | 
             
            ## Defining jobs
         | 
| 138 146 |  | 
| 139 | 
            -
            The simplest job is a class inheriting from ` | 
| 147 | 
            +
            The simplest job is a class inheriting from `Burstflow::Job` and responding to `perform` and `resume` method. Much like any other ActiveJob class.
         | 
| 140 148 |  | 
| 141 149 | 
             
            ```ruby
         | 
| 142 150 | 
             
            class FetchBook < Burst::Job
         | 
| @@ -189,14 +197,14 @@ flow = PublishBookWorkflow.build("http://url.com/book.pdf", "978-0470081204") | |
| 189 197 | 
             
            flow.start!
         | 
| 190 198 | 
             
            ```
         | 
| 191 199 |  | 
| 192 | 
            -
            Now  | 
| 200 | 
            +
            Now Burstflow will start processing jobs in the background using ActiveJob and your chosen backend.
         | 
| 193 201 |  | 
| 194 202 | 
             
            ### 3. Monitor its progress:
         | 
| 195 203 |  | 
| 196 204 | 
             
            ```ruby
         | 
| 197 205 | 
             
            flow.reload
         | 
| 198 206 | 
             
            flow.status
         | 
| 199 | 
            -
            #=> :running|:finished|:failed
         | 
| 207 | 
            +
            #=> :running|:finished|:failed|:suspended
         | 
| 200 208 | 
             
            ```
         | 
| 201 209 |  | 
| 202 210 | 
             
            `reload` is needed to see the latest status, since workflows are updated asynchronously.
         | 
| @@ -205,7 +213,7 @@ flow.status | |
| 205 213 |  | 
| 206 214 | 
             
            ### Pipelining
         | 
| 207 215 |  | 
| 208 | 
            -
             | 
| 216 | 
            +
            Burstflow offers a useful tool to pass results of a job to its dependencies, so they can act differently.
         | 
| 209 217 |  | 
| 210 218 | 
             
            **Example:**
         | 
| 211 219 |  | 
| @@ -228,9 +236,9 @@ end | |
| 228 236 | 
             
            Now, since `DownloadVideo` finished and its dependant job `EncodeVideo` started, we can access that payload inside it:
         | 
| 229 237 |  | 
| 230 238 | 
             
            ```ruby
         | 
| 231 | 
            -
            class EncodeVideo <  | 
| 239 | 
            +
            class EncodeVideo < Burstflow::Job
         | 
| 232 240 | 
             
              def perform
         | 
| 233 | 
            -
                video_path = payloads.first[: | 
| 241 | 
            +
                video_path = payloads.first[:value]
         | 
| 234 242 | 
             
              end
         | 
| 235 243 | 
             
            end
         | 
| 236 244 | 
             
            ```
         | 
| @@ -243,7 +251,7 @@ end | |
| 243 251 | 
             
              {
         | 
| 244 252 | 
             
                id: "DownloadVideo-41bfb730-b49f-42ac-a808-156327989294" # unique id of the ancestor job
         | 
| 245 253 | 
             
                class: "DownloadVideo",
         | 
| 246 | 
            -
                 | 
| 254 | 
            +
                value: "https://s3.amazonaws.com/somebucket/downloaded-file.mp4" #the payload returned by DownloadVideo job using `output()` method
         | 
| 247 255 | 
             
              }
         | 
| 248 256 | 
             
            ]
         | 
| 249 257 | 
             
            ```
         | 
| @@ -259,7 +267,7 @@ As an example, let's write a workflow which accepts an array of users and has to | |
| 259 267 |  | 
| 260 268 | 
             
            ```ruby
         | 
| 261 269 |  | 
| 262 | 
            -
            class ParentJob <  | 
| 270 | 
            +
            class ParentJob < Burstflow::Job
         | 
| 263 271 | 
             
              def perform
         | 
| 264 272 | 
             
                configure do 
         | 
| 265 273 | 
             
                  params[:user_ids].map do |user_id|
         | 
| @@ -286,7 +294,7 @@ https://github.com/chaps-io/gush#contributors | |
| 286 294 |  | 
| 287 295 | 
             
            ## Contributing
         | 
| 288 296 |  | 
| 289 | 
            -
            1. Fork it ( https://github.com/RnD-Soft/ | 
| 297 | 
            +
            1. Fork it ( https://github.com/RnD-Soft/burstflow/fork )
         | 
| 290 298 | 
             
            2. Create your feature branch (`git checkout -b my-new-feature`)
         | 
| 291 299 | 
             
            3. Commit your changes (`git commit -am 'Add some feature'`)
         | 
| 292 300 | 
             
            4. Push to the branch (`git push origin my-new-feature`)
         | 
    
        data/burstflow.gemspec
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 | 
            -
            $:.push File.expand_path( | 
| 1 | 
            +
            $:.push File.expand_path('lib', __dir__)
         | 
| 2 2 |  | 
| 3 3 | 
             
            # Maintain your gem's version:
         | 
| 4 | 
            -
            require  | 
| 4 | 
            +
            require 'burstflow/version'
         | 
| 5 5 |  | 
| 6 6 | 
             
            Gem::Specification.new do |spec|
         | 
| 7 7 | 
             
              spec.name          = 'burstflow'
         | 
| @@ -19,9 +19,9 @@ Gem::Specification.new do |spec| | |
| 19 19 |  | 
| 20 20 | 
             
              spec.add_dependency 'activejob'
         | 
| 21 21 | 
             
              spec.add_dependency 'activerecord'
         | 
| 22 | 
            -
             | 
| 22 | 
            +
             | 
| 23 23 | 
             
              spec.add_development_dependency 'bundler'
         | 
| 24 | 
            +
              spec.add_development_dependency 'generator_spec'
         | 
| 24 25 | 
             
              spec.add_development_dependency 'rake'
         | 
| 25 26 | 
             
              spec.add_development_dependency 'rspec'
         | 
| 26 | 
            -
              spec.add_development_dependency  'generator_spec'
         | 
| 27 27 | 
             
            end
         | 
    
        data/db/schema.rb
    CHANGED
    
    | @@ -10,20 +10,18 @@ | |
| 10 10 | 
             
            #
         | 
| 11 11 | 
             
            # It's strongly recommended that you check this file into your version control system.
         | 
| 12 12 |  | 
| 13 | 
            -
            ActiveRecord::Schema.define(version:  | 
| 14 | 
            -
             | 
| 13 | 
            +
            ActiveRecord::Schema.define(version: 20_180_101_000_001) do
         | 
| 15 14 | 
             
              # These are extensions that must be enabled in order to support this database
         | 
| 16 | 
            -
              enable_extension  | 
| 17 | 
            -
              enable_extension  | 
| 15 | 
            +
              enable_extension 'pgcrypto'
         | 
| 16 | 
            +
              enable_extension 'plpgsql'
         | 
| 18 17 |  | 
| 19 | 
            -
              create_table  | 
| 20 | 
            -
                t.string  | 
| 21 | 
            -
                t.string  | 
| 22 | 
            -
                t.jsonb  | 
| 23 | 
            -
                t.datetime  | 
| 24 | 
            -
                t.datetime  | 
| 25 | 
            -
                t.index [ | 
| 26 | 
            -
                t.index [ | 
| 18 | 
            +
              create_table 'burstflow_workflows', id: :uuid, default: -> { 'gen_random_uuid()' }, force: :cascade do |t|
         | 
| 19 | 
            +
                t.string 'type'
         | 
| 20 | 
            +
                t.string 'status'
         | 
| 21 | 
            +
                t.jsonb 'flow', default: {}, null: false
         | 
| 22 | 
            +
                t.datetime 'created_at', null: false
         | 
| 23 | 
            +
                t.datetime 'updated_at', null: false
         | 
| 24 | 
            +
                t.index ['status'], name: 'index_burstflow_workflows_on_status'
         | 
| 25 | 
            +
                t.index ['type'], name: 'index_burstflow_workflows_on_type'
         | 
| 27 26 | 
             
              end
         | 
| 28 | 
            -
             | 
| 29 27 | 
             
            end
         | 
    
        data/lib/burstflow/job.rb
    CHANGED
    
    | @@ -1,12 +1,13 @@ | |
| 1 | 
            -
            require  | 
| 2 | 
            -
            require  | 
| 1 | 
            +
            require 'active_support/rescuable'
         | 
| 2 | 
            +
            require 'active_job/callbacks'
         | 
| 3 3 |  | 
| 4 4 | 
             
            class Burstflow::Job
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              require  | 
| 7 | 
            -
              require  | 
| 8 | 
            -
              require  | 
| 9 | 
            -
              require  | 
| 5 | 
            +
             | 
| 6 | 
            +
              require 'burstflow/job/exception'
         | 
| 7 | 
            +
              require 'burstflow/job/model'
         | 
| 8 | 
            +
              require 'burstflow/job/initialization'
         | 
| 9 | 
            +
              require 'burstflow/job/state'
         | 
| 10 | 
            +
              require 'burstflow/job/callbacks'
         | 
| 10 11 |  | 
| 11 12 | 
             
              include Burstflow::Job::Model
         | 
| 12 13 | 
             
              include Burstflow::Job::Initialization
         | 
| @@ -30,28 +31,28 @@ class Burstflow::Job | |
| 30 31 | 
             
              end
         | 
| 31 32 |  | 
| 32 33 | 
             
              # execute this code by ActiveJob. You may return Burstflow::Job::SUSPEND to suspend job, or call suspend method
         | 
| 33 | 
            -
              def perform
         | 
| 34 | 
            -
              end
         | 
| 34 | 
            +
              def perform; end
         | 
| 35 35 |  | 
| 36 36 | 
             
              def perform_now
         | 
| 37 37 | 
             
                run_callbacks :perform do
         | 
| 38 38 | 
             
                  perform
         | 
| 39 39 | 
             
                end
         | 
| 40 | 
            -
              rescue => exception
         | 
| 40 | 
            +
              rescue StandardError => exception
         | 
| 41 41 | 
             
                rescue_with_handler(exception) || raise
         | 
| 42 42 | 
             
              end
         | 
| 43 43 |  | 
| 44 44 | 
             
              # execute this code when resumes after suspending
         | 
| 45 45 | 
             
              def resume(data)
         | 
| 46 | 
            -
                raise InternalError.new(self, "Can't perform resume: not resumed")  | 
| 46 | 
            +
                raise InternalError.new(self, "Can't perform resume: not resumed") unless resumed?
         | 
| 47 | 
            +
             | 
| 47 48 | 
             
                set_output(data)
         | 
| 48 49 | 
             
              end
         | 
| 49 50 |  | 
| 50 | 
            -
              def resume_now | 
| 51 | 
            +
              def resume_now(data)
         | 
| 51 52 | 
             
                run_callbacks :resume do
         | 
| 52 53 | 
             
                  resume(data)
         | 
| 53 54 | 
             
                end
         | 
| 54 | 
            -
              rescue => exception
         | 
| 55 | 
            +
              rescue StandardError => exception
         | 
| 55 56 | 
             
                rescue_with_handler(exception) || raise
         | 
| 56 57 | 
             
              end
         | 
| 57 58 |  | 
| @@ -62,13 +63,13 @@ class Burstflow::Job | |
| 62 63 |  | 
| 63 64 | 
             
              # mark execution as suspended
         | 
| 64 65 | 
             
              def suspend
         | 
| 65 | 
            -
                raise InternalError.new(self, "Can't suspend: not running")  | 
| 66 | 
            +
                raise InternalError.new(self, "Can't suspend: not running") unless running?
         | 
| 67 | 
            +
             | 
| 66 68 | 
             
                set_output(SUSPEND)
         | 
| 67 69 | 
             
              end
         | 
| 68 70 |  | 
| 69 | 
            -
              def configure | 
| 71 | 
            +
              def configure(*args, &block)
         | 
| 70 72 | 
             
                workflow.with_lock do
         | 
| 71 | 
            -
             | 
| 72 73 | 
             
                  builder = Burstflow::Workflow::Builder.new(workflow, *args, &block)
         | 
| 73 74 | 
             
                  workflow.flow['jobs_config'] = builder.as_json
         | 
| 74 75 | 
             
                  workflow.save!
         | 
| @@ -78,12 +79,12 @@ class Burstflow::Job | |
| 78 79 |  | 
| 79 80 | 
             
              def attributes
         | 
| 80 81 | 
             
                {
         | 
| 81 | 
            -
                  workflow_id:  | 
| 82 | 
            -
                  id:  | 
| 83 | 
            -
                  klass:  | 
| 82 | 
            +
                  workflow_id: workflow_id,
         | 
| 83 | 
            +
                  id: id,
         | 
| 84 | 
            +
                  klass: klass,
         | 
| 84 85 | 
             
                  params: params,
         | 
| 85 | 
            -
                  incoming:  | 
| 86 | 
            -
                  outgoing:  | 
| 86 | 
            +
                  incoming: incoming,
         | 
| 87 | 
            +
                  outgoing: outgoing,
         | 
| 87 88 | 
             
                  output: output,
         | 
| 88 89 | 
             
                  started_at: started_at,
         | 
| 89 90 | 
             
                  enqueued_at: enqueued_at,
         | 
| @@ -91,12 +92,8 @@ class Burstflow::Job | |
| 91 92 | 
             
                  failed_at: failed_at,
         | 
| 92 93 | 
             
                  suspended_at: suspended_at,
         | 
| 93 94 | 
             
                  resumed_at: resumed_at,
         | 
| 94 | 
            -
                  failure:  | 
| 95 | 
            +
                  failure: failure
         | 
| 95 96 | 
             
                }
         | 
| 96 97 | 
             
              end
         | 
| 97 98 |  | 
| 98 | 
            -
              
         | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 99 | 
             
            end
         | 
| @@ -1,17 +1,15 @@ | |
| 1 1 | 
             
            module Burstflow::Job::Callbacks
         | 
| 2 | 
            +
             | 
| 2 3 | 
             
              extend  ActiveSupport::Concern
         | 
| 3 4 | 
             
              include ActiveJob::Callbacks
         | 
| 4 5 |  | 
| 5 6 | 
             
              included do
         | 
| 6 | 
            -
             | 
| 7 7 | 
             
                define_callbacks :suspend
         | 
| 8 8 | 
             
                define_callbacks :resume
         | 
| 9 9 | 
             
                define_callbacks :failure
         | 
| 10 | 
            -
             | 
| 11 10 | 
             
              end
         | 
| 12 11 |  | 
| 13 12 | 
             
              class_methods do
         | 
| 14 | 
            -
             | 
| 15 13 | 
             
                def before_suspend(*filters, &blk)
         | 
| 16 14 | 
             
                  set_callback(:suspend, :before, *filters, &blk)
         | 
| 17 15 | 
             
                end
         | 
| @@ -24,7 +22,6 @@ module Burstflow::Job::Callbacks | |
| 24 22 | 
             
                  set_callback(:suspend, :around, *filters, &blk)
         | 
| 25 23 | 
             
                end
         | 
| 26 24 |  | 
| 27 | 
            -
              
         | 
| 28 25 | 
             
                def before_resume(*filters, &blk)
         | 
| 29 26 | 
             
                  set_callback(:resume, :before, *filters, &blk)
         | 
| 30 27 | 
             
                end
         | 
| @@ -37,19 +34,17 @@ module Burstflow::Job::Callbacks | |
| 37 34 | 
             
                  set_callback(:resume, :around, *filters, &blk)
         | 
| 38 35 | 
             
                end
         | 
| 39 36 |  | 
| 40 | 
            -
              
         | 
| 41 37 | 
             
                def before_failure(*filters, &blk)
         | 
| 42 38 | 
             
                  set_callback(:failure, :before, *filters, &blk)
         | 
| 43 39 | 
             
                end
         | 
| 44 | 
            -
             | 
| 40 | 
            +
             | 
| 45 41 | 
             
                def after_failure(*filters, &blk)
         | 
| 46 42 | 
             
                  set_callback(:failure, :after, *filters, &blk)
         | 
| 47 43 | 
             
                end
         | 
| 48 | 
            -
             | 
| 44 | 
            +
             | 
| 49 45 | 
             
                def around_failure(*filters, &blk)
         | 
| 50 46 | 
             
                  set_callback(:failure, :around, *filters, &blk)
         | 
| 51 47 | 
             
                end
         | 
| 52 | 
            -
             | 
| 53 48 | 
             
              end
         | 
| 54 49 |  | 
| 55 | 
            -
            end
         | 
| 50 | 
            +
            end
         | 
| @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            module Burstflow::Job::Initialization
         | 
| 2 | 
            -
              extend  ActiveSupport::Concern
         | 
| 3 2 |  | 
| 4 | 
            -
               | 
| 3 | 
            +
              extend ActiveSupport::Concern
         | 
| 5 4 |  | 
| 5 | 
            +
              included do
         | 
| 6 6 | 
             
                def initialize(workflow, job_config = {})
         | 
| 7 7 | 
             
                  @workflow = workflow
         | 
| 8 8 | 
             
                  assign_default_values(job_config)
         | 
| @@ -21,15 +21,12 @@ module Burstflow::Job::Initialization | |
| 21 21 | 
             
                def reload
         | 
| 22 22 | 
             
                  assign_default_values(@workflow.job_hash(self.id))
         | 
| 23 23 | 
             
                end
         | 
| 24 | 
            -
             | 
| 25 24 | 
             
              end
         | 
| 26 25 |  | 
| 27 26 | 
             
              class_methods do
         | 
| 28 | 
            -
             | 
| 29 27 | 
             
                def from_hash(workflow, job_config)
         | 
| 30 28 | 
             
                  job_config[:klass].constantize.new(workflow, job_config)
         | 
| 31 29 | 
             
                end
         | 
| 32 | 
            -
             | 
| 33 30 | 
             
              end
         | 
| 34 31 |  | 
| 35 | 
            -
            end
         | 
| 32 | 
            +
            end
         | 
    
        data/lib/burstflow/job/state.rb
    CHANGED
    
    | @@ -1,11 +1,12 @@ | |
| 1 1 | 
             
            module Burstflow::Job::State
         | 
| 2 | 
            -
              extend  ActiveSupport::Concern
         | 
| 3 2 |  | 
| 4 | 
            -
               | 
| 3 | 
            +
              extend ActiveSupport::Concern
         | 
| 5 4 |  | 
| 5 | 
            +
              included do
         | 
| 6 6 | 
             
                # mark job as enqueued when it is scheduled to queue
         | 
| 7 7 | 
             
                def enqueue!
         | 
| 8 8 | 
             
                  raise Burstflow::Job::InternalError.new(self, "Can't enqueue: already enqueued") if enqueued?
         | 
| 9 | 
            +
             | 
| 9 10 | 
             
                  self.enqueued_at = current_timestamp
         | 
| 10 11 | 
             
                  self.started_at = nil
         | 
| 11 12 | 
             
                  self.finished_at = nil
         | 
| @@ -17,22 +18,25 @@ module Burstflow::Job::State | |
| 17 18 | 
             
                # mark job as started when it is start performing
         | 
| 18 19 | 
             
                def start!
         | 
| 19 20 | 
             
                  raise Burstflow::Job::InternalError.new(self, "Can't start: already started") if started?
         | 
| 20 | 
            -
                  raise Burstflow::Job::InternalError.new(self, "Can't start: not enqueued")  | 
| 21 | 
            +
                  raise Burstflow::Job::InternalError.new(self, "Can't start: not enqueued") unless enqueued?
         | 
| 22 | 
            +
             | 
| 21 23 | 
             
                  self.started_at = current_timestamp
         | 
| 22 24 | 
             
                end
         | 
| 23 25 |  | 
| 24 26 | 
             
                # mark job as finished when it is finish performing
         | 
| 25 27 | 
             
                def finish!
         | 
| 26 28 | 
             
                  raise Burstflow::Job::InternalError.new(self, "Can't finish: already finished") if finished?
         | 
| 27 | 
            -
                  raise Burstflow::Job::InternalError.new(self, "Can't finish: not started")  | 
| 29 | 
            +
                  raise Burstflow::Job::InternalError.new(self, "Can't finish: not started") unless started?
         | 
| 30 | 
            +
             | 
| 28 31 | 
             
                  self.finished_at = current_timestamp
         | 
| 29 32 | 
             
                end
         | 
| 30 33 |  | 
| 31 34 | 
             
                # mark job as failed when it is failed
         | 
| 32 | 
            -
                def fail! | 
| 33 | 
            -
                  #raise Burstflow::Job::InternalError.new(self, "Can't fail: already failed") if failed?
         | 
| 34 | 
            -
                  #raise Burstflow::Job::InternalError.new(self, Can't fail: already finished") if finished?
         | 
| 35 | 
            -
                  raise Burstflow::Job::InternalError.new(self, "Can't fail: not started")  | 
| 35 | 
            +
                def fail!(msg_or_exception)
         | 
| 36 | 
            +
                  # raise Burstflow::Job::InternalError.new(self, "Can't fail: already failed") if failed?
         | 
| 37 | 
            +
                  # raise Burstflow::Job::InternalError.new(self, Can't fail: already finished") if finished?
         | 
| 38 | 
            +
                  raise Burstflow::Job::InternalError.new(self, "Can't fail: not started") unless started?
         | 
| 39 | 
            +
             | 
| 36 40 | 
             
                  self.finished_at = self.failed_at = current_timestamp
         | 
| 37 41 |  | 
| 38 42 | 
             
                  context = {}
         | 
| @@ -51,14 +55,16 @@ module Burstflow::Job::State | |
| 51 55 | 
             
                # mark job as suspended
         | 
| 52 56 | 
             
                def suspend!
         | 
| 53 57 | 
             
                  raise Burstflow::Job::InternalError.new(self, "Can't suspend: already suspended") if suspended?
         | 
| 54 | 
            -
                  raise Burstflow::Job::InternalError.new(self, "Can't suspend: not runnig")  | 
| 58 | 
            +
                  raise Burstflow::Job::InternalError.new(self, "Can't suspend: not runnig") unless running?
         | 
| 59 | 
            +
             | 
| 55 60 | 
             
                  self.suspended_at = current_timestamp
         | 
| 56 61 | 
             
                end
         | 
| 57 62 |  | 
| 58 63 | 
             
                # mark job as resumed
         | 
| 59 64 | 
             
                def resume!
         | 
| 60 65 | 
             
                  raise Burstflow::Job::InternalError.new(self, "Can't resume: already resumed") if resumed?
         | 
| 61 | 
            -
                  raise Burstflow::Job::InternalError.new(self, "Can't resume: not suspended")  | 
| 66 | 
            +
                  raise Burstflow::Job::InternalError.new(self, "Can't resume: not suspended") unless suspended?
         | 
| 67 | 
            +
             | 
| 62 68 | 
             
                  self.resumed_at = current_timestamp
         | 
| 63 69 | 
             
                end
         | 
| 64 70 |  | 
| @@ -115,11 +121,9 @@ module Burstflow::Job::State | |
| 115 121 | 
             
                def current_timestamp
         | 
| 116 122 | 
             
                  Time.now.to_i
         | 
| 117 123 | 
             
                end
         | 
| 118 | 
            -
             | 
| 119 124 | 
             
              end
         | 
| 120 125 |  | 
| 121 126 | 
             
              class_methods do
         | 
| 122 | 
            -
             | 
| 123 127 | 
             
              end
         | 
| 124 128 |  | 
| 125 | 
            -
            end
         | 
| 129 | 
            +
            end
         |