ecoportal-api 0.10.1 → 0.10.2

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: 84d530d29757e28159e985e70e8a0da65f16d831ea2658fcafbe94f42e98f882
4
- data.tar.gz: a4778b377de727e3c648fa79d674b044b32d452c7cc4f024d5fbb383185a3097
3
+ metadata.gz: 4cc0547ca88715ad6b0f2d3bc7ed4661bab0f9259117ce28aa5d43aab0761d02
4
+ data.tar.gz: 1e109b427a0e71bd91edf1d4e9ce6e7cf9ac2df998662c97746df30b8e07998b
5
5
  SHA512:
6
- metadata.gz: cb0dad40ddd3d5b0b621ff61b063bf2e92522b09156035009a15e782d946d43aa9db28c0066c3db1c805c78f29a2ee550fd7c358020b7216a776624c3d31f43e
7
- data.tar.gz: c84332d17ddd19fbfbbd69f287c2110cad88064ebce801f232fcaeeccc5e6db5ec2c5ce359267d43df6bd8f4bf08238b0c242f30ef39789b92321030a914b09f
6
+ metadata.gz: 44eba3743e30beff3c04e71b1191900b8477d81af1371f1a5003cb6847384e384d535e51390e4f8db39e8aa81a0cbf7fc200a87ac18036c45e56530b72b09342
7
+ data.tar.gz: 1749045310b0748e8935027cd0d1b9d69e7a84c4534b27017bd1581848d579c6359e59dedfe19e3cbe451038e2a4c70fb82150a01ca4c9260eadde64bfac5a92
data/.rubocop.yml CHANGED
@@ -30,6 +30,11 @@ Style/ConditionalAssignment:
30
30
  Style/BlockDelimiters:
31
31
  BracesRequiredMethods: ['log']
32
32
  AllowedPatterns: ['proc', 'new']
33
+ Style/HashSyntax:
34
+ EnforcedShorthandSyntax: either
35
+ EnforcedStyle: no_mixed_keys
36
+ Style/ArgumentsForwarding:
37
+ UseAnonymousForwarding: false
33
38
  Style/ClassAndModuleChildren:
34
39
  Enabled: false
35
40
  Style/FrozenStringLiteralComment:
@@ -93,3 +98,5 @@ Naming/MethodParameterName:
93
98
  AllowedNames: ['x', 'y', 'i', 'j', 'id', 'io', 'to']
94
99
  Naming/RescuedExceptionsVariableName:
95
100
  Enabled: false
101
+ Naming/BlockForwarding:
102
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -2,19 +2,37 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.10.3] - 2024-09-xx
6
+
7
+ ### Added
8
+
9
+ ### Changed
10
+
11
+ ### Fixed
12
+
13
+ ## [0.10.2] - 2024-09-27
14
+
15
+ ### Added
16
+
17
+ - `Ecoportal::API::Common::TimeOut` to calculate adaptive time outs.
18
+
19
+ ### Changed
20
+
21
+ - `Ecoportal::API::V1::Person#job`
22
+ - added **adaptative await**
23
+ - evaluate `true` to `complete?` if `progress` is that of total count.
24
+
5
25
  ## [0.10.1] - 2024-08-01
6
26
 
7
27
  ### Added
8
28
 
9
- - `Ecoportal::V1::Person#brand_id`
10
- - `Ecoportal::V1::Person#archived`
29
+ - `Ecoportal::API::V1::Person#brand_id`
30
+ - `Ecoportal::API::V1::Person#archived`
11
31
 
12
32
  ### Changed
13
33
 
14
34
  - require `ruby 3`
15
35
 
16
- ### Fixed
17
-
18
36
  ## [0.9.8] - 2024-05-15
19
37
 
20
38
  ### Added
@@ -344,5 +362,3 @@ All notable changes to this project will be documented in this file.
344
362
 
345
363
  - this `CHANGELOG.md` file
346
364
  - person model: `freemium` core property
347
-
348
-
@@ -1,12 +1,17 @@
1
+ # rubocop:disable Gemspec/DevelopmentDependencies
1
2
  lib = File.expand_path('lib', __dir__)
2
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "ecoportal/api/version"
4
+
5
+ require 'ecoportal/api/version'
4
6
 
5
7
  Gem::Specification.new do |spec|
6
8
  spec.name = "ecoportal-api"
7
9
  spec.version = Ecoportal::API::VERSION
8
- spec.authors = ["Tapio Saarinen"]
9
- spec.email = ["tapio@ecoportal.co.nz", "rien@ecoportal.co.nz", "oscar@ecoportal.co.nz", "bozydar@ecoportal.co.nz"]
10
+ spec.authors = ['Tapio Saarinen']
11
+ spec.email = [
12
+ 'tapio@ecoportal.co.nz',
13
+ 'oscar@ecoportal.co.nz'
14
+ ]
10
15
 
