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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: db17bf2caf28d2e2c9f8c610e0c882f53543af959af846e63f25dc4b9cf71d88
4
- data.tar.gz: 28ae921a4fcfd86ab11c726238db69350341190fae32e897dc1c518562baec64
3
+ metadata.gz: 8a6590eba29150d752565e62505dbbf6ec2a6a0a66f3867e853d76dd102e0991
4
+ data.tar.gz: dc34cb351261f71e21c4ee692b11622c794a9827e53b5344ed1b1728b1cfd046
5
5
  SHA512:
6
- metadata.gz: 5974cd83124ff35a036dce13e4800095f2a3c37923a6c568b5315140f44fb62390858545403ed52873a29ff432b7e785ed20c80c29e5fe467b75274ae40745ac
7
- data.tar.gz: 548fc102b9aa3861efa4cb538845589f02ab32baefabd7821201cdb2992b01cbb07b90a75294a04032c036a70db2d06477880bb7a6f579ec228574607d893abe
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.0)
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.0)
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.1)
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/example-ruby).
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 = [Time, Date, DateTime].freeze
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
- case object.class.name
74
- when 'Time'
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
- case object.class.name
104
- when 'Time'
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
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Zenaton
4
4
  # This gem's current version
5
- VERSION = '0.2.0'
5
+ VERSION = '0.2.1'
6
6
  end
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.0
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-08 00:00:00.000000000 Z
11
+ date: 2018-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport