dwf 0.1.5 → 0.1.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cfd1989fd7228daec1f81759e249cb3a0d6e920e465b38f1f6998239c78f6c7
4
- data.tar.gz: 0e4139ec4372ef7f5fb91b61cae9b2131e7e5b5983e25219a213b3edb821c9c6
3
+ metadata.gz: d37bac690df59157001462d6017a8a63d3956a280689de789d9a99163a476832
4
+ data.tar.gz: 935d76e99ff5ca109f00be80c01950c20272969f556fc70d0e1ef5c026c024e4
5
5
  SHA512:
6
- metadata.gz: 38b96a776878ddce8df1757ecdba3452a833f117536b9a3f44a07dc801ce71be7ac7cfac997622cd3e172c1a2929ac333f50e4823f901cb844149189c18563de
7
- data.tar.gz: 3a32f7469c5a7009e8f04a1d1c9e35fcd8de4fb322593f8e3c9f90fa617fe96eda8dc768dd97c5a3f7bb9044a2eaa87632970fcdddfd6bb57e96c6d72446951b
6
+ metadata.gz: c105d178cd44f12577ee9eeed5065768a23adc508da7d686e50c46d26e4eed9c160dc71b10942ab8041e38f6c732384742f40fa9d3076e0a924fbdfb1cd62845
7
+ data.tar.gz: ad9c6f1041f092847364e91408887be311435be62e0502ab54f2b408c92fc598a879792eabb00c81b05d5c97fb37ea4a19136765d54b0d4efe9dbdb9ad2f64b5
@@ -6,8 +6,8 @@ on:
6
6
  # Alternatively, publish whenever changes are merged to the `main` branch.
7
7
  push:
8
8
  branches: [ master ]
9
- pull_request:
10
- branches: [ master ]
9
+ paths:
10
+ - 'dwf.gemspec'
11
11
 
12
12
  jobs:
13
13
  build:
@@ -1,9 +1,9 @@
1
- name: dwf
1
+ name: Test
2
2
 
3
3
  on:
4
4
  push:
5
5
  branches:
6
- - '**'
6
+ - 'master'
7
7
  pull_request:
8
8
  branches:
9
9
  - '**'