11
16
  spec.summary = %q{A collection of helpers for interacting with the ecoPortal MS's various APIs}
12
17
  spec.homepage = "https://www.ecoportal.com"
@@ -19,17 +24,21 @@ Gem::Specification.new do |spec|
19
24
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
25
  f.match(%r{^(test|spec|features)/})
21
26
  end
22
- spec.bindir = "exe"
27
+ spec.bindir = 'exe'
23
28
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
- spec.require_paths = ["lib"]
29
+ spec.require_paths = ['lib']
25
30
 
26
- spec.add_development_dependency "rspec", ">= 3.12.0", "< 4"
27
- spec.add_development_dependency "rake", ">= 13.1.0", "< 14"
28
- spec.add_development_dependency "yard", ">= 0.9.34", "< 1"
29
- spec.add_development_dependency "redcarpet", ">= 3.6.0", "< 4"
30
- spec.add_development_dependency "pry" , "~> 0.14"
31
+ spec.add_development_dependency 'pry' , '~> 0.14'
32
+ spec.add_development_dependency 'rake', '>= 13.0.3', '< 14'
33
+ spec.add_development_dependency 'redcarpet', '>= 3.6.0', '< 4'
34
+ spec.add_development_dependency 'rspec', '>= 3.12.0', '< 4'
35
+ spec.add_development_dependency 'rubocop', '~> 1'
36
+ spec.add_development_dependency 'rubocop-rake', '~> 0'
37
+ spec.add_development_dependency 'yard', '~> 0.9'
31
38
 
32
39
  spec.add_dependency 'dotenv', '~> 3'
33
40
  spec.add_dependency 'elastic-apm', '>= 4.7', "< 5"
34
41
  spec.add_dependency 'http', '~> 5.1', "< 6"
35
42
  end
43
+
44
+ # rubocop:enable Gemspec/DevelopmentDependencies
@@ -11,6 +11,10 @@ module Ecoportal
11
11
  @logger = logger
12
12
  end
13
13
 
14
+ def count
15
+ @operations.count
16
+ end
17
+
14
18
  def as_json
15
19
  {
16
20
  actions: @operations.map do |operation|
@@ -12,7 +12,7 @@ module Ecoportal
12
12
  doc
13
13
  end
14
14
  end
15
-
15
+
16
16
  def get_id(doc)
17
17
  id = nil
18
18
  id ||= doc.id if doc.respond_to?(:id)
@@ -0,0 +1,26 @@
1
+ module Ecoportal
2
+ module API
3
+ module Common
4
+ module TimeOut
5
+ MIN_THROUGHPUT = 0.2 # people per second
6
+ MIN_SIZE = 10
7
+
8
+ private
9
+
10
+ def min_throughput
11
+ self.class::MIN_THROUGHPUT
12
+ end
13
+
14
+ def min_size
15
+ self.class::MIN_SIZE
16
+ end
17
+
18
+ def timeout_for(count)
19
+ count = 1 unless count&.positive?
20
+ count = min_size if count < min_size
21
+ (count.ceil / min_throughput).ceil
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -11,6 +11,7 @@ require 'ecoportal/api/common/base_model'
11
11
  require 'ecoportal/api/common/doc_helpers'
12
12
  require 'ecoportal/api/common/logging'
13
13
  require 'ecoportal/api/common/elastic_apm_integration'
14
+ require 'ecoportal/api/common/time_out'
14
15
  require 'ecoportal/api/common/client'
15
16
  require 'ecoportal/api/common/response'
16
17
  require 'ecoportal/api/common/wrapped_response'
@@ -0,0 +1,33 @@
1
+ module Ecoportal
2
+ module API
3
+ class V1
4
+ class JobStatus
5
+ attr_reader :id, :progress
6
+
7
+ def initialize(id, complete, errored, progress)
8
+ @id = id
9
+ @complete = complete
10
+ @errored = errored
11
+ @progress = progress
12
+ end
13
+
14
+ def complete?(total = nil)
15
+ return @complete if total.nil?
16
+
17
+ progress >= total
18
+ end
19
+
20
+ def errored?
21
+ @errored
22
+ end
23
+
24
+ def to_s
25
+ msg = complete? ? "Completed" : "In progress"
26
+ msg = "Errored" if errored?
27
+ msg << " with #{progress} done."
28
+ msg
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -6,9 +6,9 @@ module Ecoportal
6
6
  class People
7
7
  extend Common::BaseClass
8
8
  include Common::DocHelpers
9
+ include Common::TimeOut
9
10
  include Enumerable
10
11
 
11
- JOB_TIMEOUT = 240
12
12
  DELAY_STATUS_CHECK = 5
13
13
 
14
14
  class_resolver :person_class, "Ecoportal::API::V1::Person"
@@ -169,15 +169,20 @@ module Ecoportal
169
169
 
170
170
  yield operation
171
171
 
172
- job_id = create_job(operation)
173
- status = wait_for_job_completion(job_id)
172
+ total = operation.count
173
+ timeout = timeout_for(total)
174
174
 
175
- if status&.complete?
175
+ job_id = create_job(operation)
176
+ status = wait_for_job_completion(job_id, timeout: timeout, total: total)
177
+
178
+ # @todo
179
+ # if total == status.progress
180
+ if status&.complete?(total)
176
181
  job_result(job_id, operation)
177
182
  else
178
- msg = "Job `#{job_id}` not complete. "
179
- msg << "Probably timeout after #{JOB_TIMEOUT} seconds. "
180
- msg << "Current status: #{status}"
183
+ msg = "Job '#{job_id}' not complete (size: #{total}).\n"
184
+ msg << " Probably timeout after #{timeout} seconds.\n"
185
+ msg << " Current status: #{status}"
181
186
 
182
187
  raise API::Errors::TimeOut, msg
183
188
  end
@@ -191,8 +196,6 @@ module Ecoportal
191
196
 
192
197
  private
193
198
 
194
- JobStatus = Struct.new(:id, :complete?, :errored?, :progress)
195
-
196
199
  def job_status(job_id)
197
200
  response = client.get("/people/job/#{CGI.escape(job_id)}/status")
198
201
  body = response && body_data(response.body)
@@ -201,12 +204,7 @@ module Ecoportal
201
204
  msg << "Errors: #{body}"
202
205
  raise msg unless response.success?
203
206
 
204
- JobStatus.new(
205
- body["id"],
206
- body["complete"],
207
- body["errored"],
208
- body["progress"]
209
- )
207
+ JobStatus.new(*body.values_at(*%w[id complete errored progress]))
210
208
  end
211
209
 
212
210
  # @return [Ecoportal::API::Common::Response] the results of the batch job
@@ -216,15 +214,25 @@ module Ecoportal
216
214
  end
217
215
  end
218
216
 
219
- def wait_for_job_completion(job_id)
217
+ def wait_for_job_completion(job_id, timeout:, total:)
220
218
  # timeout library is evil. So we make poor-man timeout.
221
219
  # https://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-is-terrifying/
222
220
  before = Time.now
223
221
 
224
222
  loop do
225
223
  status = job_status(job_id)
226
- break status if status.complete?
227
- break status if Time.now >= before + JOB_TIMEOUT
224
+ break status if status.complete?(total)
225
+
226
+ left = (before + timeout) - Time.now
227
+ break status unless left.positive?
228
+ # break status if Time.now >= before + timeout
229
+
230
+ msg = " ... Await job "
231
+ msg << "('#{job_id}'; done: #{status.progress}): "
232
+ msg << "#{left.ceil} sec. \r"
233
+
234
+ print msg
235
+ $stdout.flush
228
236
 
229
237
  sleep(DELAY_STATUS_CHECK)
230
238
  status
@@ -46,5 +46,6 @@ module Ecoportal
46
46
  end
47
47
  end
48
48
 
49
+ require 'ecoportal/api/v1/job_status'
49
50
  require 'ecoportal/api/v1/person_schemas'
50
51
  require 'ecoportal/api/v1/people'
@@ -1,5 +1,5 @@
1
1
  module Ecoportal
2
2
  module API
3
- VERSION = "0.10.1".freeze
3
+ VERSION = '0.10.2'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,42 +1,36 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecoportal-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.10.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tapio Saarinen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-01 00:00:00.000000000 Z
11
+ date: 2024-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rspec
14
+ name: pry
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 3.12.0
20
- - - "<"
17
+ - - "~>"
21
18
  - !ruby/object:Gem::Version
22
- version: '4'
19
+ version: '0.14'
23
20
  type: :development
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: 3.12.0
30
- - - "<"
24
+ - - "~>"
31
25
  - !ruby/object:Gem::Version
32
- version: '4'
26
+ version: '0.14'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: rake
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
31
  - - ">="
38
32
  - !ruby/object:Gem::Version
39
- version: 13.1.0
33
+ version: 13.0.3
40
34
  - - "<"
41
35
  - !ruby/object:Gem::Version
42
36
  version: '14'
@@ -46,37 +40,37 @@ dependencies:
46
40
  requirements:
47
41
  - - ">="
48
42
  - !ruby/object:Gem::Version
49
- version: 13.1.0
43
+ version: 13.0.3
50
44
  - - "<"
51
45
  - !ruby/object:Gem::Version
52
46
  version: '14'
53
47
  - !ruby/object:Gem::Dependency
54
- name: yard
48
+ name: redcarpet
55
49
  requirement: !ruby/object:Gem::Requirement
56
50
  requirements:
57
51
  - - ">="
58
52
  - !ruby/object:Gem::Version
59
- version: 0.9.34
53
+ version: 3.6.0
60
54
  - - "<"
61
55
  - !ruby/object:Gem::Version
62
- version: '1'
56
+ version: '4'
63
57
  type: :development
64
58
  prerelease: false
65
59
  version_requirements: !ruby/object:Gem::Requirement
66
60
  requirements:
67
61
  - - ">="
68
62
  - !ruby/object:Gem::Version
69
- version: 0.9.34
63
+ version: 3.6.0
70
64
  - - "<"
71
65
  - !ruby/object:Gem::Version
72
- version: '1'
66
+ version: '4'
73
67
  - !ruby/object:Gem::Dependency
74
- name: redcarpet
68
+ name: rspec
75
69
  requirement: !ruby/object:Gem::Requirement
76
70
  requirements:
77
71
  - - ">="
78
72
  - !ruby/object:Gem::Version
79
- version: 3.6.0
73
+ version: 3.12.0
80
74
  - - "<"
81
75
  - !ruby/object:Gem::Version
82
76
  version: '4'
@@ -86,24 +80,52 @@ dependencies:
86
80
  requirements:
87
81
  - - ">="
88
82
  - !ruby/object:Gem::Version
89
- version: 3.6.0
83
+ version: 3.12.0
90
84
  - - "<"
91
85
  - !ruby/object:Gem::Version
92
86
  version: '4'
93
87
  - !ruby/object:Gem::Dependency
94
- name: pry
88
+ name: rubocop
95
89
  requirement: !ruby/object:Gem::Requirement
96
90
  requirements:
97
91
  - - "~>"
98
92
  - !ruby/object:Gem::Version
99
- version: '0.14'
93
+ version: '1'
100
94
  type: :development
101
95
  prerelease: false
102
96
  version_requirements: !ruby/object:Gem::Requirement
103
97
  requirements:
104
98
  - - "~>"
105
99
  - !ruby/object:Gem::Version
106
- version: '0.14'
100
+ version: '1'
101
+ - !ruby/object:Gem::Dependency
102
+ name: rubocop-rake
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: yard
117
+ requirement: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: '0.9'
122
+ type: :development
123
+ prerelease: false
124
+ version_requirements: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - "~>"
127
+ - !ruby/object:Gem::Version
128
+ version: '0.9'
107
129
  - !ruby/object:Gem::Dependency
108
130
  name: dotenv
109
131
  requirement: !ruby/object:Gem::Requirement
@@ -161,9 +183,7 @@ dependencies:
161
183
  description:
162
184
  email:
163
185
  - tapio@ecoportal.co.nz
164
- - rien@ecoportal.co.nz
165
186
  - oscar@ecoportal.co.nz
166
- - bozydar@ecoportal.co.nz
167
187
  executables: []
168
188
  extensions: []
169
189
  extra_rdoc_files: []
@@ -194,6 +214,7 @@ files:
194
214
  - lib/ecoportal/api/common/hash_diff.rb
195
215
  - lib/ecoportal/api/common/logging.rb
196
216
  - lib/ecoportal/api/common/response.rb
217
+ - lib/ecoportal/api/common/time_out.rb
197
218
  - lib/ecoportal/api/common/wrapped_response.rb
198
219
  - lib/ecoportal/api/errors.rb
199
220
  - lib/ecoportal/api/errors/base.rb
@@ -215,6 +236,7 @@ files:
215
236
  - lib/ecoportal/api/internal/schema_field_value.rb
216
237
  - lib/ecoportal/api/logger.rb
217
238
  - lib/ecoportal/api/v1.rb
239
+ - lib/ecoportal/api/v1/job_status.rb
218
240
  - lib/ecoportal/api/v1/people.rb
219
241
  - lib/ecoportal/api/v1/person.rb
220
242
  - lib/ecoportal/api/v1/person_details.rb
@@ -243,7 +265,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
243
265
  - !ruby/object:Gem::Version
244
266
  version: '0'
245
267
  requirements: []
246
- rubygems_version: 3.5.6
268
+ rubygems_version: 3.5.18
247
269
  signing_key:
248
270
  specification_version: 4
249
271
  summary: A collection of helpers for interacting with the ecoPortal MS's various APIs