burstflow 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +1 -3
  3. data/Gemfile.lock +119 -0
  4. data/burstflow.gemspec +10 -6
  5. data/config/database.yml +4 -3
  6. data/db/migrate/20180101000001_create_workflow.rb +1 -0
  7. data/db/schema.rb +13 -7
  8. data/lib/burstflow.rb +11 -0
  9. data/lib/burstflow/job.rb +102 -0
  10. data/lib/burstflow/job/callbacks.rb +55 -0
  11. data/lib/burstflow/job/exception.rb +8 -0
  12. data/lib/burstflow/job/initialization.rb +35 -0
  13. data/lib/{burst → burstflow/job}/model.rb +1 -3
  14. data/lib/burstflow/job/state.rb +125 -0
  15. data/lib/burstflow/manager.rb +123 -0
  16. data/lib/burstflow/railtie.rb +6 -0
  17. data/lib/burstflow/version.rb +3 -0
  18. data/lib/burstflow/worker.rb +59 -0
  19. data/lib/burstflow/workflow.rb +207 -0
  20. data/lib/burstflow/workflow/builder.rb +91 -0
  21. data/lib/burstflow/workflow/callbacks.rb +66 -0
  22. data/lib/{burst/workflow_helper.rb → burstflow/workflow/configuration.rb} +8 -39
  23. data/lib/burstflow/workflow/exception.rb +8 -0
  24. data/lib/generators/burstflow/install/install_generator.rb +22 -0
  25. data/lib/generators/burstflow/install/templates/create_workflow.rb +15 -0
  26. data/spec/builder_spec.rb +63 -0
  27. data/spec/{burst_spec.rb → burstflow_spec.rb} +1 -1
  28. data/spec/generators/install_generator_spec.rb +27 -0
  29. data/spec/job_spec.rb +18 -8
  30. data/spec/spec_helper.rb +4 -1
  31. data/spec/support/database_clean.rb +4 -1
  32. data/spec/workflow_spec.rb +397 -147
  33. metadata +45 -21
  34. data/db/migrate/20180101000001_create_workflow.rb +0 -13
  35. data/db/seeds.rb +0 -1
  36. data/lib/burst.rb +0 -37
  37. data/lib/burst/builder.rb +0 -48
  38. data/lib/burst/configuration.rb +0 -27
  39. data/lib/burst/job.rb +0 -187
  40. data/lib/burst/manager.rb +0 -79
  41. data/lib/burst/worker.rb +0 -42
  42. data/lib/burst/workflow.rb +0 -148
  43. data/spec/cases_spec.rb +0 -180
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 24e4b83edc403cfa7903a0aa9fe90ab8fe0968d5
4
- data.tar.gz: ff4e300d06ab5152d9ed07913b6cb88c73afefd6
2
+ SHA256:
3
+ metadata.gz: 435e3f0b3dba1c654d192d3f5f4cb1687bfe55e6c60f03e6fcb4643946603f0a
4
+ data.tar.gz: e5390d5f58fb4a2e3503516f0c0744bce0cac68411edf56477e82d84a9f9ed87
5
5
  SHA512:
6
- metadata.gz: d123b0cde794b44e1d5c969084823a299033f0d551a8a4f2790bb1622914abdb19ae3d11b1f29f9cf9c3e97edd5a68423aae8ecb785308c0e04d34507390f468
7
- data.tar.gz: e9af6f93dcae06d5d60ec1f71d746de2d9ef49e783f081a76fe854085686355e53a040978262d22ef1df7534500fca1a7caf7644cc95e531eaab9ab9aac5c19c
6
+ metadata.gz: fcb37c6b28837184136c25333cfaa3bd403bb953b9aa8dc8fe5971d499013650664444b5415aa50e2530218a88d07107e5032f90cc3ef3cd5114bd8593752669
7
+ data.tar.gz: ae739a9ab5a48b10512c3461e4720e54e564722192fca3aaf36123a48ed3a1c36de28483d19fd975659b2586637120be3dd32068f62e5bb2a294a1f6c8177e33
data/Gemfile CHANGED
@@ -5,12 +5,10 @@ platforms :mri, :ruby do
5
5
  gem 'yajl-ruby'
6
6
  end
7
7
 
8
- gem 'rake'
9
-
10
8
  group :test do
11
9
  gem 'activesupport'
12
- gem 'awesome_print'
13
10
  gem 'database_cleaner'
14
11
  gem 'otr-activerecord'
15
12
  gem 'pg', '~> 0.21.0'
13
+ gem 'awesome_print'
16
14
  end
@@ -0,0 +1,119 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ burstflow (0.2.0)
5
+ activejob
6
+ activerecord
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actionpack (5.2.2)
12
+ actionview (= 5.2.2)
13
+ activesupport (= 5.2.2)
14
+ rack (~> 2.0)
15
+ rack-test (>= 0.6.3)
16
+ rails-dom-testing (~> 2.0)
17
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
18
+ actionview (5.2.2)
19
+ activesupport (= 5.2.2)
20
+ builder (~> 3.1)
21
+ erubi (~> 1.4)
22
+ rails-dom-testing (~> 2.0)
23
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
24
+ activejob (5.2.2)
25
+ activesupport (= 5.2.2)
26
+ globalid (>= 0.3.6)
27
+ activemodel (5.2.2)
28
+ activesupport (= 5.2.2)
29
+ activerecord (5.2.2)
30
+ activemodel (= 5.2.2)
31
+ activesupport (= 5.2.2)
32
+ arel (>= 9.0)
33
+ activesupport (5.2.2)
34
+ concurrent-ruby (~> 1.0, >= 1.0.2)
35
+ i18n (>= 0.7, < 2)
36
+ minitest (~> 5.1)
37
+ tzinfo (~> 1.1)
38
+ arel (9.0.0)
39
+ awesome_print (1.8.0)
40
+ builder (3.2.3)
41
+ concurrent-ruby (1.1.4)
42
+ crass (1.0.4)
43
+ database_cleaner (1.7.0)
44
+ diff-lcs (1.3)
45
+ erubi (1.8.0)
46
+ generator_spec (0.9.4)
47
+ activesupport (>= 3.0.0)
48
+ railties (>= 3.0.0)
49
+ globalid (0.4.2)
50
+ activesupport (>= 4.2.0)
51
+ hashie (3.6.0)
52
+ hashie-forbidden_attributes (0.1.1)
53
+ hashie (>= 3.0)
54
+ i18n (1.4.0)
55
+ concurrent-ruby (~> 1.0)
56
+ loofah (2.2.3)
57
+ crass (~> 1.0.2)
58
+ nokogiri (>= 1.5.9)
59
+ method_source (0.9.2)
60
+ mini_portile2 (2.4.0)
61
+ minitest (5.11.3)
62
+ nokogiri (1.10.1)
63
+ mini_portile2 (~> 2.4.0)
64
+ otr-activerecord (1.2.6)
65
+ activerecord (>= 4.0, < 5.3)
66
+ hashie-forbidden_attributes (~> 0.1)
67
+ pg (0.21.0)
68
+ rack (2.0.6)
69
+ rack-test (1.1.0)
70
+ rack (>= 1.0, < 3)
71
+ rails-dom-testing (2.0.3)
72
+ activesupport (>= 4.2.0)
73
+ nokogiri (>= 1.6)
74
+ rails-html-sanitizer (1.0.4)
75
+ loofah (~> 2.2, >= 2.2.2)
76
+ railties (5.2.2)
77
+ actionpack (= 5.2.2)
78
+ activesupport (= 5.2.2)
79
+ method_source
80
+ rake (>= 0.8.7)
81
+ thor (>= 0.19.0, < 2.0)
82
+ rake (12.3.2)
83
+ rspec (3.8.0)
84
+ rspec-core (~> 3.8.0)
85
+ rspec-expectations (~> 3.8.0)
86
+ rspec-mocks (~> 3.8.0)
87
+ rspec-core (3.8.0)
88
+ rspec-support (~> 3.8.0)
89
+ rspec-expectations (3.8.2)
90
+ diff-lcs (>= 1.2.0, < 2.0)
91
+ rspec-support (~> 3.8.0)
92
+ rspec-mocks (3.8.0)
93
+ diff-lcs (>= 1.2.0, < 2.0)
94
+ rspec-support (~> 3.8.0)
95
+ rspec-support (3.8.0)
96
+ thor (0.20.3)
97
+ thread_safe (0.3.6)
98
+ tzinfo (1.2.5)
99
+ thread_safe (~> 0.1)
100
+ yajl-ruby (1.4.1)
101
+
102
+ PLATFORMS
103
+ ruby
104
+
105
+ DEPENDENCIES
106
+ activesupport
107
+ awesome_print
108
+ bundler
109
+ burstflow!
110
+ database_cleaner
111
+ generator_spec
112
+ otr-activerecord
113
+ pg (~> 0.21.0)
114
+ rake
115
+ rspec
116
+ yajl-ruby
117
+
118
+ BUNDLED WITH
119
+ 1.17.2
@@ -1,14 +1,16 @@
1
- lib = File.expand_path('lib', __dir__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
1
+ $:.push File.expand_path("lib", __dir__)
2
+
3
+ # Maintain your gem's version:
4
+ require "burstflow/version"
3
5
 
4
6
  Gem::Specification.new do |spec|
5
7
  spec.name = 'burstflow'
6
- spec.version = '0.1.1'
8
+ spec.version = Burstflow::VERSION
7
9
  spec.authors = ['Samoilenko Yuri']
8
10
  spec.email = ['kinnalru@gmail.com']
9
- spec.summary = 'Burst is a parallel workflow runner using ActiveRecord and ActiveJob'
10
- spec.description = 'Burst is a parallel workflow runner using ActiveRecord and ActiveJob. It has dependency, result pipelining and suspend/resume ability'
11
- spec.homepage = 'https://github.com/RnD-Soft/burst'
11
+ spec.summary = 'Burstflow is a parallel workflow runner using ActiveRecord and ActiveJob'
12
+ spec.description = 'Burstflow is a parallel workflow runner using ActiveRecord and ActiveJob. It has dependency, result pipelining and suspend/resume ability'
13
+ spec.homepage = 'https://github.com/RnD-Soft/burstflow'
12
14
  spec.license = 'MIT'
13
15
 
14
16
  spec.files = `git ls-files -z`.split("\x0")
@@ -17,7 +19,9 @@ Gem::Specification.new do |spec|
17
19
 
18
20
  spec.add_dependency 'activejob'
19
21
  spec.add_dependency 'activerecord'
22
+
20
23
  spec.add_development_dependency 'bundler'
21
24
  spec.add_development_dependency 'rake'
22
25
  spec.add_development_dependency 'rspec'
26
+ spec.add_development_dependency 'generator_spec'
23
27
  end
@@ -3,13 +3,14 @@ development: &base
3
3
  host: <%= ENV['DATABASE_HOST'] || 'localhost' %>
4
4
  port: <%= ENV['DATABASE_PORT'] || 5432 %>
5
5
  encoding: unicode
6
- database: <%= ENV['DATABASE_NAME'] || 'burst_test' %>
7
- pool: 4
6
+ database: <%= ENV['DATABASE_NAME'] || 'burstflow_test' %>
7
+ pool: 150
8
8
  username: <%= ENV['DATABASE_USER'] || 'postgres' %>
9
9
  password: <%= ENV['DATABASE_PASS'] || '' %>
10
10
 
11
11
  test:
12
- <<: *base
12
+ <<: *base
13
+
13
14
 
14
15
  production:
15
16
  <<: *base
@@ -0,0 +1 @@
1
+ ../../lib/generators/burstflow/install/templates/create_workflow.rb
@@ -10,14 +10,20 @@
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: 20_180_101_000_001) do
13
+ ActiveRecord::Schema.define(version: 2018_01_01_000001) do
14
+
14
15
  # These are extensions that must be enabled in order to support this database
