startback-jobs 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|