zenaton 0.2.0 → 0.2.1
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/Gemfile.lock +3 -3
- data/README.md +74 -2
- data/lib/zenaton/services/properties.rb +35 -61
- data/lib/zenaton/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a6590eba29150d752565e62505dbbf6ec2a6a0a66f3867e853d76dd102e0991
|
4
|
+
data.tar.gz: dc34cb351261f71e21c4ee692b11622c794a9827e53b5344ed1b1728b1cfd046
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71b975257fc54acf682d52c4b5fc4be318c7bd50f5b1dd81045277021d2f3d8a9eaf53c7822157d9decee33f0f8049d57d29ad7cdc6f3e2219d45fe1fd2a8540
|
7
|
+
data.tar.gz: 92fee9e3987c2e13f36f75cf68dbe6aa8995e608825732f8091a5e04ed1341e022b12b8808f0fc51c96908ea680eacfbc62f36ddda1483962a3eac948dd517c0
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
zenaton (0.2.
|
4
|
+
zenaton (0.2.1)
|
5
5
|
activesupport
|
6
6
|
httparty
|
7
7
|
tzinfo-data
|
@@ -9,7 +9,7 @@ PATH
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
activesupport (5.2.
|
12
|
+
activesupport (5.2.1)
|
13
13
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
14
14
|
i18n (>= 0.7, < 2)
|
15
15
|
minitest (~> 5.1)
|
@@ -26,7 +26,7 @@ GEM
|
|
26
26
|
hashdiff (0.3.7)
|
27
27
|
httparty (0.16.2)
|
28
28
|
multi_xml (>= 0.5.2)
|
29
|
-
i18n (1.0
|
29
|
+
i18n (1.1.0)
|
30
30
|
concurrent-ruby (~> 1.0)
|
31
31
|
jaro_winkler (1.5.1)
|
32
32
|
json (2.1.0)
|
data/README.md
CHANGED
@@ -27,9 +27,9 @@ Or install it yourself as:
|
|
27
27
|
|
28
28
|
$ gem install zenaton
|
29
29
|
|
30
|
-
## Usage
|
30
|
+
## Usage in plain Ruby
|
31
31
|
|
32
|
-
For more detailed examples, please check [Zenaton Ruby examples](https://github.com/zenaton/
|
32
|
+
For more detailed examples, please check [Zenaton Ruby examples](https://github.com/zenaton/examples-ruby).
|
33
33
|
|
34
34
|
### Client Initialization
|
35
35
|
|
@@ -93,6 +93,78 @@ that you can start and configure with
|
|
93
93
|
|
94
94
|
where `.env` is the env file containing your credentials, and `boot.rb` is a file that will be included before each task execution - this file should load all workflow classes.
|
95
95
|
|
96
|
+
## Usage inside a Ruby on Rails application
|
97
|
+
|
98
|
+
### Client initialization
|
99
|
+
|
100
|
+
Edit your application secrets with `rails credentials:edit` and add your Zenaton
|
101
|
+
credentials to it (you'll find them [here](https://zenaton/app/api)). For
|
102
|
+
example:
|
103
|
+
```yml
|
104
|
+
zenaton:
|
105
|
+
app_id: 123456
|
106
|
+
api_token: abcdefgh
|
107
|
+
```
|
108
|
+
|
109
|
+
Then create an initializer in `config/initializers/zenaton.rb` with the
|
110
|
+
following:
|
111
|
+
```ruby
|
112
|
+
Zenaton::Client.init(
|
113
|
+
Rails.application.credentials.zenaton[:app_id],
|
114
|
+
Rails.application.credentials.zenaton[:api_token],
|
115
|
+
Rails.env.production? ? 'production' : 'dev'
|
116
|
+
)
|
117
|
+
```
|
118
|
+
|
119
|
+
### Writing Workflows and Tasks
|
120
|
+
|
121
|
+
We can create a workflow in `app/workflows/my_workflow.rb`.
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
class MyWorkflow < Zenaton::Interfaces::Worflow
|
125
|
+
include Zenatonable
|
126
|
+
|
127
|
+
def handle
|
128
|
+
# Your workflow implementation
|
129
|
+
end
|
130
|
+
end
|
131
|
+
```
|
132
|
+
Note that your workflow implementation should be idempotent. See [documentation](https://zenaton.com/app/documentation#workflow-basics-implementation).
|
133
|
+
|
134
|
+
And we can create a task in `app/tasks/my_task.rb`.
|
135
|
+
```ruby
|
136
|
+
class MyTask < Zenaton::Interfaces::Task
|
137
|
+
include Zenatonable
|
138
|
+
|
139
|
+
def handle
|
140
|
+
# Your task implementation
|
141
|
+
end
|
142
|
+
end
|
143
|
+
```
|
144
|
+
|
145
|
+
### Lauching a workflow
|
146
|
+
|
147
|
+
We can start a workflow from anywhere in our application code with:
|
148
|
+
```ruby
|
149
|
+
MyWorkflow.new.dispatch
|
150
|
+
```
|
151
|
+
|
152
|
+
### Worker Installation
|
153
|
+
|
154
|
+
Your workflow's tasks will be executed on your worker servers. Please install a Zenaton worker on it:
|
155
|
+
|
156
|
+
$ curl https://install.zenaton.com | sh
|
157
|
+
|
158
|
+
that you can start and configure from your application directory with
|
159
|
+
|
160
|
+
$ zenaton start && zenaton listen --env=.env --rails
|
161
|
+
|
162
|
+
where `.env` is the env file containing your credentials.
|
163
|
+
|
164
|
+
**Note** In this example we created our workflows and tasks in the `/app`
|
165
|
+
folder since Rails will autoload ruby files in that path. If you create your
|
166
|
+
workflows and tasks somewhere else, ensure Rails loads them at boot time.
|
167
|
+
|
96
168
|
## Documentation
|
97
169
|
|
98
170
|
Please see https://zenaton.com/documentation for complete documentation.
|
@@ -1,6 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'singleton'
|
4
|
+
require 'json/add/core'
|
5
|
+
require 'json/add/rational'
|
6
|
+
require 'json/add/complex'
|
7
|
+
require 'json/add/bigdecimal'
|
8
|
+
require 'json/add/ostruct'
|
4
9
|
|
5
10
|
module Zenaton
|
6
11
|
module Services
|
@@ -8,15 +13,36 @@ module Zenaton
|
|
8
13
|
# to create new objects with a given set of instance variables.
|
9
14
|
class Properties
|
10
15
|
# Handle (de)serializaton separately for these classes.
|
11
|
-
SPECIAL_CASES = [
|
16
|
+
SPECIAL_CASES = [
|
17
|
+
::Complex,
|
18
|
+
::Date,
|
19
|
+
::DateTime,
|
20
|
+
::Range,
|
21
|
+
::Rational,
|
22
|
+
::Regexp,
|
23
|
+
::Symbol,
|
24
|
+
::Time,
|
25
|
+
defined?(::OpenStruct) ? ::OpenStruct : nil,
|
26
|
+
defined?(::BigDecimal) ? ::BigDecimal : nil
|
27
|
+
].compact.freeze
|
28
|
+
|
29
|
+
NUMERIC_INITIALIATION = [
|
30
|
+
::Rational,
|
31
|
+
::Complex,
|
32
|
+
defined?(::BigDecimal) ? ::BigDecimal : nil
|
33
|
+
].compact.freeze
|
12
34
|
|
13
35
|
# Returns an allocated instance of the given class name
|
14
36
|
# @param class_name [String] the name of the class to allocate
|
15
37
|
# @return [Object]
|
16
38
|
def blank_instance(class_name)
|
17
39
|
klass = Object.const_get(class_name)
|
18
|
-
if klass < Singleton
|
40
|
+
if klass < ::Singleton
|
19
41
|
klass.instance
|
42
|
+
elsif NUMERIC_INITIALIATION.include?(klass)
|
43
|
+
Kernel.send(klass.to_s, 1, 1)
|
44
|
+
elsif klass == Symbol
|
45
|
+
:place_holder
|
20
46
|
else
|
21
47
|
klass.allocate
|
22
48
|
end
|
@@ -70,72 +96,20 @@ module Zenaton
|
|
70
96
|
end
|
71
97
|
|
72
98
|
def from_complex_type(object)
|
73
|
-
|
74
|
-
|
75
|
-
from_time(object)
|
76
|
-
when 'Date'
|
77
|
-
from_date(object)
|
78
|
-
when 'DateTime'
|
79
|
-
from_date_time(object)
|
99
|
+
JSON.parse(object.to_json).tap do |attributes|
|
100
|
+
attributes.delete('json_class')
|
80
101
|
end
|
81
102
|
end
|
82
103
|
|
83
|
-
def from_time(object)
|
84
|
-
nanoseconds = [object.tv_usec * 1_000]
|
85
|
-
object.respond_to?(:tv_nsec) && nanoseconds << object.tv_nsec
|
86
|
-
{ 's' => object.tv_sec, 'n' => nanoseconds.max }
|
87
|
-
end
|
88
|
-
|
89
|
-
def from_date(object)
|
90
|
-
{ 'y' => object.year, 'm' => object.month,
|
91
|
-
'd' => object.day, 'sg' => object.start }
|
92
|
-
end
|
93
|
-
|
94
|
-
def from_date_time(object)
|
95
|
-
{
|
96
|
-
'y' => object.year, 'm' => object.month, 'd' => object.day,
|
97
|
-
'H' => object.hour, 'M' => object.minute, 'S' => object.sec,
|
98
|
-
'of' => object.offset.to_s, 'sg' => object.start
|
99
|
-
}
|
100
|
-
end
|
101
|
-
|
102
104
|
def set_complex_type(object, props)
|
103
|
-
|
104
|
-
|
105
|
-
return_time(object, props)
|
106
|
-
when 'Date'
|
107
|
-
return_date(props)
|
108
|
-
when 'DateTime'
|
109
|
-
return_date_time(props)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def return_time(object, props)
|
114
|
-
if object.respond_to?(:tv_usec)
|
115
|
-
Time.at(props['s'], Rational(props['n'], 1000))
|
116
|
-
else
|
117
|
-
Time.at(props['s'], props['n'] / 1000)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def return_date(props)
|
122
|
-
Date.civil(*props.values_at('y', 'm', 'd', 'sg'))
|
123
|
-
end
|
124
|
-
|
125
|
-
def return_date_time(props)
|
126
|
-
args = props.values_at('y', 'm', 'd', 'H', 'M', 'S')
|
127
|
-
of_a, of_b = props['of'].split('/')
|
128
|
-
args << if of_b && of_b != 0
|
129
|
-
Rational(of_a.to_i, of_b.to_i)
|
130
|
-
else
|
131
|
-
of_a
|
132
|
-
end
|
133
|
-
args << props['sg']
|
134
|
-
DateTime.civil(*args) # rubocop:disable Style/DateTime
|
105
|
+
props['json_class'] = object.class.name
|
106
|
+
JSON(props.to_json)
|
135
107
|
end
|
136
108
|
|
137
109
|
def special_case?(object)
|
138
|
-
SPECIAL_CASES.include?(object.class)
|
110
|
+
SPECIAL_CASES.include?(object.class) \
|
111
|
+
|| object.is_a?(Struct) \
|
112
|
+
|| object.is_a?(Exception)
|
139
113
|
end
|
140
114
|
end
|
141
115
|
end
|
data/lib/zenaton/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zenaton
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zenaton
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|