15
- enable_extension 'pgcrypto'
16
- enable_extension 'plpgsql'
16
+ enable_extension "pgcrypto"
17
+ enable_extension "plpgsql"
17
18
 
18
- create_table 'burst_workflows', id: :uuid, default: -> { 'gen_random_uuid()' }, force: :cascade do |t|
19
- t.jsonb 'flow', default: {}, null: false
20
- t.datetime 'created_at', null: false
21
- t.datetime 'updated_at', null: false
19
+ create_table "burstflow_workflows", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
20
+ t.string "type"
21
+ t.string "status"
22
+ t.jsonb "flow", default: {}, null: false
23
+ t.datetime "created_at", null: false
24
+ t.datetime "updated_at", null: false
25
+ t.index ["status"], name: "index_burstflow_workflows_on_status"
26
+ t.index ["type"], name: "index_burstflow_workflows_on_type"
22
27
  end
28
+
23
29
  end
@@ -0,0 +1,11 @@
1
+ require 'burstflow/railtie' if defined?(Rails)
2
+
3
+ require 'active_support/all'
4
+
5
+ require 'burstflow/workflow'
6
+ require 'burstflow/job'
7
+ require 'burstflow/worker'
8
+
9
+ module Burstflow
10
+
11
+ end
@@ -0,0 +1,102 @@
1
+ require "active_support/rescuable"
2
+ require "active_job/callbacks"
3
+
4
+ class Burstflow::Job
5
+ require "burstflow/job/exception"
6
+ require "burstflow/job/model"
7
+ require "burstflow/job/initialization"
8
+ require "burstflow/job/state"
9
+ require "burstflow/job/callbacks"
10
+
11
+ include Burstflow::Job::Model
12
+ include Burstflow::Job::Initialization
13
+ include Burstflow::Job::State
14
+ include Burstflow::Job::Callbacks
15
+ include ActiveSupport::Rescuable
16
+
17
+ attr_accessor :workflow, :payloads
18
+
19
+ define_stored_attributes :id, :workflow_id, :klass, :params, :incoming, :outgoing, :output, :failure
20
+ define_stored_attributes :enqueued_at, :started_at, :finished_at, :failed_at, :suspended_at, :resumed_at
21
+
22
+ SUSPEND = 'suspend'.freeze
23
+
24
+ def save!
25
+ workflow.with_lock do
26
+ workflow.set_job(self)
27
+ workflow.save!
28
+ yield if block_given?
29
+ end
30
+ end
31
+
32
+ # execute this code by ActiveJob. You may return Burstflow::Job::SUSPEND to suspend job, or call suspend method
33
+ def perform
34
+ end
35
+
36
+ def perform_now
37
+ run_callbacks :perform do
38
+ perform
39
+ end
40
+ rescue => exception
41
+ rescue_with_handler(exception) || raise
42
+ end
43
+
44
+ # execute this code when resumes after suspending
45
+ def resume(data)
46
+ raise InternalError.new(self, "Can't perform resume: not resumed") if !resumed?
47
+ set_output(data)
48
+ end
49
+
50
+ def resume_now data
51
+ run_callbacks :resume do
52
+ resume(data)
53
+ end
54
+ rescue => exception
55
+ rescue_with_handler(exception) || raise
56
+ end
57
+
58
+ # store data to be available for next jobs
59
+ def set_output(data)
60
+ self.output = data
61
+ end
62
+
63
+ # mark execution as suspended
64
+ def suspend
65
+ raise InternalError.new(self, "Can't suspend: not running") if !running?
66
+ set_output(SUSPEND)
67
+ end
68
+
69
+ def configure *args, &block
70
+ workflow.with_lock do
71
+
72
+ builder = Burstflow::Workflow::Builder.new(workflow, *args, &block)
73
+ workflow.flow['jobs_config'] = builder.as_json
74
+ workflow.save!
75
+ reload
76
+ end
77
+ end
78
+
79
+ def attributes
80
+ {
81
+ workflow_id: self.workflow_id,
82
+ id: self.id,
83
+ klass: self.klass,
84
+ params: params,
85
+ incoming: self.incoming,
86
+ outgoing: self.outgoing,
87
+ output: output,
88
+ started_at: started_at,
89
+ enqueued_at: enqueued_at,
90
+ finished_at: finished_at,
91
+ failed_at: failed_at,
92
+ suspended_at: suspended_at,
93
+ resumed_at: resumed_at,
94
+ failure: self.failure
95
+ }
96
+ end
97
+
98
+
99
+
100
+
101
+
102
+ end
@@ -0,0 +1,55 @@
1
+ module Burstflow::Job::Callbacks
2
+ extend ActiveSupport::Concern
3
+ include ActiveJob::Callbacks
4
+
5
+ included do
6
+
7
+ define_callbacks :suspend
8
+ define_callbacks :resume
9
+ define_callbacks :failure
10
+
11
+ end
12
+
13
+ class_methods do
14
+
15
+ def before_suspend(*filters, &blk)
16
+ set_callback(:suspend, :before, *filters, &blk)
17
+ end
18
+
19
+ def after_suspend(*filters, &blk)
20
+ set_callback(:suspend, :after, *filters, &blk)
21
+ end
22
+
23
+ def around_suspend(*filters, &blk)
24
+ set_callback(:suspend, :around, *filters, &blk)
25
+ end
26
+
27
+
28
+ def before_resume(*filters, &blk)
29
+ set_callback(:resume, :before, *filters, &blk)
30
+ end
31
+
32
+ def after_resume(*filters, &blk)
33
+ set_callback(:resume, :after, *filters, &blk)
34
+ end
35
+
36
+ def around_resume(*filters, &blk)
37
+ set_callback(:resume, :around, *filters, &blk)
38
+ end
39
+
40
+
41
+ def before_failure(*filters, &blk)
42
+ set_callback(:failure, :before, *filters, &blk)
43
+ end
44
+
45
+ def after_failure(*filters, &blk)
46
+ set_callback(:failure, :after, *filters, &blk)
47
+ end
48
+
49
+ def around_failure(*filters, &blk)
50
+ set_callback(:failure, :around, *filters, &blk)
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1,8 @@
1
+ class Burstflow::Job::InternalError < ::RuntimeError
2
+ attr_accessor :job
3
+
4
+ def initialize(job, message)
5
+ @job = job
6
+ super(message)
7
+ end
8
+ end
@@ -0,0 +1,35 @@
1
+ module Burstflow::Job::Initialization
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+
6
+ def initialize(workflow, job_config = {})
7
+ @workflow = workflow
8
+ assign_default_values(job_config)
9
+ end
10
+
11
+ def assign_default_values(job_config)
12
+ set_model(job_config.deep_dup)
13
+
14
+ self.id ||= SecureRandom.uuid
15
+ self.workflow_id ||= @workflow.try(:id)
16
+ self.klass ||= self.class.to_s
17
+ self.incoming ||= []
18
+ self.outgoing ||= []
19
+ end
20
+
21
+ def reload
22
+ assign_default_values(@workflow.job_hash(self.id))
23
+ end
24
+
25
+ end
26
+
27
+ class_methods do
28
+
29
+ def from_hash(workflow, job_config)
30
+ job_config[:klass].constantize.new(workflow, job_config)
31
+ end
32
+
33
+ end
34
+
35
+ end