marty 1.0.15 → 1.0.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/components/marty/promise_view.rb +5 -1
- data/app/models/marty/event.rb +55 -25
- data/db/migrate/202_add_completion_status_to_event.rb +6 -0
- data/lib/marty/version.rb +1 -1
- data/spec/job_helper.rb +8 -0
- data/spec/models/event_spec.rb +56 -24
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ddef9c94cc142b0d56475fd47ce2d8a91bdc988e
|
4
|
+
data.tar.gz: 46e3879a1402abf89018c5ac88323109d83ce905
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7cf2b4a830eb713c974a60909d6e777eacbcbcb773f6bfa217ae00d0a87d1df17ab982c8f725be17d4e5932f723c2afa11a83a58dbc1c048b77380a1b5acfbe8
|
7
|
+
data.tar.gz: 15ac135cf790bd8eb3bd8cb5f8bdda2c2930be1b62c9d880eb9e770bdc1ed0d835f6dcbf0f67cdd3ef78bea0c422e3cd50bc5a1bf58786c872b0265061d15ac4
|
@@ -55,7 +55,11 @@ class Marty::PromiseView < Netzke::Tree::Base
|
|
55
55
|
config.root_visible = false
|
56
56
|
config.paging = :none
|
57
57
|
config.bbar = bbar
|
58
|
-
|
58
|
+
config.read_only = true
|
59
|
+
config.permissions = { update: false,
|
60
|
+
create: false,
|
61
|
+
delete: false,
|
62
|
+
}
|
59
63
|
# garbage collect old promises (hacky to do this here)
|
60
64
|
Marty::Promise.cleanup(false)
|
61
65
|
end
|
data/app/models/marty/event.rb
CHANGED
@@ -17,29 +17,41 @@ class Marty::Event < Marty::Base
|
|
17
17
|
self.comment = self.comment.truncate(255) if self.comment
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
20
|
+
UPDATE_SQL =<<SQL
|
21
|
+
UPDATE marty_events as me
|
22
|
+
SET start_dt = p.start_dt,
|
23
|
+
end_dt = p.end_dt
|
24
|
+
FROM marty_promises p
|
25
|
+
WHERE me.promise_id = p.id
|
26
|
+
AND ( ( p.start_dt IS NOT NULL
|
27
|
+
AND me.start_dt IS NULL
|
28
|
+
)
|
29
|
+
OR ( p.end_dt IS NOT NULL
|
30
|
+
AND me.end_dt IS NULL
|
31
|
+
)
|
32
|
+
)
|
33
|
+
SQL
|
34
|
+
BASE_QUERY =<<SQL
|
35
|
+
SELECT id,
|
36
|
+
klass,
|
37
|
+
subject_id,
|
38
|
+
enum_event_operation,
|
39
|
+
comment,
|
40
|
+
start_dt,
|
41
|
+
end_dt,
|
42
|
+
expire_secs,
|
43
|
+
error
|
44
|
+
FROM marty_events
|
45
|
+
SQL
|
31
46
|
def self.running_query(time_now_s)
|
32
|
-
"
|
33
|
-
|
34
|
-
|
35
|
-
'#{time_now_s}'::timestamp - interval '24 hours') sub
|
36
|
-
WHERE (end_dt IS NULL or end_dt > '#{time_now_s}'::timestamp)
|
47
|
+
"#{BASE_QUERY}
|
48
|
+
WHERE start_dt >= '#{time_now_s}'::timestamp - interval '24 hours'
|
49
|
+
AND (end_dt IS NULL or end_dt > '#{time_now_s}'::timestamp)
|
37
50
|
AND (expire_secs IS NULL
|
38
51
|
OR expire_secs > EXTRACT (EPOCH FROM '#{time_now_s}'::timestamp - start_dt))
|
39
52
|
ORDER BY start_dt"
|
40
53
|
end
|
41
54
|
|
42
|
-
|
43
55
|
def self.op_is_running?(klass, subject_id, operation)
|
44
56
|
all_running.detect do |pm|
|
45
57
|
pm["klass"] == klass && pm["subject_id"].to_i == subject_id.to_i &&
|
@@ -76,16 +88,17 @@ class Marty::Event < Marty::Base
|
|
76
88
|
end
|
77
89
|
|
78
90
|
def self.lookup_event(klass, subject_id, operation)
|
79
|
-
get_data(BASE_QUERY
|
80
|
-
|
81
|
-
|
82
|
-
|
91
|
+
get_data("#{BASE_QUERY}
|
92
|
+
WHERE klass = '#{klass}'
|
93
|
+
AND subject_id = #{subject_id}
|
94
|
+
AND enum_event_operation = '#{operation}'")
|
83
95
|
|
84
96
|
#For now we return a bare hash
|
85
97
|
#Marty::Event.find_by_id(hash["id"])
|
86
98
|
end
|
87
99
|
|
88
|
-
def self.finish_event(klass, subject_id, operation, comment=nil)
|
100
|
+
def self.finish_event(klass, subject_id, operation, error=false, comment=nil)
|
101
|
+
raise "error must be true or false" unless [true, false].include?(error)
|
89
102
|
time_now_s = Time.zone.now.strftime('%Y-%m-%d %H:%M:%S.%6N')
|
90
103
|
|
91
104
|
event = get_data(running_query(time_now_s)).detect do |ev|
|
@@ -98,6 +111,7 @@ class Marty::Event < Marty::Base
|
|
98
111
|
ev = Marty::Event.find_by_id(event["id"])
|
99
112
|
raise "can't explicitly finish a promise event" if ev.promise_id
|
100
113
|
ev.end_dt = Time.zone.now
|
114
|
+
ev.error = error
|
101
115
|
ev.comment = comment if comment
|
102
116
|
ev.save!
|
103
117
|
end
|
@@ -112,10 +126,11 @@ class Marty::Event < Marty::Base
|
|
112
126
|
|
113
127
|
op_sql = "AND enum_event_operation = '#{operation}'" if operation
|
114
128
|
|
115
|
-
get_data("
|
129
|
+
get_data("#{BASE_QUERY}
|
116
130
|
WHERE klass = '#{klass}'
|
117
|
-
|
118
|
-
|
131
|
+
AND subject_id = #{subject_id} #{op_sql}
|
132
|
+
AND end_dt IS NOT NULL
|
133
|
+
ORDER BY end_dt desc").first
|
119
134
|
end
|
120
135
|
|
121
136
|
def self.currently_running(klass, subject_id)
|
@@ -142,6 +157,10 @@ class Marty::Event < Marty::Base
|
|
142
157
|
hash['end_dt'] ? hash['end_dt'].strftime("%H:%M") : '---'
|
143
158
|
end
|
144
159
|
|
160
|
+
def self.update_start_and_end
|
161
|
+
ActiveRecord::Base.connection.execute(UPDATE_SQL)
|
162
|
+
end
|
163
|
+
|
145
164
|
def self.get_data(sql)
|
146
165
|
ActiveRecord::Base.connection.execute(sql).to_a.map do |h|
|
147
166
|
h["id"] = h["id"].to_i
|
@@ -150,6 +169,7 @@ class Marty::Event < Marty::Base
|
|
150
169
|
h["end_dt"] = Time.zone.parse(h["end_dt"]) if h["end_dt"]
|
151
170
|
h["expire_secs"] = h["expire_secs"].to_i if h["expire_secs"]
|
152
171
|
h["comment"] = h["comment"]
|
172
|
+
h["error"] = h["error"]
|
153
173
|
h
|
154
174
|
end
|
155
175
|
end
|
@@ -166,6 +186,7 @@ class Marty::Event < Marty::Base
|
|
166
186
|
time_now_i = time_now.to_i
|
167
187
|
time_now_s = time_now.strftime('%Y-%m-%d %H:%M:%S.%6N')
|
168
188
|
if time_now_i - @all_running[:timestamp] > @poll_secs
|
189
|
+
update_start_and_end
|
169
190
|
@all_running[:data] = get_data(running_query(time_now_s))
|
170
191
|
@all_running[:timestamp] = time_now_i
|
171
192
|
end
|
@@ -184,6 +205,7 @@ class Marty::Event < Marty::Base
|
|
184
205
|
strftime('%Y-%m-%d %H:%M:%S.%6N')
|
185
206
|
|
186
207
|
if time_now_i - @all_finished[:timestamp] > @poll_secs
|
208
|
+
update_start_and_end
|
187
209
|
raw = get_data(
|
188
210
|
"SELECT * FROM
|
189
211
|
(SELECT ROW_NUMBER() OVER (PARTITION BY klass,
|
@@ -197,6 +219,14 @@ class Marty::Event < Marty::Base
|
|
197
219
|
)
|
198
220
|
@all_finished[:timestamp] = time_now_i
|
199
221
|
raw.each_with_object(@all_finished[:data]) do |ev, hash|
|
222
|
+
if ev["end_dt"] && ev["error"].nil?
|
223
|
+
real_ev = Marty::Event.where(id: ev["id"]).first
|
224
|
+
promise = Marty::Promise.where(id: real_ev["promise_id"]).first
|
225
|
+
maybe_error = promise.result["error"]
|
226
|
+
ev["error"] = real_ev.error = !!maybe_error
|
227
|
+
real_ev.comment = maybe_error
|
228
|
+
real_ev.save!
|
229
|
+
end
|
200
230
|
subhash = hash[[ev["klass"], ev["subject_id"]]] ||= {}
|
201
231
|
subhash[ev["enum_event_operation"]] =
|
202
232
|
ev["end_dt"].strftime("%Y-%m-%d %H:%M:%S")
|
data/lib/marty/version.rb
CHANGED
data/spec/job_helper.rb
CHANGED
@@ -95,6 +95,13 @@ SLEEPER:
|
|
95
95
|
a = Gemini::Helper.sleep(secs) && secs
|
96
96
|
EOS
|
97
97
|
|
98
|
+
NAME_J = "PromiseJ"
|
99
|
+
SCRIPT_J = <<EOS
|
100
|
+
FAILER:
|
101
|
+
dummy =? nil
|
102
|
+
a = ERR('I had an error')
|
103
|
+
EOS
|
104
|
+
|
98
105
|
def promise_bodies
|
99
106
|
{
|
100
107
|
NAME_A => SCRIPT_A,
|
@@ -106,5 +113,6 @@ def promise_bodies
|
|
106
113
|
NAME_G => SCRIPT_G,
|
107
114
|
NAME_H => SCRIPT_H,
|
108
115
|
NAME_I => SCRIPT_I,
|
116
|
+
NAME_J => SCRIPT_J,
|
109
117
|
}
|
110
118
|
end
|
data/spec/models/event_spec.rb
CHANGED
@@ -23,22 +23,26 @@ describe Marty::Event do
|
|
23
23
|
@old_start = '1970-01-01 08:00:00'
|
24
24
|
@old_end = '1970-01-01 09:00:00'
|
25
25
|
# add events
|
26
|
-
[['testcl1', 123, @time, nil, nil, 'AVM', 'a comment'
|
27
|
-
|
28
|
-
['testcl1', 123, @time +
|
29
|
-
|
30
|
-
['
|
26
|
+
[['testcl1', 123, @time, nil, nil, 'AVM', 'a comment',
|
27
|
+
nil],
|
28
|
+
['testcl1', 123, @time + 2.second, nil,nil, 'CRA', 'b comment',
|
29
|
+
nil],
|
30
|
+
['testcl1', 123, @time + 4.seconds, nil,10000, 'PRICING', 'c comment',
|
31
|
+
nil],
|
32
|
+
['testcl2', 123, @time, nil, 2, 'AVM', 'e comment', nil],
|
33
|
+
['testcl2', 123, @time + 1.second, nil, 4, 'CRA', 'f comment', nil],
|
31
34
|
['testcl2', 123, Time.zone.parse(@old_start),
|
32
|
-
Time.zone.parse(@old_end), nil, 'PRICING', 'old event'],
|
35
|
+
Time.zone.parse(@old_end), nil, 'PRICING', 'old event', 0],
|
33
36
|
].each do
|
34
|
-
|klass, subjid, startdt, enddt, expire, op, comment|
|
37
|
+
|klass, subjid, startdt, enddt, expire, op, comment, error|
|
35
38
|
Marty::Event.create!(klass: klass,
|
36
39
|
subject_id: subjid,
|
37
40
|
start_dt: startdt,
|
38
41
|
end_dt: enddt,
|
39
42
|
expire_secs: expire,
|
40
43
|
comment: comment,
|
41
|
-
enum_event_operation: op
|
44
|
+
enum_event_operation: op,
|
45
|
+
error: error)
|
42
46
|
end
|
43
47
|
|
44
48
|
|
@@ -48,6 +52,12 @@ describe Marty::Event do
|
|
48
52
|
id: 987,
|
49
53
|
operation: 'PRICING'})
|
50
54
|
res.force
|
55
|
+
engine = Marty::ScriptSet.new.get_engine(NAME_J)
|
56
|
+
res = engine.background_eval("FAILER", {"dummy" => "dummy"}, ["a"],
|
57
|
+
{klass: "testcl3",
|
58
|
+
id: 654,
|
59
|
+
operation: 'PRICING'})
|
60
|
+
res.force rescue nil
|
51
61
|
sleep 5
|
52
62
|
save_clean_db(@save_file)
|
53
63
|
end
|
@@ -69,7 +79,6 @@ describe Marty::Event do
|
|
69
79
|
['AVM', 'CRA', 'PRICING'])
|
70
80
|
expect(Marty::Event.currently_running('testcl2', 123)).to eq([])
|
71
81
|
expect(Marty::Event.currently_running('testcl3', 987)).to eq([])
|
72
|
-
|
73
82
|
expect(Marty::Event.last_event('testcl1', 123)).to include(
|
74
83
|
{"klass"=>"testcl1",
|
75
84
|
"subject_id"=>123,
|
@@ -78,9 +87,8 @@ describe Marty::Event do
|
|
78
87
|
expect(Marty::Event.last_event('testcl2', 123)).to include(
|
79
88
|
{"klass"=>"testcl2",
|
80
89
|
"subject_id"=>123,
|
81
|
-
"enum_event_operation"=>"
|
82
|
-
"comment"=>"
|
83
|
-
"expire_secs"=>4})
|
90
|
+
"enum_event_operation"=>"PRICING",
|
91
|
+
"comment"=>"old event"})
|
84
92
|
expect(Marty::Event.last_event('testcl3', 987)).to include(
|
85
93
|
{"klass"=>"testcl3",
|
86
94
|
"subject_id"=>987,
|
@@ -112,9 +120,29 @@ describe Marty::Event do
|
|
112
120
|
end
|
113
121
|
|
114
122
|
it "misc API tests" do
|
115
|
-
|
123
|
+
ev1 = Marty::Event.where(klass: 'testcl3', subject_id: 987).first
|
124
|
+
ev2 = Marty::Event.where(klass: 'testcl3', subject_id: 654).first
|
116
125
|
af = Marty::Event.all_finished
|
117
|
-
|
126
|
+
ev3 = Marty::Event.where(klass: 'testcl3', subject_id: 987).first
|
127
|
+
ev4 = Marty::Event.where(klass: 'testcl3', subject_id: 654).first
|
128
|
+
|
129
|
+
# ev1/ev2 should have null start/end
|
130
|
+
# ev3/ev4 should have start/end populated from promise and error status
|
131
|
+
expect(ev1.start_dt).to be_nil
|
132
|
+
expect(ev1.end_dt).to be_nil
|
133
|
+
expect(ev1.error).to be_falsey
|
134
|
+
expect(ev2.start_dt).to be_nil
|
135
|
+
expect(ev2.end_dt).to be_nil
|
136
|
+
expect(ev2.error).to be_falsey
|
137
|
+
|
138
|
+
expect(ev3.start_dt).not_to be_nil
|
139
|
+
expect(ev3.end_dt).not_to be_nil
|
140
|
+
expect(ev3.error).to be_falsey
|
141
|
+
expect(ev4.start_dt).not_to be_nil
|
142
|
+
expect(ev4.end_dt).not_to be_nil
|
143
|
+
expect(ev4.error).to be_truthy
|
144
|
+
|
145
|
+
expect(af.count).to eq(3)
|
118
146
|
expect(af).to include(['testcl3', 987])
|
119
147
|
expect(af).to include(['testcl2', 123])
|
120
148
|
expect(af[['testcl3', 987]]).to include('PRICING')
|
@@ -125,7 +153,7 @@ describe Marty::Event do
|
|
125
153
|
expect(Marty::Event.currently_running('testcl1', 123)).to eq(
|
126
154
|
['AVM', 'CRA', 'PRICING'])
|
127
155
|
expect(Marty::Event.op_is_running?('testcl1', 123, 'AVM')).to be_truthy
|
128
|
-
Marty::Event.finish_event('testcl1', 123, 'AVM', 'wassup')
|
156
|
+
Marty::Event.finish_event('testcl1', 123, 'AVM', false, 'wassup')
|
129
157
|
Marty::Event.clear_cache
|
130
158
|
expect(Marty::Event.currently_running('testcl1', 123)).to eq(
|
131
159
|
['CRA', 'PRICING'])
|
@@ -138,7 +166,8 @@ describe Marty::Event do
|
|
138
166
|
"subject_id"=>123,
|
139
167
|
"enum_event_operation"=>"AVM",
|
140
168
|
"comment"=>"wassup",
|
141
|
-
"expire_secs"=>nil
|
169
|
+
"expire_secs"=>nil,
|
170
|
+
"error"=>'f'})
|
142
171
|
Marty::Event.update_comment(ev.first, "updated")
|
143
172
|
ev = Marty::Event.lookup_event('testcl1', 123, 'AVM')
|
144
173
|
expect(ev.first).to include({"comment"=>"updated"})
|
@@ -148,11 +177,10 @@ describe Marty::Event do
|
|
148
177
|
expect(Marty::Event.pretty_op(ev)).to eq('Pricing')
|
149
178
|
|
150
179
|
af = Marty::Event.all_finished
|
151
|
-
expect(af.count).to eq(
|
180
|
+
expect(af.count).to eq(4)
|
152
181
|
expect(af[['testcl3', 987]]).to include('PRICING')
|
153
182
|
expect(af[['testcl1', 123]]).to include('AVM')
|
154
183
|
expect(af[['testcl1', 123]]['AVM']).to start_with(@date_string)
|
155
|
-
|
156
184
|
end
|
157
185
|
|
158
186
|
it "raises on error" do
|
@@ -164,20 +192,24 @@ describe Marty::Event do
|
|
164
192
|
to raise_error(%r!AVM is already running for testcl/1234!)
|
165
193
|
expect {Marty::Event.create_event('testcl', 2345, 'AVM', Time.zone.now, 600,
|
166
194
|
"the comment") }.not_to raise_error
|
167
|
-
expect {Marty::Event.finish_event('testcl', 1234, 'AVM',
|
195
|
+
expect {Marty::Event.finish_event('testcl', 1234, 'AVM', false,
|
196
|
+
"new comment") }.
|
168
197
|
not_to raise_error
|
169
|
-
expect {Marty::Event.finish_event('testcl', 1234, 'AVM',
|
198
|
+
expect {Marty::Event.finish_event('testcl', 1234, 'AVM', false,
|
199
|
+
"new comment") }.
|
170
200
|
to raise_error(%r!event testcl/1234/AVM not found!)
|
171
|
-
expect {Marty::Event.finish_event('testcl', 2345, 'AVM', 'foobar') }.
|
201
|
+
expect {Marty::Event.finish_event('testcl', 2345, 'AVM', false, 'foobar') }.
|
172
202
|
not_to raise_error
|
173
|
-
expect {Marty::Event.finish_event('testcl', 2345, 'AVM', 'foobar') }.
|
203
|
+
expect {Marty::Event.finish_event('testcl', 2345, 'AVM', false, 'foobar') }.
|
174
204
|
to raise_error(%r!event testcl/2345/AVM not found!)
|
205
|
+
expect {Marty::Event.finish_event('testcl', 2345, 'AVM', nil, 'foobar') }.
|
206
|
+
to raise_error(/error must be true or false/)
|
175
207
|
expect {Marty::Event.create_event('testcl', 1234, 'AMV', Time.zone.now, 600,
|
176
208
|
"the comment") }.
|
177
209
|
to raise_error(%r!PG::.*invalid input value for enum.*"AMV"!)
|
178
210
|
Marty::Event.clear_cache
|
179
211
|
af = Marty::Event.all_finished
|
180
|
-
expect(af.count).to eq(
|
212
|
+
expect(af.count).to eq(5)
|
181
213
|
expect(af).to include(['testcl', 1234])
|
182
214
|
expect(af).to include(['testcl', 2345])
|
183
215
|
expect(af[['testcl', 1234]]).to include('AVM')
|
@@ -200,7 +232,7 @@ describe Marty::Event do
|
|
200
232
|
|
201
233
|
Marty::Event.create_event('testcl', 789, 'AVM', Time.zone.now, 600,
|
202
234
|
"comment")
|
203
|
-
Marty::Event.finish_event('testcl', 789, 'AVM', long_comment)
|
235
|
+
Marty::Event.finish_event('testcl', 789, 'AVM', false, long_comment)
|
204
236
|
|
205
237
|
e1 = Marty::Event.lookup_event('testcl', 123, 'PRICING').first
|
206
238
|
e2 = Marty::Event.lookup_event('testcl', 456, 'CRA').first
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arman Bostani
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2016-
|
17
|
+
date: 2016-12-29 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: pg
|
@@ -436,6 +436,7 @@ files:
|
|
436
436
|
- db/migrate/106_make_grid_indexes_nullable.rb
|
437
437
|
- db/migrate/200_create_marty_event_operation_enum.rb
|
438
438
|
- db/migrate/201_create_marty_events.rb
|
439
|
+
- db/migrate/202_add_completion_status_to_event.rb
|
439
440
|
- db/seeds.rb
|
440
441
|
- gemini_deprecations.md
|
441
442
|
- lib/marty.rb
|