zenaton 0.4.2 → 0.5.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 +4 -4
- data/.circleci/config.yml +79 -52
- data/.gitignore +7 -0
- data/.rubocop.yml +4 -0
- data/Appraisals +13 -0
- data/CHANGELOG.md +17 -1
- data/Gemfile.lock +17 -8
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/rails_5.0.gemfile +7 -0
- data/gemfiles/rails_5.1.gemfile +7 -0
- data/gemfiles/rails_5.2.gemfile +7 -0
- data/lib/zenaton/client.rb +63 -0
- data/lib/zenaton/contexts.rb +7 -0
- data/lib/zenaton/contexts/task.rb +33 -0
- data/lib/zenaton/contexts/workflow.rb +17 -0
- data/lib/zenaton/engine.rb +16 -0
- data/lib/zenaton/interfaces/task.rb +30 -1
- data/lib/zenaton/interfaces/workflow.rb +15 -0
- data/lib/zenaton/refinements.rb +16 -0
- data/lib/zenaton/refinements/big_decimal.rb +25 -0
- data/lib/zenaton/refinements/class.rb +21 -0
- data/lib/zenaton/refinements/complex.rb +22 -0
- data/lib/zenaton/refinements/date.rb +26 -0
- data/lib/zenaton/refinements/date_time.rb +40 -0
- data/lib/zenaton/refinements/exception.rb +24 -0
- data/lib/zenaton/refinements/object.rb +15 -0
- data/lib/zenaton/refinements/open_struct.rb +26 -0
- data/lib/zenaton/refinements/range.rb +21 -0
- data/lib/zenaton/refinements/rational.rb +22 -0
- data/lib/zenaton/refinements/regexp.rb +22 -0
- data/lib/zenaton/refinements/struct.rb +24 -0
- data/lib/zenaton/refinements/symbol.rb +21 -0
- data/lib/zenaton/refinements/time.rb +32 -0
- data/lib/zenaton/services/graphql.rb +71 -0
- data/lib/zenaton/services/http.rb +14 -9
- data/lib/zenaton/services/properties.rb +11 -57
- data/lib/zenaton/services/serializer.rb +2 -0
- data/lib/zenaton/traits/with_timestamp.rb +4 -2
- data/lib/zenaton/traits/zenatonable.rb +9 -0
- data/lib/zenaton/version.rb +1 -1
- data/zenaton.gemspec +2 -0
- metadata +54 -2
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zenaton
|
4
|
+
module Contexts
|
5
|
+
# Represents the current runtime context of a Task.
|
6
|
+
#
|
7
|
+
# The information provided by the context can be useful to alter the
|
8
|
+
# behaviour of the task.
|
9
|
+
#
|
10
|
+
# For example, you can use the attempt index to know if a task has been
|
11
|
+
# automatically retried or not and how many times, and decide to do
|
12
|
+
# something when you did not expect the task to be retried more than X
|
13
|
+
# times.
|
14
|
+
#
|
15
|
+
# You can also use the attempt number in the `on_error_retry_delay` method
|
16
|
+
# of a task in order to implement complex retry strategies.
|
17
|
+
class Task
|
18
|
+
# @return [String] The UUID identifying the current task
|
19
|
+
attr_reader :id
|
20
|
+
|
21
|
+
# @return [Integer] The number of times this task has been automatically
|
22
|
+
# retried. This counter is reset if you issue a manual retry from your
|
23
|
+
# dashboard
|
24
|
+
attr_reader :retry_index
|
25
|
+
|
26
|
+
# @return [Zenaton::Contexts::Task] a new execution context for a task
|
27
|
+
def initialize(**kwargs)
|
28
|
+
@id = kwargs[:id]
|
29
|
+
@retry_index = kwargs[:retry_index]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zenaton
|
4
|
+
module Contexts
|
5
|
+
# Represents the current runtime context of a Workflow.
|
6
|
+
class Workflow
|
7
|
+
# @return [String] The UUID identifying the current workflow
|
8
|
+
attr_reader :id
|
9
|
+
|
10
|
+
# @return [Zenaton::Contexts::Workflow] a new execution context for a
|
11
|
+
# workflow
|
12
|
+
def initialize(**kwargs)
|
13
|
+
@id = kwargs[:id]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/zenaton/engine.rb
CHANGED
@@ -24,6 +24,22 @@ module Zenaton
|
|
24
24
|
@processor = nil
|
25
25
|
end
|
26
26
|
|
27
|
+
# Executes scheduling jobs synchronously
|
28
|
+
# @param jobs [Array<Zenaton::Interfaces::Job>]
|
29
|
+
# @param cron String
|
30
|
+
# @return [Array<String>, nil] the results if executed locally, or nil
|
31
|
+
def schedule(jobs, cron)
|
32
|
+
jobs.map(&method(:check_argument))
|
33
|
+
jobs.map do |job|
|
34
|
+
if job.is_a? Interfaces::Workflow
|
35
|
+
@client.start_scheduled_workflow(job, cron)
|
36
|
+
else
|
37
|
+
@client.start_scheduled_task(job, cron)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
|
27
43
|
# Executes jobs synchronously
|
28
44
|
# @param jobs [Array<Zenaton::Interfaces::Job>]
|
29
45
|
# @return [Array<String>, nil] the results if executed locally, or nil
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'zenaton/interfaces/job'
|
4
|
+
require 'zenaton/contexts/task'
|
4
5
|
|
5
6
|
module Zenaton
|
6
7
|
module Interfaces
|
@@ -9,7 +10,35 @@ module Zenaton
|
|
9
10
|
# Child classes should implement the handle method
|
10
11
|
def handle
|
11
12
|
raise NotImplemented,
|
12
|
-
"Your workflow does not implement the
|
13
|
+
"Your workflow does not implement the `#handle' method"
|
14
|
+
end
|
15
|
+
|
16
|
+
# (Optional) Implement this method for automatic retrial of task in
|
17
|
+
# case of failures.
|
18
|
+
# @param _exception [Exception] the reason for the task failure.
|
19
|
+
# @return [Integer, FalseClass, NilClass] the non-negative amount of
|
20
|
+
# seconds to wait before automatically retrying this task. Falsy values
|
21
|
+
# will avoid retrial. Other values will cause the retrial to fail.
|
22
|
+
def on_error_retry_delay(_exception)
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Zenaton::Contexts::Task] the task execution context
|
27
|
+
def context
|
28
|
+
@context || Contexts::Task.new
|
29
|
+
end
|
30
|
+
|
31
|
+
# @private
|
32
|
+
# Sets a new context if none has been set yet.
|
33
|
+
# This is called from the zenaton agent and will raise if called twice.
|
34
|
+
# @raise [ArgumentError] when the context was already set.
|
35
|
+
def add_context(**attributes)
|
36
|
+
message = <<~ERROR
|
37
|
+
Context has already been set and cannot be mutated.
|
38
|
+
ERROR
|
39
|
+
raise ArgumentError, message if @context
|
40
|
+
|
41
|
+
@context = Contexts::Task.new(attributes)
|
13
42
|
end
|
14
43
|
end
|
15
44
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'zenaton/interfaces/job'
|
4
|
+
require 'zenaton/contexts/workflow'
|
4
5
|
|
5
6
|
module Zenaton
|
6
7
|
module Interfaces
|
@@ -18,6 +19,20 @@ module Zenaton
|
|
18
19
|
def id
|
19
20
|
nil
|
20
21
|
end
|
22
|
+
|
23
|
+
# @return [Zenaton::Contexts::Workflow] the workflow execution context
|
24
|
+
def context
|
25
|
+
@context || Contexts::Workflow.new
|
26
|
+
end
|
27
|
+
|
28
|
+
# @private
|
29
|
+
# Sets a new context if none has been set yet.
|
30
|
+
# This is called from the zenaton agent and will raise if called twice.
|
31
|
+
# @raise [ArgumentError] when the context was already set.
|
32
|
+
def add_context(**attributes)
|
33
|
+
raise ArgumentError if @context
|
34
|
+
@context = Contexts::Workflow.new(attributes)
|
35
|
+
end
|
21
36
|
end
|
22
37
|
end
|
23
38
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'zenaton/refinements/big_decimal'
|
4
|
+
require 'zenaton/refinements/class'
|
5
|
+
require 'zenaton/refinements/complex'
|
6
|
+
require 'zenaton/refinements/date'
|
7
|
+
require 'zenaton/refinements/date_time'
|
8
|
+
require 'zenaton/refinements/exception'
|
9
|
+
require 'zenaton/refinements/object'
|
10
|
+
require 'zenaton/refinements/open_struct'
|
11
|
+
require 'zenaton/refinements/range'
|
12
|
+
require 'zenaton/refinements/rational'
|
13
|
+
require 'zenaton/refinements/regexp'
|
14
|
+
require 'zenaton/refinements/struct'
|
15
|
+
require 'zenaton/refinements/symbol'
|
16
|
+
require 'zenaton/refinements/time'
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Style/AndOr
|
4
|
+
defined?(::BigDecimal) or require 'bigdecimal'
|
5
|
+
# rubocop:enable Style/AndOr
|
6
|
+
|
7
|
+
module Zenaton
|
8
|
+
# :nodoc
|
9
|
+
module Refinements
|
10
|
+
refine BigDecimal do
|
11
|
+
def to_zenaton
|
12
|
+
{
|
13
|
+
'b' => _dump
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Reimplements `json/add/bigdecimal`
|
21
|
+
class BigDecimal
|
22
|
+
def self.from_zenaton(props)
|
23
|
+
BigDecimal._load props['b']
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zenaton
|
4
|
+
# :nodoc
|
5
|
+
module Refinements
|
6
|
+
refine Class do
|
7
|
+
def to_zenaton
|
8
|
+
{
|
9
|
+
'n' => name
|
10
|
+
}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Load an instance of class from zenaton properties
|
17
|
+
class Class
|
18
|
+
def self.from_zenaton(props)
|
19
|
+
Object.const_get(props['n'])
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zenaton
|
4
|
+
# :nodoc
|
5
|
+
module Refinements
|
6
|
+
refine Complex do
|
7
|
+
def to_zenaton
|
8
|
+
{
|
9
|
+
'r' => real,
|
10
|
+
'i' => imag
|
11
|
+
}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Reimplements `json/add/complex`
|
18
|
+
class Complex
|
19
|
+
def self.from_zenaton(props)
|
20
|
+
Complex(props['r'], props['i'])
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
module Zenaton
|
6
|
+
# :nodoc
|
7
|
+
module Refinements
|
8
|
+
refine Date do
|
9
|
+
def to_zenaton
|
10
|
+
{
|
11
|
+
'y' => year,
|
12
|
+
'm' => month,
|
13
|
+
'd' => day,
|
14
|
+
'sg' => start
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Reimplements `json/add/date`
|
22
|
+
class Date
|
23
|
+
def self.from_zenaton(props)
|
24
|
+
civil(*props.values_at('y', 'm', 'd', 'sg'))
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
module Zenaton
|
6
|
+
# :nodoc
|
7
|
+
module Refinements
|
8
|
+
refine DateTime do
|
9
|
+
def to_zenaton
|
10
|
+
{
|
11
|
+
'y' => year,
|
12
|
+
'm' => month,
|
13
|
+
'd' => day,
|
14
|
+
'H' => hour,
|
15
|
+
'M' => min,
|
16
|
+
'S' => sec,
|
17
|
+
'of' => offset.to_s,
|
18
|
+
'sg' => start
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Reimplements `json/add/date_time`
|
26
|
+
class DateTime
|
27
|
+
def self.from_zenaton(props)
|
28
|
+
args = props.values_at('y', 'm', 'd', 'H', 'M', 'S')
|
29
|
+
of_a, of_b = props['of'].split('/')
|
30
|
+
# rubocop:disable Style/ConditionalAssignment
|
31
|
+
if of_b && of_b != '0'
|
32
|
+
args << Rational(of_a.to_i, of_b.to_i)
|
33
|
+
else
|
34
|
+
args << of_a
|
35
|
+
end
|
36
|
+
# rubocop:enable Style/ConditionalAssignment
|
37
|
+
args << props['sg']
|
38
|
+
civil(*args)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zenaton
|
4
|
+
# :nodoc
|
5
|
+
module Refinements
|
6
|
+
refine Exception do
|
7
|
+
def to_zenaton
|
8
|
+
{
|
9
|
+
'm' => message,
|
10
|
+
'b' => backtrace
|
11
|
+
}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Reimplements `json/add/exception`
|
18
|
+
class Exception
|
19
|
+
def self.from_zenaton(props)
|
20
|
+
result = new(props['m'])
|
21
|
+
result.set_backtrace props['b']
|
22
|
+
result
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
module Zenaton
|
6
|
+
# :nodoc
|
7
|
+
module Refinements
|
8
|
+
refine OpenStruct do
|
9
|
+
def to_zenaton
|
10
|
+
class_name = self.class.name.to_s
|
11
|
+
error_message = 'Only named structs are supported'
|
12
|
+
raise ArgumentError, error_message if class_name.empty?
|
13
|
+
{
|
14
|
+
't' => table
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Reimplements `json/add/ostruct`
|
22
|
+
class OpenStruct
|
23
|
+
def self.from_zenaton(props)
|
24
|
+
new(props['t'] || props[:t])
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zenaton
|
4
|
+
# :nodoc
|
5
|
+
module Refinements
|
6
|
+
refine Range do
|
7
|
+
def to_zenaton
|
8
|
+
{
|
9
|
+
'a' => [first, last, exclude_end?]
|
10
|
+
}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Reimplements `json/add/range`
|
17
|
+
class Range
|
18
|
+
def self.from_zenaton(props)
|
19
|
+
new(*props['a'])
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zenaton
|
4
|
+
# :nodoc
|
5
|
+
module Refinements
|
6
|
+
refine Rational do
|
7
|
+
def to_zenaton
|
8
|
+
{
|
9
|
+
'n' => numerator,
|
10
|
+
'd' => denominator
|
11
|
+
}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Reimplements `json/add/rational`
|
18
|
+
class Rational
|
19
|
+
def self.from_zenaton(props)
|
20
|
+
Rational(props['n'], props['d'])
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zenaton
|
4
|
+
# :nodoc
|
5
|
+
module Refinements
|
6
|
+
refine Regexp do
|
7
|
+
def to_zenaton
|
8
|
+
{
|
9
|
+
'o' => options,
|
10
|
+
's' => source
|
11
|
+
}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Reimplements `json/add/regexp`
|
18
|
+
class Regexp
|
19
|
+
def self.from_zenaton(props)
|
20
|
+
new(props['s'], props['o'])
|
21
|
+
end
|
22
|
+
end
|