startback-jobs 0.13.0
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 +7 -0
- data/Gemfile +4 -0
- data/Rakefile +18 -0
- data/lib/startback/ext/support/operation_runner.rb +17 -0
- data/lib/startback/ext/web/api.rb +12 -0
- data/lib/startback/ext.rb +2 -0
- data/lib/startback/jobs/agent.rb +15 -0
- data/lib/startback/jobs/api.rb +12 -0
- data/lib/startback/jobs/event/job_created.rb +8 -0
- data/lib/startback/jobs/event/job_ran.rb +8 -0
- data/lib/startback/jobs/event.rb +8 -0
- data/lib/startback/jobs/model/job.rb +35 -0
- data/lib/startback/jobs/model.rb +12 -0
- data/lib/startback/jobs/operation/create_job.rb +37 -0
- data/lib/startback/jobs/operation/run_job.rb +35 -0
- data/lib/startback/jobs/operation.rb +8 -0
- data/lib/startback/jobs/services.rb +25 -0
- data/lib/startback/jobs/support/job_result/embedded.rb +15 -0
- data/lib/startback/jobs/support/job_result/not_ready.rb +15 -0
- data/lib/startback/jobs/support/job_result/redirect.rb +32 -0
- data/lib/startback/jobs/support/job_result.rb +31 -0
- data/lib/startback/jobs/support.rb +1 -0
- data/lib/startback/jobs.fio +44 -0
- data/lib/startback/jobs.rb +23 -0
- data/spec/spec_helper.rb +42 -0
- data/spec/unit/api/test_job_result.rb +121 -0
- data/spec/unit/model/test_job.rb +23 -0
- data/spec/unit/operation/test_create_job.rb +42 -0
- data/spec/unit/operation/test_run_job.rb +37 -0
- data/spec/unit/test_finitio_schema.rb +20 -0
- data/tasks/test.rake +13 -0
- metadata +188 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 485b5ef6145820975b98f3f457c276c7b3fd824a0b63752e4688110c9935b642
|
4
|
+
data.tar.gz: 5cbadc773d07ea6108488e86a58d3cc9ce1e919fa23359ac87f340e94235610c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dddbd22a80647d96483a2e674a0e306e7414fb7cb445474571db569e8aff89e88178dbab5e5de5b29eaf4ce925f54b22df988d88d9e41c5e1fff96fe0a7cb796
|
7
|
+
data.tar.gz: 10de6fca4203d5e2ef706967545d3e24460c4593382a47b58e9fae2eeb240dce9ec19b213469e8a6ad05d87552e9aed5ee3314bcf6de4a453c330fd603f4742e
|
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$:.unshift File.expand_path('../lib', __FILE__)
|
2
|
+
|
3
|
+
def shell(*cmds)
|
4
|
+
cmd = cmds.join("\n")
|
5
|
+
puts cmd
|
6
|
+
system cmd
|
7
|
+
end
|
8
|
+
|
9
|
+
#
|
10
|
+
# Install all tasks found in tasks folder
|
11
|
+
#
|
12
|
+
# See .rake files there for complete documentation.
|
13
|
+
#
|
14
|
+
Dir["tasks/*.rake"].each do |taskfile|
|
15
|
+
load taskfile
|
16
|
+
end
|
17
|
+
|
18
|
+
task :default => :test
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Startback
|
2
|
+
module Support
|
3
|
+
module OperationRunner
|
4
|
+
|
5
|
+
def run_as_job(op)
|
6
|
+
run Startback::Jobs::CreateJob.new({
|
7
|
+
isReady: false,
|
8
|
+
opClass: op.class.name,
|
9
|
+
opInput: op.input,
|
10
|
+
opContext: context.to_h,
|
11
|
+
createdBy: '',
|
12
|
+
})
|
13
|
+
end
|
14
|
+
|
15
|
+
end # module OperationRunner
|
16
|
+
end # module Support
|
17
|
+
end # module Startback
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Startback
|
2
|
+
module Jobs
|
3
|
+
class Agent < Startback::Event::Agent
|
4
|
+
|
5
|
+
def install_listeners
|
6
|
+
async Event::JobCreated, 'job-runner'
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(event)
|
10
|
+
run RunJob.new(event.data.to_h)
|
11
|
+
end
|
12
|
+
|
13
|
+
end # class Agent
|
14
|
+
end # module Jobs
|
15
|
+
end # module Startback
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Startback
|
2
|
+
module Jobs
|
3
|
+
class Api < Startback::Web::Api
|
4
|
+
|
5
|
+
get %r{/([^\/]+)/result/?} do |id|
|
6
|
+
job = context.factor(Services).get_job!(id: id)
|
7
|
+
Support::JobResult.for(job).api_serve(self)
|
8
|
+
end
|
9
|
+
|
10
|
+
end # class Api
|
11
|
+
end # module Jobs
|
12
|
+
end # module Startback
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Startback
|
2
|
+
module Jobs
|
3
|
+
class Model
|
4
|
+
class Job < Model
|
5
|
+
def self.ref(data)
|
6
|
+
dress(data, 'Job.Ref')
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.full(data)
|
10
|
+
dress(data, 'Job.Full')
|
11
|
+
end
|
12
|
+
|
13
|
+
def ready?
|
14
|
+
self.isReady
|
15
|
+
end
|
16
|
+
|
17
|
+
def not_ready?
|
18
|
+
!ready?
|
19
|
+
end
|
20
|
+
|
21
|
+
def expired?
|
22
|
+
self.expiredAt && self.expiredAt < Time.now
|
23
|
+
end
|
24
|
+
|
25
|
+
def fully_consumed?
|
26
|
+
self.consumedMax && (self.consumedCount || 0 >= self.consumedMax)
|
27
|
+
end
|
28
|
+
|
29
|
+
def result
|
30
|
+
Support::JobResult.for(self)
|
31
|
+
end
|
32
|
+
end # class Job
|
33
|
+
end # class Model
|
34
|
+
end # module Jobs
|
35
|
+
end # module Startback
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Startback
|
2
|
+
module Jobs
|
3
|
+
class CreateJob < Operation
|
4
|
+
|
5
|
+
def initialize(input)
|
6
|
+
super(System['Job.CreationRequest'].dress(input))
|
7
|
+
end
|
8
|
+
|
9
|
+
def call
|
10
|
+
@job = Model::Job.full({
|
11
|
+
id: SecureRandom.urlsafe_base64(16),
|
12
|
+
opInput: {},
|
13
|
+
opContext: {},
|
14
|
+
opResult: nil,
|
15
|
+
strategy: 'NotReady',
|
16
|
+
strategyOptions: {},
|
17
|
+
expiresAt: nil,
|
18
|
+
refreshFreq: nil,
|
19
|
+
refreshedAt: nil,
|
20
|
+
consumeMax: nil,
|
21
|
+
consumeCount: 0,
|
22
|
+
createdAt: Time.now,
|
23
|
+
createdBy: nil,
|
24
|
+
}.merge(input))
|
25
|
+
|
26
|
+
context.world.startback_jobs.insert(@job.to_data)
|
27
|
+
|
28
|
+
@job
|
29
|
+
end
|
30
|
+
|
31
|
+
emits(Event::JobCreated) do
|
32
|
+
{ id: @job.id }
|
33
|
+
end
|
34
|
+
|
35
|
+
end # class CreateJob
|
36
|
+
end # module Jobs
|
37
|
+
end # module Startback
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Startback
|
2
|
+
module Jobs
|
3
|
+
class RunJob < Operation
|
4
|
+
|
5
|
+
def initialize(input)
|
6
|
+
super(System['Job.Ref'].dress(input))
|
7
|
+
end
|
8
|
+
|
9
|
+
def call
|
10
|
+
services = context.factor(Services)
|
11
|
+
@job = services.get_job!(input)
|
12
|
+
|
13
|
+
job_context = context.fork(@job.op_context)
|
14
|
+
job_class = ::Kernel.const_get(@job.op_class)
|
15
|
+
job_input = @job.op_input
|
16
|
+
|
17
|
+
op_result = with_context(job_context) do
|
18
|
+
run job_class.new(job_input)
|
19
|
+
end
|
20
|
+
|
21
|
+
services.update_job!(input, {
|
22
|
+
opResult: op_result,
|
23
|
+
isReady: true,
|
24
|
+
})
|
25
|
+
|
26
|
+
op_result
|
27
|
+
end
|
28
|
+
|
29
|
+
emits(Event::JobRan) do
|
30
|
+
{ id: @job.id }
|
31
|
+
end
|
32
|
+
|
33
|
+
end # class RunJob
|
34
|
+
end # module Jobs
|
35
|
+
end # module Startback
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Startback
|
2
|
+
module Jobs
|
3
|
+
class Services < Startback::Services
|
4
|
+
|
5
|
+
def get_job!(ref)
|
6
|
+
job_relvar = startback_jobs.restrict(ref)
|
7
|
+
Model::Job.full(job_relvar.one)
|
8
|
+
rescue Bmg::OneError
|
9
|
+
not_found_error!("Job #{ref[:id]}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def update_job!(ref, update)
|
13
|
+
job_relvar = startback_jobs.restrict(ref)
|
14
|
+
job_relvar.update(update)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def startback_jobs
|
20
|
+
context.world.startback_jobs
|
21
|
+
end
|
22
|
+
|
23
|
+
end # class Services
|
24
|
+
end # module Jobs
|
25
|
+
end # module Startback
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Startback
|
2
|
+
module Jobs
|
3
|
+
module Support
|
4
|
+
class JobResult
|
5
|
+
class Embedded < JobResult
|
6
|
+
|
7
|
+
def api_serve(api)
|
8
|
+
[200, {}, [job.opResult]]
|
9
|
+
end
|
10
|
+
|
11
|
+
end # class Embedded
|
12
|
+
end # class JobResult
|
13
|
+
end # module Support
|
14
|
+
end # module Jobs
|
15
|
+
end # module Startback
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Startback
|
2
|
+
module Jobs
|
3
|
+
module Support
|
4
|
+
class JobResult
|
5
|
+
class NotReady < JobResult
|
6
|
+
|
7
|
+
def api_serve(api)
|
8
|
+
[202, {}, []]
|
9
|
+
end
|
10
|
+
|
11
|
+
end # class NotReady
|
12
|
+
end # class JobResult
|
13
|
+
end # module Support
|
14
|
+
end # module Jobs
|
15
|
+
end # module Startback
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Startback
|
2
|
+
module Jobs
|
3
|
+
module Support
|
4
|
+
class JobResult
|
5
|
+
class Redirect < JobResult
|
6
|
+
|
7
|
+
DEFAULT_REDIRECT_OPTIONS = {
|
8
|
+
status: 301,
|
9
|
+
headers: {}
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
def api_serve(api)
|
13
|
+
options = redirect_options
|
14
|
+
[
|
15
|
+
options.status || 301,
|
16
|
+
options.headers.merge("Location" => job.opResult),
|
17
|
+
[]
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
def redirect_options
|
22
|
+
opts = DEFAULT_REDIRECT_OPTIONS.merge(
|
23
|
+
job.strategy_options
|
24
|
+
)
|
25
|
+
Startback::Model.new(opts)
|
26
|
+
end
|
27
|
+
|
28
|
+
end # class Embedded
|
29
|
+
end # class JobResult
|
30
|
+
end # module Support
|
31
|
+
end # module Jobs
|
32
|
+
end # module Startback
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Startback
|
2
|
+
module Jobs
|
3
|
+
module Support
|
4
|
+
class JobResult
|
5
|
+
|
6
|
+
def initialize(job)
|
7
|
+
@job = job
|
8
|
+
end
|
9
|
+
private :initialize
|
10
|
+
|
11
|
+
attr_reader :job
|
12
|
+
|
13
|
+
def self.for(job)
|
14
|
+
unless job.is_ready?
|
15
|
+
JobResult::NotReady.new(job)
|
16
|
+
else
|
17
|
+
JobResult.const_get(job.strategy).new(job)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def api_serve(api)
|
22
|
+
raise NotImplementedError
|
23
|
+
end
|
24
|
+
|
25
|
+
end # class JobResult
|
26
|
+
end # module Support
|
27
|
+
end # module Jobs
|
28
|
+
end # module Startback
|
29
|
+
require_relative 'job_result/not_ready'
|
30
|
+
require_relative 'job_result/embedded'
|
31
|
+
require_relative 'job_result/redirect'
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'support/job_result'
|
@@ -0,0 +1,44 @@
|
|
1
|
+
@import finitio/data
|
2
|
+
|
3
|
+
ClassName = String
|
4
|
+
|
5
|
+
DumpableHash = { ...: .Object }
|
6
|
+
|
7
|
+
Job.Ref = {
|
8
|
+
id : String
|
9
|
+
}
|
10
|
+
|
11
|
+
Job.Strategy = String(s | %w{Embedded NotReady Redirect}.include? s )
|
12
|
+
|
13
|
+
Job.Full = {
|
14
|
+
id : String
|
15
|
+
opClass : ClassName
|
16
|
+
opInput : DumpableHash
|
17
|
+
opContext : DumpableHash
|
18
|
+
opResult : .
|
19
|
+
isReady : Boolean
|
20
|
+
strategy : Job.Strategy
|
21
|
+
strategyOptions : DumpableHash
|
22
|
+
expiresAt : DateTime|Time|Nil
|
23
|
+
refreshFreq : String|Nil
|
24
|
+
refreshedAt : DateTime|Time|Nil
|
25
|
+
consumeMax : Integer|Nil
|
26
|
+
consumeCount : Integer|Nil
|
27
|
+
createdAt : DateTime|Time|Nil
|
28
|
+
createdBy : String|Nil
|
29
|
+
}
|
30
|
+
|
31
|
+
Job.CreationRequest = {
|
32
|
+
opClass : ClassName
|
33
|
+
opInput : DumpableHash
|
34
|
+
opContext : DumpableHash
|
35
|
+
createdBy : String
|
36
|
+
|
37
|
+
isReady : Boolean
|
38
|
+
strategy :? Job.Strategy
|
39
|
+
strategyOptions :? DumpableHash
|
40
|
+
|
41
|
+
expiresAt :? DateTime|Time
|
42
|
+
refreshFreq :? String
|
43
|
+
consumeMax :? Integer
|
44
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'path'
|
2
|
+
require 'finitio'
|
3
|
+
require 'startback'
|
4
|
+
require 'startback/event'
|
5
|
+
require 'startback/web/api'
|
6
|
+
|
7
|
+
module Startback
|
8
|
+
module Jobs
|
9
|
+
require_relative 'jobs/support'
|
10
|
+
require_relative 'jobs/model'
|
11
|
+
require_relative 'jobs/event'
|
12
|
+
require_relative 'jobs/operation'
|
13
|
+
require_relative 'jobs/services'
|
14
|
+
require_relative 'jobs/api'
|
15
|
+
require_relative 'jobs/agent'
|
16
|
+
|
17
|
+
require_relative './ext'
|
18
|
+
|
19
|
+
Finitio.stdlib_path(Path.dir.parent)
|
20
|
+
|
21
|
+
System = Finitio.system(Path.dir/'jobs.fio')
|
22
|
+
end
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
require 'startback'
|
3
|
+
require 'startback/jobs'
|
4
|
+
require 'rack/test'
|
5
|
+
require 'bmg'
|
6
|
+
|
7
|
+
module SpecHelpers
|
8
|
+
end
|
9
|
+
|
10
|
+
RSpec.configure do |c|
|
11
|
+
c.include SpecHelpers
|
12
|
+
|
13
|
+
def a_job_data(override = {})
|
14
|
+
{
|
15
|
+
id: 'abcdef',
|
16
|
+
isReady: false,
|
17
|
+
opClass: 'CowSay',
|
18
|
+
opInput: { 'message' => 'Hello !!' },
|
19
|
+
opContext: {},
|
20
|
+
opResult: nil,
|
21
|
+
strategy: 'NotReady',
|
22
|
+
strategyOptions: {},
|
23
|
+
expiresAt: nil,
|
24
|
+
refreshFreq: nil,
|
25
|
+
refreshedAt: nil,
|
26
|
+
consumeMax: nil,
|
27
|
+
consumeCount: 0,
|
28
|
+
createdAt: DateTime.now,
|
29
|
+
createdBy: 'blambeau',
|
30
|
+
}.merge(override)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class CowSay < Startback::Operation
|
35
|
+
def initialize(input)
|
36
|
+
@input = Startback::Model.new(input)
|
37
|
+
end
|
38
|
+
|
39
|
+
def call
|
40
|
+
input.message
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Startback
|
4
|
+
module Jobs
|
5
|
+
describe Api, "GET /{id}/result/" do
|
6
|
+
include Rack::Test::Methods
|
7
|
+
|
8
|
+
let(:job_data) do
|
9
|
+
a_job_data(override)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:jobs_relvar) do
|
13
|
+
Bmg.mutable([job_data])
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:context) do
|
17
|
+
Context.new.with_world(startback_jobs: jobs_relvar)
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:app) do
|
21
|
+
context = self.context
|
22
|
+
Rack::Builder.new do
|
23
|
+
use Context::Middleware, context
|
24
|
+
run Jobs::Api
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:job_id) do
|
29
|
+
'abcdef'
|
30
|
+
end
|
31
|
+
|
32
|
+
subject do
|
33
|
+
get "/#{job_id}/result/"
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when the job does not exist' do
|
37
|
+
let(:job_id) do
|
38
|
+
"no-such-one"
|
39
|
+
end
|
40
|
+
|
41
|
+
let(:override) do
|
42
|
+
{}
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'raises' do
|
46
|
+
expect{
|
47
|
+
subject
|
48
|
+
}.to raise_error(Startback::Errors::NotFoundError)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'when the job is not ready yet' do
|
53
|
+
let(:override) do
|
54
|
+
{
|
55
|
+
isReady: false,
|
56
|
+
strategy: 'NotReady',
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'works fine' do
|
61
|
+
res = subject
|
62
|
+
expect(res.status).to eql(202)
|
63
|
+
expect(res.body).to be_empty
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when the job is ready' do
|
68
|
+
let(:override) do
|
69
|
+
{
|
70
|
+
isReady: true,
|
71
|
+
opResult: 'Hello!!',
|
72
|
+
strategy: 'Embedded'
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'works fine' do
|
77
|
+
res = subject
|
78
|
+
expect(res.status).to eql(200)
|
79
|
+
expect(res.body).to eql("Hello!!")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when the job is ready and has to redirect' do
|
84
|
+
let(:override) do
|
85
|
+
{
|
86
|
+
isReady: true,
|
87
|
+
strategy: 'Redirect',
|
88
|
+
opResult: 'http://google.com',
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'works fine' do
|
93
|
+
res = subject
|
94
|
+
expect(res.status).to eql(301)
|
95
|
+
expect(res['Location']).to eql("http://google.com")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'when the job is ready and has to redirect with a 302' do
|
100
|
+
let(:override) do
|
101
|
+
{
|
102
|
+
isReady: true,
|
103
|
+
strategy: 'Redirect',
|
104
|
+
strategyOptions: {
|
105
|
+
'status' => 302,
|
106
|
+
'headers' => { 'X-Mine' => 'foo' }
|
107
|
+
},
|
108
|
+
opResult: 'http://google.com',
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'works fine' do
|
113
|
+
res = subject
|
114
|
+
expect(res.status).to eql(302)
|
115
|
+
expect(res['X-Mine']).to eql('foo')
|
116
|
+
expect(res['Location']).to eql("http://google.com")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Startback
|
4
|
+
module Jobs
|
5
|
+
class Model
|
6
|
+
describe Job do
|
7
|
+
it 'makes it easy to create an instance' do
|
8
|
+
job = Job.new(a_job_data)
|
9
|
+
expect(job.id).to eql('abcdef')
|
10
|
+
expect(job[:id]).to eql('abcdef')
|
11
|
+
expect(job.ready?).to eql(false)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'makes it easy to dress an instance' do
|
15
|
+
job = Job.full(a_job_data)
|
16
|
+
expect(job.id).to eql('abcdef')
|
17
|
+
expect(job[:id]).to eql('abcdef')
|
18
|
+
expect(job.ready?).to eql(false)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Startback
|
4
|
+
module Jobs
|
5
|
+
describe CreateJob do
|
6
|
+
|
7
|
+
let(:request) do
|
8
|
+
{
|
9
|
+
isReady: false,
|
10
|
+
opClass: 'CowSay',
|
11
|
+
opInput: {},
|
12
|
+
opContext: {},
|
13
|
+
createdBy: 'blambeau',
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:jobs_relvar) do
|
18
|
+
Bmg.mutable([])
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:context) do
|
22
|
+
Context.new.with_world(startback_jobs: jobs_relvar)
|
23
|
+
end
|
24
|
+
|
25
|
+
subject do
|
26
|
+
CreateJob.new(request).bind({
|
27
|
+
context: context,
|
28
|
+
}).call
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'creates a job' do
|
32
|
+
expect(subject).to be_a(Model::Job)
|
33
|
+
expect(subject.id).not_to be_nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'inserts the job in the relvar' do
|
37
|
+
subject
|
38
|
+
expect(jobs_relvar.count).to eql(1)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Startback
|
4
|
+
module Jobs
|
5
|
+
describe RunJob do
|
6
|
+
|
7
|
+
let(:job_data) do
|
8
|
+
a_job_data
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:jobs_relvar) do
|
12
|
+
Bmg.mutable([job_data])
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:context) do
|
16
|
+
Context.new.with_world(startback_jobs: jobs_relvar)
|
17
|
+
end
|
18
|
+
|
19
|
+
subject do
|
20
|
+
RunJob.new(id: 'abcdef').bind({
|
21
|
+
context: context,
|
22
|
+
}).call
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'runs the job' do
|
26
|
+
expect(subject).to eql('Hello !!')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'updates the job' do
|
30
|
+
subject
|
31
|
+
job_info = jobs_relvar.one
|
32
|
+
expect(job_info[:opResult]).to eql('Hello !!')
|
33
|
+
expect(job_info[:isReady]).to eql(true)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Startback
|
4
|
+
module Jobs
|
5
|
+
describe 'Finitio schemas' do
|
6
|
+
|
7
|
+
it 'is correctly installed on stdlib' do
|
8
|
+
system = Finitio.system <<~FIO
|
9
|
+
@import startback/jobs
|
10
|
+
|
11
|
+
Job.Ref
|
12
|
+
FIO
|
13
|
+
expect {
|
14
|
+
system.dress({ id: "hello" })
|
15
|
+
}.not_to raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/tasks/test.rake
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
|
3
|
+
namespace :test do
|
4
|
+
|
5
|
+
desc "Run RSpec unit tests"
|
6
|
+
RSpec::Core::RakeTask.new(:unit) do |t|
|
7
|
+
t.pattern = "spec/unit/**/test_*.rb"
|
8
|
+
t.rspec_opts = %{-Ilib -Ispec --color --backtrace --format progress --format RspecJunitFormatter --out spec/rspec-unit.xml}
|
9
|
+
end
|
10
|
+
|
11
|
+
task :all => [:unit]
|
12
|
+
end
|
13
|
+
task :test => :'test:all'
|
metadata
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: startback-jobs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.13.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bernard Lambeau
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-05-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.6'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '4.0'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.6'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '4.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rspec_junit_formatter
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.4.1
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0.5'
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 0.4.1
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0.5'
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: webspicy
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 0.20.5
|
60
|
+
- - "<"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0.21'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.20.5
|
70
|
+
- - "<"
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0.21'
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: rake
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
type: :development
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: rack-test
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
type: :development
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: bmg
|
103
|
+
requirement: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
type: :development
|
109
|
+
prerelease: false
|
110
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: startback
|
117
|
+
requirement: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - '='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: 0.13.0
|
122
|
+
type: :runtime
|
123
|
+
prerelease: false
|
124
|
+
version_requirements: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - '='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: 0.13.0
|
129
|
+
description: Asynchronous jobs on top of the Startback framework
|
130
|
+
email: blambeau@gmail.com
|
131
|
+
executables: []
|
132
|
+
extensions: []
|
133
|
+
extra_rdoc_files: []
|
134
|
+
files:
|
135
|
+
- Gemfile
|
136
|
+
- Rakefile
|
137
|
+
- lib/startback/ext.rb
|
138
|
+
- lib/startback/ext/support/operation_runner.rb
|
139
|
+
- lib/startback/ext/web/api.rb
|
140
|
+
- lib/startback/jobs.fio
|
141
|
+
- lib/startback/jobs.rb
|
142
|
+
- lib/startback/jobs/agent.rb
|
143
|
+
- lib/startback/jobs/api.rb
|
144
|
+
- lib/startback/jobs/event.rb
|
145
|
+
- lib/startback/jobs/event/job_created.rb
|
146
|
+
- lib/startback/jobs/event/job_ran.rb
|
147
|
+
- lib/startback/jobs/model.rb
|
148
|
+
- lib/startback/jobs/model/job.rb
|
149
|
+
- lib/startback/jobs/operation.rb
|
150
|
+
- lib/startback/jobs/operation/create_job.rb
|
151
|
+
- lib/startback/jobs/operation/run_job.rb
|
152
|
+
- lib/startback/jobs/services.rb
|
153
|
+
- lib/startback/jobs/support.rb
|
154
|
+
- lib/startback/jobs/support/job_result.rb
|
155
|
+
- lib/startback/jobs/support/job_result/embedded.rb
|
156
|
+
- lib/startback/jobs/support/job_result/not_ready.rb
|
157
|
+
- lib/startback/jobs/support/job_result/redirect.rb
|
158
|
+
- spec/spec_helper.rb
|
159
|
+
- spec/unit/api/test_job_result.rb
|
160
|
+
- spec/unit/model/test_job.rb
|
161
|
+
- spec/unit/operation/test_create_job.rb
|
162
|
+
- spec/unit/operation/test_run_job.rb
|
163
|
+
- spec/unit/test_finitio_schema.rb
|
164
|
+
- tasks/test.rake
|
165
|
+
homepage: http://www.enspirit.be
|
166
|
+
licenses:
|
167
|
+
- MIT
|
168
|
+
metadata: {}
|
169
|
+
post_install_message:
|
170
|
+
rdoc_options: []
|
171
|
+
require_paths:
|
172
|
+
- lib
|
173
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
requirements: []
|
184
|
+
rubygems_version: 3.3.7
|
185
|
+
signing_key:
|
186
|
+
specification_version: 4
|
187
|
+
summary: Asynchronous jobs on top of Startback
|
188
|
+
test_files: []
|