ecoportal-api 0.10.10 → 0.10.11
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/.gitignore +2 -0
- data/CHANGELOG.md +6 -0
- data/lib/ecoportal/api/common/base_model.rb +4 -3
- data/lib/ecoportal/api/common/client/time_out.rb +3 -0
- data/lib/ecoportal/api/common/hash_diff.rb +1 -1
- data/lib/ecoportal/api/v1/job/awaiter/timer.rb +28 -9
- data/lib/ecoportal/api/v1/job/awaiter.rb +10 -3
- data/lib/ecoportal/api/v1/job.rb +2 -1
- data/lib/ecoportal/api/v1/person_details.rb +3 -2
- data/lib/ecoportal/api/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: 5a555853c173845b7e088537a48316ab93d1e1cade81a1554bf75ebdd9d754c5
|
4
|
+
data.tar.gz: 1cbd64e04195227bd5d4eb2694b8968f0987ca301ccb48a558fd1ca7fb409e6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7adc6cf22eef822270e8429e469d4566109e93bcfbb93431a4a47406e7ff370c1bd26f4f683ede1799fc2b8c7b4d46509d41d28674489868b58a2550f5eafa7b
|
7
|
+
data.tar.gz: 15ba327d877408f5b576e004789143deddf231f4d6954943034bfa82b9e69aa14137fb65c4a33f93dd8dc0be96164f540dcb29b7c1867d7315a2ee4ea285731f
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -8,8 +8,14 @@ All notable changes to this project will be documented in this file.
|
|
8
8
|
|
9
9
|
### Changed
|
10
10
|
|
11
|
+
- `MAX_START_DELAY` to be `120` (it was `60`).
|
12
|
+
|
11
13
|
### Fixed
|
12
14
|
|
15
|
+
- `PersonDetails#changed?`: `ref` wasn't being used.
|
16
|
+
- `Ecoportal::API::V1::Job::Awaiter`
|
17
|
+
- First timer relay should use `ldelay` of 1 second if it's first loop.
|
18
|
+
|
13
19
|
## [0.10.10] - 2025-04-04
|
14
20
|
|
15
21
|
### Fixed
|
@@ -4,9 +4,10 @@ module Ecoportal
|
|
4
4
|
module Common
|
5
5
|
class BaseModel
|
6
6
|
class UnlinkedModel < StandardError
|
7
|
-
def initialize(msg =
|
8
|
-
msg
|
9
|
-
msg
|
7
|
+
def initialize(msg = nil, from: nil, key: nil)
|
8
|
+
msg ||= 'Something went wrong when linking the document.'
|
9
|
+
msg << " From: #{from}." if from
|
10
|
+
msg << " key: #{key}." if key
|
10
11
|
super(msg)
|
11
12
|
end
|
12
13
|
end
|
@@ -40,6 +40,9 @@ module Ecoportal
|
|
40
40
|
throughput.eta_for(to_count(count), **kargs)
|
41
41
|
end
|
42
42
|
|
43
|
+
# @todo introduce `min_wait`
|
44
|
+
# - The reason is because small batches have still an associated lag
|
45
|
+
# before the jobs start to run.
|
43
46
|
def timeout_for(count, waited: 0, max_wait: nil, approach: :conservative)
|
44
47
|
(waited + eta_for(count, approach: approach)).then do |time|
|
45
48
|
next time unless max_wait
|
@@ -11,7 +11,7 @@ module Ecoportal
|
|
11
11
|
|
12
12
|
# The class
|
13
13
|
Timer = Struct.new(*TIMER_ARGS) do
|
14
|
-
self::MAX_START_DELAY =
|
14
|
+
self::MAX_START_DELAY = 120
|
15
15
|
|
16
16
|
attr_reader :timestamp
|
17
17
|
|
@@ -22,17 +22,24 @@ module Ecoportal
|
|
22
22
|
end
|
23
23
|
|
24
24
|
alias_method :original_start, :start
|
25
|
+
# Previous start or current timestamp.
|
26
|
+
# @note in practice this translates into the very first
|
27
|
+
# timestamp (so it's an absolute start)
|
25
28
|
def start
|
26
29
|
original_start || timestamp
|
27
30
|
end
|
28
31
|
|
29
32
|
alias_method :original_last, :last
|
33
|
+
# Previous timestamp.
|
30
34
|
def last
|
31
35
|
original_last || start
|
32
36
|
end
|
33
37
|
|
34
38
|
def new(**kargs, &block)
|
35
|
-
self.class.new(
|
39
|
+
self.class.new(
|
40
|
+
**new_kargs.merge(kargs),
|
41
|
+
&block
|
42
|
+
)
|
36
43
|
end
|
37
44
|
|
38
45
|
def job_id
|
@@ -40,10 +47,14 @@ module Ecoportal
|
|
40
47
|
end
|
41
48
|
|
42
49
|
def complete?
|
50
|
+
return false unless status
|
51
|
+
|
43
52
|
status.complete?(total)
|
44
53
|
end
|
45
54
|
|
46
55
|
def started?
|
56
|
+
return false unless status
|
57
|
+
|
47
58
|
status.started?
|
48
59
|
end
|
49
60
|
|
@@ -59,14 +70,17 @@ module Ecoportal
|
|
59
70
|
status.progress_increase(lstatus)
|
60
71
|
end
|
61
72
|
|
73
|
+
# Total time waited (absolute).
|
62
74
|
def waited
|
63
75
|
timestamp - start
|
64
76
|
end
|
65
77
|
|
78
|
+
# Time waited since last timestamp (relative).
|
66
79
|
def lwaited
|
67
80
|
timestamp - last
|
68
81
|
end
|
69
82
|
|
83
|
+
# Absolute wait minus half of the last sleep.
|
70
84
|
def net_waited
|
71
85
|
last_delay = ldelay || 0
|
72
86
|
waited - (last_delay / 2)
|
@@ -76,22 +90,26 @@ module Ecoportal
|
|
76
90
|
(timeout_in - waited).round(2)
|
77
91
|
end
|
78
92
|
|
93
|
+
# Time left before timing out job started
|
94
|
+
# or job finished.
|
95
|
+
def timeout_in
|
96
|
+
return time_left_total if started?
|
97
|
+
|
98
|
+
time_left_to_start
|
99
|
+
end
|
100
|
+
|
101
|
+
# Total time left before timing out.
|
79
102
|
def time_left_total
|
80
103
|
(timeout - waited).round(2)
|
81
104
|
end
|
82
105
|
|
106
|
+
# Time left before Job start times out.
|
83
107
|
def time_left_to_start
|
84
108
|
return max_start_delay if started?
|
85
109
|
|
86
110
|
(max_start_delay - waited).round(2)
|
87
111
|
end
|
88
112
|
|
89
|
-
def timeout_in
|
90
|
-
return time_left_total if started?
|
91
|
-
|
92
|
-
time_left_to_start
|
93
|
-
end
|
94
|
-
|
95
113
|
# timeout library is evil. So we make poor-man timeout.
|
96
114
|
# https://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-is-terrifying/
|
97
115
|
def timeout?
|
@@ -141,7 +159,7 @@ module Ecoportal
|
|
141
159
|
%i[total timeout start].each_with_object({}) do |key, kargs|
|
142
160
|
kargs[key] = send(key)
|
143
161
|
end.tap do |kargs|
|
144
|
-
kargs[:start] = start
|
162
|
+
kargs[:start] = start # @todo redundant
|
145
163
|
kargs[:last] = timestamp
|
146
164
|
kargs[:lstatus] = status
|
147
165
|
end
|
@@ -149,6 +167,7 @@ module Ecoportal
|
|
149
167
|
|
150
168
|
private
|
151
169
|
|
170
|
+
# We would not wait more than this time for a Job to start.
|
152
171
|
def max_start_delay
|
153
172
|
self.class::MAX_START_DELAY
|
154
173
|
end
|
@@ -9,8 +9,14 @@ module Ecoportal
|
|
9
9
|
include Common::Client::TimeOut
|
10
10
|
include StatusFrequency
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
# available approaches are:
|
13
|
+
# - `:min` assumes always the `MIN_THROUGHPUT`.
|
14
|
+
# - `:last` last seen throughput.
|
15
|
+
# - `:conservative` the bigger of: min throughput seen or `MIN_THROUGHPUT`.
|
16
|
+
# - `:optimistic` the smoller of: max throughput seen or `MAX_THROUGHPUT`.
|
17
|
+
# - `:average` the accumulated avarage of througoutputs.
|
18
|
+
TIMEOUT_APPROACH = :min
|
19
|
+
TIMEOUT_FALLBACK = :min # on timeout swap to this approach.
|
14
20
|
|
15
21
|
attr_reader :job_api, :job_id, :total
|
16
22
|
|
@@ -51,10 +57,11 @@ module Ecoportal
|
|
51
57
|
|
52
58
|
timer = timer.new(
|
53
59
|
status: job_api.status(job_id),
|
54
|
-
ldelay: delay_status_check
|
60
|
+
ldelay: delay_status_check || 1
|
55
61
|
)
|
56
62
|
|
57
63
|
# ratio = throughput!(timer.net_waited, count: timer.progress)
|
64
|
+
# last throughput (rather than average as above)
|
58
65
|
ratio = throughput!(timer.lwaited, count: timer.increased)
|
59
66
|
|
60
67
|
break timer.status if timer.complete?
|
data/lib/ecoportal/api/v1/job.rb
CHANGED
@@ -4,6 +4,7 @@ require 'ecoportal/api/v1/job/awaiter'
|
|
4
4
|
module Ecoportal
|
5
5
|
module API
|
6
6
|
class V1
|
7
|
+
# @todo add `#relaunch` where only pending results are requested.
|
7
8
|
class Job
|
8
9
|
attr_reader :client, :person_class
|
9
10
|
|
@@ -15,7 +16,7 @@ module Ecoportal
|
|
15
16
|
@created = false
|
16
17
|
end
|
17
18
|
|
18
|
-
# Allows to preserve the learned
|
19
|
+
# Allows to preserve the learned throughput
|
19
20
|
def new
|
20
21
|
self.class.new(client, person_class: person_class).tap do |out|
|
21
22
|
out.awaiter = @awaiter
|
@@ -25,6 +25,7 @@ module Ecoportal
|
|
25
25
|
# @return [Array<SchemaFieldValue>] the array of fields of the schema.
|
26
26
|
def fields
|
27
27
|
return @fields if defined?(@fields)
|
28
|
+
|
28
29
|
@fields = (doc['fields'] || []).each_with_index.map do |field, i|
|
29
30
|
schema_field_value_class.new(field, parent: self, key: ['fields', i])
|
30
31
|
end
|
@@ -66,10 +67,10 @@ module Ecoportal
|
|
66
67
|
end
|
67
68
|
|
68
69
|
# @return [Boolean] `true` if `id` exists and `value` has changed, `false` otherwise
|
69
|
-
def changed?(id,
|
70
|
+
def changed?(id, ref = :last)
|
70
71
|
return false unless (field = get_field(id))
|
71
72
|
|
72
|
-
field.as_update.key?('value')
|
73
|
+
field.as_update(ref).key?('value')
|
73
74
|
end
|
74
75
|
|
75
76
|
def original_value(id)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ecoportal-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tapio Saarinen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|