data/CHANGELOG.md ADDED
@@ -0,0 +1,99 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+ ## 0.1.9
4
+ ### Added
5
+ ### Fixed
6
+ - fix incorrect argument at configuration
7
+
8
+ ## 0.1.8
9
+ ### Added
10
+ - add pinlining feature
11
+
12
+ ```ruby
13
+ class SendOutput < Dwf::Item
14
+ def perform
15
+ output('it works')
16
+ end
17
+ end
18
+
19
+ ```
20
+
21
+ `output` method used to output data from the job to add outgoing jobs
22
+
23
+ ```ruby
24
+ class ReceiveOutput < Dwf::Item
25
+ def perform
26
+ message = payloads.first[:output] # it works
27
+ end
28
+ end
29
+ ```
30
+
31
+ `payloads` is an array that containing outputs from incoming jobs
32
+
33
+ ```
34
+ [
35
+ {
36
+ id: "SendOutput|1849a3f9-5fce-401e-a73a-91fc1048356",
37
+ class: "SendOutput",
38
+ output: 'it works'
39
+ }
40
+ ]
41
+ ```
42
+
43
+ ```ruby
44
+ Dwf.config do |config|
45
+ config.opts = { url 'redis://127.0.0.1:6379' }
46
+ config.namespace = 'dwf'
47
+ end
48
+ ```
49
+
50
+ ## 0.1.7
51
+ ### Added
52
+ - Allow to config redis and queue
53
+
54
+ ```ruby
55
+ Dwf.config do |config|
56
+ config.opts = { url 'redis://127.0.0.1:6379' }
57
+ config.namespace = 'dwf'
58
+ end
59
+ ```
60
+
61
+ ## 0.1.6
62
+ ### Added
63
+ - Sidekiq batch callback: separate batches
64
+
65
+ ## 0.1.5
66
+ ### Added
67
+ - add github action with build and public gem flow
68
+
69
+ ## 0.1.4
70
+ ### Added
71
+ - Add testes
72
+ - add github action
73
+
74
+ ### Fixed
75
+ - Remove Sidekiq pro by default
76
+
77
+ ---
78
+ ## 0.1.3
79
+ ### Added
80
+ - Support both build in and [Sidekiq batches](https://github.com/mperham/sidekiq/wiki/Batches) callback
81
+ - Update readme
82
+
83
+ ### Fixed
84
+ - Fix bug require development gem
85
+
86
+ ---
87
+ ## 0.1.2
88
+ ### Added
89
+ - Support [Sidekiq batches](https://github.com/mperham/sidekiq/wiki/Batches) callback
90
+ - Update readme
91
+
92
+ ### Fixed
93
+ - fix typo and remove development gem
94
+
95
+ ---
96
+ ## 0.1.0
97
+ ### Added
98
+ - init app with basic idea following [Gush](https://github.com/chaps-io/gush) concept
99
+ - Support build in callback
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  # Installation
5
5
  ## 1. Add `dwf` to Gemfile
6
6
  ```ruby
7
- gem 'dwf', '~> 0.1.3'
7
+ gem 'dwf', '~> 0.1.9'
8
8
  ```
9
9
  ## 2. Execute flow
10
10
  ### Declare jobs
@@ -38,19 +38,20 @@ class TestWf < Dwf::Workflow
38
38
  end
39
39
  ```
40
40
 
41
- #### Note
42
- `dwf` supports 2 type of callback `Dwf::Workflow::BUILD_IN` and `Dwf::Workflow::SK_BATCH`
43
- - `Dwf::Workflow::BUILD_IN` is a build-in callback
44
- - `Dwf::Workflow::SK_BATCH` is [sidekiq batch](https://github.com/mperham/sidekiq/wiki/Batches) callback which required [`sidekiq-pro`](https://sidekiq.org/products/pro.html)
45
-
46
- By default `dwf` will use `Dwf::Workflow::BUILD_IN` callback.
47
41
 
48
42
  ### Execute flow
49
43
  ```ruby
50
- wf = TestWf.create
44
+ wf = TestWf.create(callback_type: Dwf::Workflow::SK_BATCH)
51
45
  wf.start!
52
46
  ```
53
47
 
48
+ #### Note
49
+ `dwf` supports 2 callback types `Dwf::Workflow::BUILD_IN` and `Dwf::Workflow::SK_BATCH`
50
+ - `Dwf::Workflow::BUILD_IN` is a build-in callback
51
+ - `Dwf::Workflow::SK_BATCH` is [sidekiq batch](https://github.com/mperham/sidekiq/wiki/Batches) callback which required [`sidekiq-pro`](https://sidekiq.org/products/pro.html)
52
+
53
+ By default `dwf` will use `Dwf::Workflow::BUILD_IN` callback.
54
+
54
55
  ### Output
55
56
  ```
56
57
  A Working
@@ -70,13 +71,62 @@ D say hello
70
71
  D Finished
71
72
  ```
72
73
 
74
+ # Config redis and default queue
75
+ `dwf` uses redis as the key value stograge through [redis-rb](https://github.com/redis/redis-rb), So you can pass redis configuration by `redis_opts`
76
+ ```ruby
77
+ Dwf.config do |config|
78
+ SENTINELS = [
79
+ { host: "127.0.0.1", port: 26380 },
80
+ { host: "127.0.0.1", port: 26381 }
81
+ ]
82
+ config.redis_opts = { host: 'mymaster', sentinels: SENTINELS, role: :master }
83
+ config.namespace = 'dwf'
84
+ end
85
+ ```
86
+
87
+ # Pinelining
88
+ You can pass jobs result to next nodes
89
+
90
+ ```ruby
91
+ class SendOutput < Dwf::Item
92
+ def perform
93
+ output('it works')
94
+ end
95
+ end
96
+
97
+ ```
98
+
99
+ `output` method used to output data from the job to add outgoing jobs
100
+
101
+ ```ruby
102
+ class ReceiveOutput < Dwf::Item
103
+ def perform
104
+ message = payloads.first[:output] # it works
105
+ end
106
+ end
107
+ ```
108
+
109
+ `payloads` is an array that containing outputs from incoming jobs
110
+
111
+ ```ruby
112
+ [
113
+ {
114
+ id: "SendOutput|1849a3f9-5fce-401e-a73a-91fc1048356",
115
+ class: "SendOutput",
116
+ output: 'it works'
117
+ }
118
+ ]
119
+ ```
120
+
73
121
  # Todo
74
122
  - [x] Make it work
75
123
  - [x] Support pass params
76
124
  - [x] Support with build-in callback
77
125
  - [x] Add github workflow
78
- - [ ] [WIF] Test
79
- - [ ] Transfer output through each node
126
+ - [x] Redis configurable
127
+ - [x] Pinelining
128
+ - [ ] [WIP] Test
129
+ - [ ] Support [Resque](https://github.com/resque/resque)
80
130
 
81
131
  # References
82
132
  - https://github.com/chaps-io/gush
data/dwf.gemspec CHANGED
@@ -6,7 +6,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
6
 
7
7
  Gem::Specification.new do |spec|
8
8
  spec.name = "dwf"
9
- spec.version = '0.1.5'
9
+ spec.version = '0.1.9'
10
10
  spec.authors = ["dthtien"]
11
11
  spec.email = ["tiendt2311@gmail.com"]
12
12
 
@@ -27,5 +27,6 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency 'byebug', '~> 11.1.3'
28
28
  spec.add_dependency 'redis', '~> 4.2.0'
29
29
  spec.add_development_dependency 'rspec', '~> 3.2'
30
+ spec.add_development_dependency 'mock_redis', '~> 0.27.2'
30
31
  spec.add_dependency 'sidekiq', '~> 6.2.0'
31
32
  end
data/lib/dwf/callback.rb CHANGED
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  require_relative 'client'
2
3
 
3
4
  module Dwf
4
5
  class Callback
6
+ DEFAULT_KEY = 'default_key'
7
+
5
8
  def process_next_step(status, options)
6
9
  previous_job_names = options['names']
7
10
  workflow_id = options['workflow_id']
@@ -12,7 +15,7 @@ module Dwf
12
15
  return if processing_job_names.empty?
13
16
 
14
17
  overall = Sidekiq::Batch.new(status.parent_bid)
15
- overall.jobs { setup_batch(processing_job_names, workflow_id) }
18
+ overall.jobs { setup_batches(processing_job_names, workflow_id) }
16
19
  end
17
20
 
18
21
  def start(job)
@@ -21,25 +24,45 @@ module Dwf
21
24
 
22
25
  private
23
26
 
24
- def setup_batch(processing_job_names, workflow_id)
27
+ def setup_batches(processing_job_names, workflow_id)
28
+ jobs = fetch_jobs(processing_job_names, workflow_id)
29
+ jobs_classification = classify_jobs jobs
30
+
31
+ jobs_classification.each do |key, batch_jobs|
32
+ with_lock workflow_id, key do
33
+ setup_batch(batch_jobs, workflow_id)
34
+ end
35
+ end
36
+ end
37
+
38
+ def setup_batch(jobs, workflow_id)
25
39
  batch = Sidekiq::Batch.new
26
40
  batch.on(
27
41
  :success,
28
42
  'Dwf::Callback#process_next_step',
29
- names: processing_job_names,
43
+ names: jobs.map(&:klass),
30
44
  workflow_id: workflow_id
31
45
  )
32
-
33
46
  batch.jobs do
34
- processing_job_names.each { |job_name| perform_job(job_name, workflow_id) }
47
+ jobs.each { |job| job.persist_and_perform_async! if job.ready_to_start? }
35
48
  end
36
49
  end
37
50
 
38
- def perform_job(job_name, workflow_id)
39
- with_lock workflow_id, job_name do
40
- job = client.find_job(workflow_id, job_name)
41
- job.persist_and_perform_async! if job.ready_to_start?
51
+ def classify_jobs(jobs)
52
+ hash = {}
53
+ jobs.each do |job|
54
+ outgoing_jobs = job.outgoing
55
+ key = outgoing_jobs.empty? ? DEFAULT_KEY : outgoing_jobs.join
56
+ hash[key] = hash[key].nil? ? [job] : hash[key].push(job)
42
57
  end
58
+
59
+ hash
60
+ end
61
+
62
+ def fetch_jobs(processing_job_names, workflow_id)
63
+ processing_job_names.map do |job_name|
64
+ client.find_job(workflow_id, job_name)
65
+ end.compact
43
66
  end
44
67
 
45
68
  def with_lock(workflow_id, job_name)
data/lib/dwf/client.rb CHANGED
@@ -1,5 +1,11 @@
1
1
  module Dwf
2
2
  class Client
3
+ attr_reader :config
4
+
5
+ def initialize(config = Dwf.configuration)
6
+ @config = config
7
+ end
8
+
3
9
  def find_job(workflow_id, job_name)
4
10
  job_name_match = /(?<klass>\w*[^-])-(?<identifier>.*)/.match(job_name)
5
11
  data = if job_name_match
@@ -94,7 +100,7 @@ module Dwf
94
100
  end
95
101
 
96
102
  def redis
97
- @redis ||= Redis.new
103
+ @redis ||= Redis.new(config.redis_opts)
98
104
  end
99
105
  end
100
106
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dwf
4
+ class Configuration
5
+ NAMESPACE = 'dwf'
6
+ REDIS_OPTS = { url: 'redis://localhost:6379' }.freeze
7
+
8
+ attr_accessor :redis_opts, :namespace
9
+
10
+ def initialize(hash = {})
11
+ @namespace = hash.fetch(:namespace, NAMESPACE)
12
+ @redis_opts = hash.fetch(:redis_opts, REDIS_OPTS)
13
+ end
14
+ end
15
+ end
data/lib/dwf/item.rb CHANGED
@@ -1,27 +1,15 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative 'client'
3
4
 
4
5
  module Dwf
5
6
  class Item
6
- DEFAULT_QUEUE = 'default'
7
-
8
7
  attr_reader :workflow_id, :id, :params, :queue, :klass, :started_at,
9
- :enqueued_at, :finished_at, :failed_at, :callback_type
8
+ :enqueued_at, :finished_at, :failed_at, :callback_type, :output_payload
10
9
  attr_accessor :incoming, :outgoing
11
10
 
12
11
  def initialize(options = {})
13
- @workflow_id = options[:workflow_id]
14
- @id = options[:id]
15
- @params = options[:params]
16
- @queue = options[:queue] || DEFAULT_QUEUE
17
- @incoming = options[:incoming] || []
18
- @outgoing = options[:outgoing] || []
19
- @klass = options[:klass] || self.class
20
- @failed_at = options[:failed_at]
21
- @finished_at = options[:finished_at]
22
- @enqueued_at = options[:enqueued_at]
23
- @started_at = options[:started_at]
24
- @callback_type = options[:callback_type]
12
+ assign_attributes(options)
25
13
  end
26
14
 
27
15
  def self.from_hash(hash)
@@ -40,14 +28,24 @@ module Dwf
40
28
  callback_type == Dwf::Workflow::BUILD_IN
41
29
  end
42
30
 
31
+ def reload
32
+ item = client.find_job(workflow_id, name)
33
+ assign_attributes(item.to_hash)
34
+ end
35
+
43
36
  def perform_async
44
- Dwf::Worker.set(queue: queue).perform_async(workflow_id, name)
37
+ Dwf::Worker.set(queue: queue || client.config.namespace)
38
+ .perform_async(workflow_id, name)
45
39
  end
46
40
 
47
41
  def name
48
42
  @name ||= "#{klass}|#{id}"
49
43
  end
50
44
 
45
+ def output(data)
46
+ @output_payload = data
47
+ end
48
+
51
49
  def no_dependencies?
52
50
  incoming.empty?
53
51
  end
@@ -58,6 +56,17 @@ module Dwf
58
56
  end
59
57
  end
60
58
 
59
+ def payloads
60
+ incoming.map do |job_name|
61
+ job = client.find_job(workflow_id, job_name)
62
+ {
63
+ id: job.name,
64
+ class: job.klass.to_s,
65
+ output: job.output_payload
66
+ }
67
+ end
68
+ end
69
+
61
70
  def enqueue!
62
71
  @enqueued_at = current_timestamp
63
72
  @started_at = nil
@@ -142,7 +151,8 @@ module Dwf
142
151
  failed_at: failed_at,
143
152
  params: params,
144
153
  workflow_id: workflow_id,
145
- callback_type: callback_type
154
+ callback_type: callback_type,
155
+ output_payload: output_payload
146
156
  }
147
157
  end
148
158
 
@@ -159,5 +169,21 @@ module Dwf
159
169
  def client
160
170
  @client ||= Dwf::Client.new
161
171
  end
172
+
173
+ def assign_attributes(options)
174
+ @workflow_id = options[:workflow_id]
175
+ @id = options[:id]
176
+ @params = options[:params]
177
+ @queue = options[:queue]
178
+ @incoming = options[:incoming] || []
179
+ @outgoing = options[:outgoing] || []
180
+ @klass = options[:klass] || self.class
181
+ @failed_at = options[:failed_at]
182
+ @finished_at = options[:finished_at]
183
+ @enqueued_at = options[:enqueued_at]
184
+ @started_at = options[:started_at]
185
+ @callback_type = options[:callback_type]
186
+ @output_payload = options[:output_payload]
187
+ end
162
188
  end
163
189
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dwf
4
+ VERSION = '0.1.8'
5
+ end
data/lib/dwf/worker.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'sidekiq'
2
4
  require_relative 'client'
3
5
 
@@ -7,7 +9,7 @@ module Dwf
7
9
 
8
10
  def perform(workflow_id, job_name)
9
11
  job = client.find_job(workflow_id, job_name)
10
- return job.enqueue_outgoing_jobs if job. succeeded?
12
+ return job.enqueue_outgoing_jobs if job.succeeded?
11
13
 
12
14
  job.mark_as_started
13
15
  job.perform
data/lib/dwf.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "bundler/setup"
3
4
 
4
5
  require 'sidekiq'
@@ -12,8 +13,15 @@ require_relative 'dwf/item'
12
13
  require_relative 'dwf/client'
13
14
  require_relative 'dwf/worker'
14
15
  require_relative 'dwf/callback'
16
+ require_relative 'dwf/configuration'
15
17
 
16
18
  module Dwf
17
- VERSION = '0.1.3'
19
+ def self.configuration
20
+ @configuration ||= Configuration.new
21
+ end
22
+
23
+ def self.config
24
+ yield configuration
25
+ end
18
26
  end
19
27
 
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'mock_redis'
5
+
6
+ describe Dwf::Client, client: true do
7
+ let(:client) { described_class.new }
8
+ let(:workflow_id) { SecureRandom.uuid }
9
+ let(:id) { SecureRandom.uuid }
10
+ let(:redis) { Redis.new }
11
+ before do
12
+ redis_instance = MockRedis.new
13
+ allow(Redis).to receive(:new).and_return redis_instance
14
+ end
15
+
16
+ describe '#find_job' do
17
+ let!(:job) do
18
+ j = Dwf::Item.new(workflow_id: workflow_id, id: id)
19
+ j.persist!
20
+ j
21
+ end
22
+
23
+ context 'find by item class name' do
24
+ it {
25
+ item = client.find_job(workflow_id, Dwf::Item.name)
26
+ expect(item.workflow_id).to eq workflow_id
27
+ expect(item.id).to eq id
28
+ expect(item.name).to eq job.name
29
+ }
30
+ end
31
+
32
+ context 'find by item name' do
33
+ it {
34
+ item = client.find_job(workflow_id, job.name)
35
+ expect(item.workflow_id).to eq workflow_id
36
+ expect(item.id).to eq id
37
+ expect(item.name).to eq job.name
38
+ }
39
+ end
40
+ end
41
+
42
+ describe '#persist_job' do
43
+ let!(:job) { Dwf::Item.new(workflow_id: workflow_id, id: id) }
44
+
45
+ it do
46
+ expect(redis.exists?("dwf.jobs.#{job.workflow_id}.#{job.klass}"))
47
+ .to be_falsy
48
+
49
+ client.persist_job(job)
50
+
51
+ expect(redis.exists?("dwf.jobs.#{job.workflow_id}.#{job.klass}"))
52
+ .to be_truthy
53
+ end
54
+ end
55
+
56
+ describe '#persist_workflow' do
57
+ let(:workflow) { Dwf::Workflow.new }
58
+
59
+ it do
60
+ expect(redis.exists?("dwf.workflows.#{workflow.id}")).to be_falsy
61
+ client.persist_workflow(workflow)
62
+ expect(redis.exists?("dwf.workflows.#{workflow.id}")).to be_truthy
63
+ end
64
+ end
65
+
66
+ describe '#check_or_lock' do
67
+ before do
68
+ allow_any_instance_of(described_class).to receive(:sleep)
69
+ end
70
+
71
+ context 'job is running' do
72
+ let(:job_name) { 'ahihi' }
73
+
74
+ before do
75
+ allow(client).to receive(:set)
76
+ redis.set("wf_enqueue_outgoing_jobs_#{workflow_id}-#{job_name}", 'running')
77
+ client.check_or_lock(workflow_id, job_name)
78
+ end
79
+
80
+ it { expect(client).not_to have_received(:set) }
81
+ end
82
+
83
+ context 'job is not running' do
84
+ let(:job_name) { 'ahihi' }
85
+
86
+ before do
87
+ allow(redis).to receive(:set)
88
+ client.check_or_lock(workflow_id, job_name)
89
+ end
90
+
91
+ it do
92
+ expect(redis).to have_received(:set)
93
+ .with("wf_enqueue_outgoing_jobs_#{workflow_id}-#{job_name}", 'running')
94
+ end
95
+ end
96
+ end
97
+
98
+ describe '#release_lock' do
99
+ before do
100
+ allow(redis).to receive(:del)
101
+ client.release_lock(workflow_id, 'ahihi')
102
+ end
103
+
104
+ it do
105
+ expect(redis).to have_received(:del)
106
+ .with("dwf_enqueue_outgoing_jobs_#{workflow_id}-ahihi")
107
+ end
108
+ end
109
+
110
+ describe '#build_job_id' do
111
+ before do
112
+ allow(redis).to receive(:hexists)
113
+ client.build_job_id(workflow_id, 'ahihi')
114
+ end
115
+
116
+ it { expect(redis).to have_received(:hexists) }
117
+ end
118
+
119
+ describe '#build_workflow_id' do
120
+ before do
121
+ allow(redis).to receive(:exists?)
122
+ client.build_workflow_id
123
+ end
124
+
125
+ it { expect(redis).to have_received(:exists?) }
126
+ end
127
+
128
+ describe '#key_exists?' do
129
+ before do
130
+ allow(redis).to receive(:exists?)
131
+ client.key_exists?('ahihi')
132
+ end
133
+
134
+ it { expect(redis).to have_received(:exists?).with('ahihi') }
135
+ end
136
+
137
+ describe '#set' do
138
+ before do
139
+ allow(redis).to receive(:set)
140
+ client.set('ahihi', 'a')
141
+ end
142
+
143
+ it { expect(redis).to have_received(:set).with('ahihi', 'a') }
144
+ end
145
+
146
+ describe '#delete' do
147
+ before do
148
+ allow(redis).to receive(:del)
149
+ client.delete('ahihi')
150
+ end
151
+
152
+ it { expect(redis).to have_received(:del).with('ahihi') }
153
+ end
154
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Dwf::Configuration, configuration: true do
6
+ let(:configuration) { described_class.new }
7
+
8
+ specify do
9
+ expect(configuration.namespace).to eq described_class::NAMESPACE
10
+ expect(configuration.redis_opts).to eq described_class::REDIS_OPTS
11
+ end
12
+ end
@@ -16,7 +16,7 @@ describe Dwf::Item, item: true do
16
16
  params: {},
17
17
  incoming: incoming,
18
18
  outgoing: outgoing,
19
- queue: Dwf::Item::DEFAULT_QUEUE,
19
+ queue: Dwf::Configuration::NAMESPACE,
20
20
  klass: 'Dwf::Item',
21
21
  started_at: started_at,
22
22
  finished_at: finished_at,
@@ -181,4 +181,40 @@ describe Dwf::Item, item: true do
181
181
  it { expect(a_item).not_to have_received(:persist_and_perform_async!) }
182
182
  end
183
183
  end
184
+
185
+ describe '#output' do
186
+ before { item.output(1) }
187
+
188
+ it { expect(item.output_payload).to eq 1 }
189
+ end
190
+
191
+ describe '#payloads' do
192
+ let(:incoming) { ["A|#{SecureRandom.uuid}"] }
193
+ let(:client_double) { double(find_job: nil) }
194
+ let!(:a_item) do
195
+ described_class.new(
196
+ workflow_id: SecureRandom.uuid,
197
+ id: SecureRandom.uuid,
198
+ finished_at: finished_at,
199
+ output_payload: 1
200
+ )
201
+ end
202
+
203
+ before do
204
+ allow(Dwf::Client).to receive(:new).and_return client_double
205
+ allow(client_double)
206
+ .to receive(:find_job).and_return a_item
207
+ end
208
+
209
+ it do
210
+ expected_payload = [
211
+ {
212
+ class: a_item.class.name,
213
+ id: a_item.name,
214
+ output: 1
215
+ }
216
+ ]
217
+ expect(item.payloads).to eq expected_payload
218
+ end
219
+ end
184
220
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'mock_redis'
5
+ require 'sidekiq/testing'
6
+
7
+ describe Dwf::Worker, client: true do
8
+ let(:workflow_id) { SecureRandom.uuid }
9
+ let(:id) { SecureRandom.uuid }
10
+ let(:redis) { Redis.new }
11
+ let(:worker) { described_class.perform_async(workflow_id, job.name) }
12
+ before do
13
+ redis_instance = MockRedis.new
14
+ allow(Redis).to receive(:new).and_return redis_instance
15
+ end
16
+
17
+ describe '#find_job' do
18
+ let!(:job) do
19
+ j = Dwf::Item.new(workflow_id: workflow_id, id: id)
20
+ j.persist!
21
+ j
22
+ end
23
+
24
+ before do
25
+ worker
26
+ Sidekiq::Worker.drain_all
27
+ job.reload
28
+ end
29
+
30
+ it { expect(job.finished?).to be_truthy }
31
+ end
32
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dwf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - dthtien
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-05 00:00:00.000000000 Z
11
+ date: 2021-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: byebug
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mock_redis
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.27.2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.27.2
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: sidekiq
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -78,6 +92,7 @@ files:
78
92
  - ".gitignore"
79
93
  - ".rspec"
80
94
  - ".ruby-version"
95
+ - CHANGELOG.md
81
96
  - Gemfile
82
97
  - LICENSE.txt
83
98
  - README.md
@@ -85,12 +100,17 @@ files:
85
100
  - lib/dwf.rb
86
101
  - lib/dwf/callback.rb
87
102
  - lib/dwf/client.rb
103
+ - lib/dwf/configuration.rb
88
104
  - lib/dwf/item.rb
89
105
  - lib/dwf/utils.rb
106
+ - lib/dwf/version.rb
90
107
  - lib/dwf/worker.rb
91
108
  - lib/dwf/workflow.rb
109
+ - spec/dwf/client_spec.rb
110
+ - spec/dwf/configuration_spec.rb
92
111
  - spec/dwf/item_spec.rb
93
112
  - spec/dwf/utils_spec.rb
113
+ - spec/dwf/worker_spec.rb
94
114
  - spec/spec_helper.rb
95
115
  homepage: https://github.com/dthtien/wf
96
116
  licenses:
@@ -117,6 +137,9 @@ specification_version: 4
117
137
  summary: Gush cloned without ActiveJob but requried Sidekiq. This project is for researching
118
138
  DSL purpose
119
139
  test_files:
140
+ - spec/dwf/client_spec.rb
141
+ - spec/dwf/configuration_spec.rb
120
142
  - spec/dwf/item_spec.rb
121
143
  - spec/dwf/utils_spec.rb
144
+ - spec/dwf/worker_spec.rb
122
145
  - spec/spec_helper.rb