durable_rules 0.34.06 → 0.34.07
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/librb/engine.rb +152 -85
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f801482db85dfb25b213d116aa0d014cdad42084
|
4
|
+
data.tar.gz: 409a2fcaed3552123300f4198d33f4a31fc77cbd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93816e1cd7f9da714223c40f358f25e4cee82863617721b9d1e47c46a6054b1a3057851a34db7706b717f34788da8460dedd1e68006614f087c94e82f3e3f251
|
7
|
+
data.tar.gz: d8dc3652fc040a1b0f4c255858c89b55652e9870547153eb1d9a7e4d8bed4ff952c3dcac6e2689c9d25edcb729fbfdbead94e0b620aff9231c6cdafd71057625
|
data/librb/engine.rb
CHANGED
@@ -3,11 +3,10 @@ require "timers"
|
|
3
3
|
require_relative "../src/rulesrb/rules"
|
4
4
|
|
5
5
|
module Engine
|
6
|
-
@@timers = nil
|
7
6
|
|
8
7
|
class Closure_Queue
|
9
8
|
attr_reader :_queued_posts, :_queued_asserts, :_queued_retracts
|
10
|
-
|
9
|
+
|
11
10
|
def initialize()
|
12
11
|
@_queued_posts = []
|
13
12
|
@_queued_asserts = []
|
@@ -246,7 +245,7 @@ module Engine
|
|
246
245
|
def to_s
|
247
246
|
@_d.to_s
|
248
247
|
end
|
249
|
-
|
248
|
+
|
250
249
|
private
|
251
250
|
|
252
251
|
def handle_property(name, value=nil)
|
@@ -283,7 +282,7 @@ module Engine
|
|
283
282
|
@sync = true
|
284
283
|
@root = self
|
285
284
|
@timers = Timers::Group.new
|
286
|
-
|
285
|
+
|
287
286
|
if func.arity > 1
|
288
287
|
@sync = false
|
289
288
|
end
|
@@ -305,13 +304,13 @@ module Engine
|
|
305
304
|
def run(c, complete)
|
306
305
|
if @sync
|
307
306
|
begin
|
308
|
-
@func.call c
|
307
|
+
@func.call c
|
309
308
|
rescue Exception => e
|
310
309
|
puts "unexpected error #{e}"
|
311
310
|
puts e.backtrace
|
312
311
|
c.s.exception = e.to_s
|
313
312
|
end
|
314
|
-
|
313
|
+
|
315
314
|
if @next
|
316
315
|
@next.run c, complete
|
317
316
|
else
|
@@ -350,7 +349,7 @@ module Engine
|
|
350
349
|
puts e.backtrace
|
351
350
|
c.s.exception = e.to_s
|
352
351
|
complete.call nil
|
353
|
-
end
|
352
|
+
end
|
354
353
|
end
|
355
354
|
end
|
356
355
|
|
@@ -368,9 +367,9 @@ module Engine
|
|
368
367
|
c.retract c.m[0].chart_context
|
369
368
|
else
|
370
369
|
c.retract c.chart_context
|
371
|
-
end
|
370
|
+
end
|
372
371
|
end
|
373
|
-
|
372
|
+
|
374
373
|
id = rand(1000000000)
|
375
374
|
if assert_state
|
376
375
|
c.assert(:label => to_state, :chart => 1, :id => id)
|
@@ -410,19 +409,19 @@ module Engine
|
|
410
409
|
@actions[rule_name] = action.root
|
411
410
|
elsif action.kind_of? Proc
|
412
411
|
@actions[rule_name] = Promise.new action
|
413
|
-
end
|
412
|
+
end
|
414
413
|
end
|
415
414
|
|
416
|
-
@handle = Rules.create_ruleset name, JSON.generate(ruleset_definition), state_cache_size
|
415
|
+
@handle = Rules.create_ruleset name, JSON.generate(ruleset_definition), state_cache_size
|
417
416
|
@definition = ruleset_definition
|
418
|
-
end
|
417
|
+
end
|
419
418
|
|
420
419
|
def bind(databases)
|
421
420
|
for db in databases do
|
422
421
|
if db.kind_of? String
|
423
422
|
Rules.bind_ruleset @handle, db, 0, nil
|
424
|
-
else
|
425
|
-
Rules.bind_ruleset @handle, db[:host], db[:port], db[:password]
|
423
|
+
else
|
424
|
+
Rules.bind_ruleset @handle, db[:host], db[:port], db[:password]
|
426
425
|
end
|
427
426
|
end
|
428
427
|
end
|
@@ -509,11 +508,11 @@ module Engine
|
|
509
508
|
|
510
509
|
def renew_action_lease(sid)
|
511
510
|
Rules.renew_action_lease @handle, sid.to_s
|
512
|
-
end
|
511
|
+
end
|
513
512
|
|
514
513
|
def Ruleset.create_rulesets(parent_name, host, ruleset_definitions, state_cache_size)
|
515
514
|
branches = {}
|
516
|
-
for name, definition in ruleset_definitions do
|
515
|
+
for name, definition in ruleset_definitions do
|
517
516
|
name = name.to_s
|
518
517
|
if name.end_with? "$state"
|
519
518
|
name = name[0..-7]
|
@@ -529,25 +528,27 @@ module Engine
|
|
529
528
|
end
|
530
529
|
end
|
531
530
|
|
532
|
-
branches
|
531
|
+
branches
|
533
532
|
end
|
534
533
|
|
535
534
|
def dispatch_timers(complete)
|
536
535
|
begin
|
537
|
-
Rules.assert_timers @handle
|
536
|
+
if !(Rules.assert_timers @handle)
|
537
|
+
complete.call nil, false
|
538
|
+
else
|
539
|
+
complete.call nil, true
|
540
|
+
end
|
538
541
|
rescue Exception => e
|
539
|
-
complete.call e
|
542
|
+
complete.call e, true
|
540
543
|
return
|
541
544
|
end
|
542
|
-
|
543
|
-
complete.call nil
|
544
545
|
end
|
545
|
-
|
546
|
+
|
546
547
|
def dispatch(complete, async_result = nil)
|
547
|
-
|
548
|
+
state = nil
|
548
549
|
action_handle = nil
|
549
550
|
action_binding = nil
|
550
|
-
|
551
|
+
result_container = {}
|
551
552
|
if async_result
|
552
553
|
state = async_result[0]
|
553
554
|
result_container = {:message => JSON.parse(async_result[1])}
|
@@ -556,18 +557,23 @@ module Engine
|
|
556
557
|
else
|
557
558
|
begin
|
558
559
|
result = Rules.start_action @handle
|
559
|
-
if result
|
560
|
+
if !result
|
561
|
+
complete.call nil, true
|
562
|
+
return
|
563
|
+
else
|
560
564
|
state = JSON.parse result[0]
|
561
565
|
result_container = {:message => JSON.parse(result[1])}
|
562
566
|
action_handle = result[2]
|
563
567
|
action_binding = result[3]
|
564
568
|
end
|
565
569
|
rescue Exception => e
|
566
|
-
|
570
|
+
puts "start action exception #{e}"
|
571
|
+
puts e.backtrace
|
572
|
+
complete.call e, true
|
567
573
|
return
|
568
574
|
end
|
569
575
|
end
|
570
|
-
|
576
|
+
|
571
577
|
while result_container.key? :message do
|
572
578
|
action_name = nil
|
573
579
|
for action_name, message in result_container[:message] do
|
@@ -580,15 +586,15 @@ module Engine
|
|
580
586
|
if result_container.key? :async
|
581
587
|
result_container.delete :async
|
582
588
|
end
|
583
|
-
|
589
|
+
|
584
590
|
@actions[action_name].run c, -> e {
|
585
591
|
if c.has_completed
|
586
592
|
return
|
587
593
|
end
|
588
|
-
|
594
|
+
|
589
595
|
if e
|
590
596
|
Rules.abandon_action @handle, c.handle
|
591
|
-
complete.call e
|
597
|
+
complete.call e, true
|
592
598
|
else
|
593
599
|
begin
|
594
600
|
for timer_id, timer in c._cancelled_timers do
|
@@ -602,17 +608,17 @@ module Engine
|
|
602
608
|
for ruleset_name, q in c._queues do
|
603
609
|
for message in q._queued_posts do
|
604
610
|
sid = (message.key? :sid) ? message[:sid]: message['sid']
|
605
|
-
queue_assert_event sid.to_s, ruleset_name, message
|
611
|
+
queue_assert_event sid.to_s, ruleset_name, message
|
606
612
|
end
|
607
613
|
|
608
614
|
for message in q._queued_asserts do
|
609
615
|
sid = (message.key? :sid) ? message[:sid]: message['sid']
|
610
|
-
queue_assert_fact sid.to_s, ruleset_name, message
|
616
|
+
queue_assert_fact sid.to_s, ruleset_name, message
|
611
617
|
end
|
612
618
|
|
613
619
|
for message in q._queued_retracts do
|
614
620
|
sid = (message.key? :sid) ? message[:sid]: message['sid']
|
615
|
-
queue_retract_fact sid.to_s, ruleset_name, message
|
621
|
+
queue_retract_fact sid.to_s, ruleset_name, message
|
616
622
|
end
|
617
623
|
end
|
618
624
|
|
@@ -674,7 +680,7 @@ module Engine
|
|
674
680
|
new_result = Rules.complete_and_start_action @handle, replies, c.handle
|
675
681
|
if new_result
|
676
682
|
if result_container.key? :async
|
677
|
-
dispatch -> e {}, [state, new_result, action_handle, action_binding]
|
683
|
+
dispatch -> e, wait {}, [state, new_result, action_handle, action_binding]
|
678
684
|
else
|
679
685
|
result_container[:message] = JSON.parse new_result
|
680
686
|
end
|
@@ -684,24 +690,24 @@ module Engine
|
|
684
690
|
end
|
685
691
|
rescue Exception => e
|
686
692
|
Rules.abandon_action @handle, c.handle
|
687
|
-
puts "
|
693
|
+
puts "unknown exception #{e}"
|
688
694
|
puts e.backtrace
|
689
|
-
complete.call e
|
695
|
+
complete.call e, true
|
690
696
|
end
|
691
697
|
|
692
698
|
if c._deleted
|
693
699
|
begin
|
694
700
|
delete_state c.s.sid
|
695
701
|
rescue Exception => e
|
696
|
-
complete.call e
|
702
|
+
complete.call e, true
|
697
703
|
end
|
698
704
|
end
|
699
705
|
|
700
706
|
end
|
701
707
|
}
|
702
|
-
result_container[:async] = true
|
708
|
+
result_container[:async] = true
|
703
709
|
end
|
704
|
-
complete.call nil
|
710
|
+
complete.call nil, false
|
705
711
|
end
|
706
712
|
|
707
713
|
def to_json
|
@@ -725,22 +731,22 @@ module Engine
|
|
725
731
|
def transform(parent_name, parent_triggers, parent_start_state, chart_definition, rules)
|
726
732
|
start_state = {}
|
727
733
|
reflexive_states = {}
|
728
|
-
|
734
|
+
|
729
735
|
for state_name, state in chart_definition do
|
730
736
|
qualified_name = state_name.to_s
|
731
737
|
qualified_name = "#{parent_name}.#{state_name}" if parent_name
|
732
738
|
start_state[qualified_name] = true
|
733
739
|
|
734
740
|
for trigger_name, trigger in state do
|
735
|
-
if ((trigger.key? :to) && (trigger[:to] == state_name)) ||
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
741
|
+
if ((trigger.key? :to) && (trigger[:to] == state_name)) ||
|
742
|
+
((trigger.key? "to") && (trigger["to"] == state_name)) ||
|
743
|
+
(trigger.key? :count) || (trigger.key? "count") ||
|
744
|
+
(trigger.key? :cap) || (trigger.key? "cap") ||
|
745
|
+
(trigger.key? :span) || (trigger.key? "span")
|
740
746
|
reflexive_states[qualified_name] = true
|
741
747
|
end
|
742
748
|
end
|
743
|
-
end
|
749
|
+
end
|
744
750
|
|
745
751
|
for state_name, state in chart_definition do
|
746
752
|
qualified_name = state_name.to_s
|
@@ -756,7 +762,7 @@ module Engine
|
|
756
762
|
|
757
763
|
for trigger_name, trigger in state do
|
758
764
|
trigger_name = trigger_name.to_s
|
759
|
-
if trigger_name != "$chart"
|
765
|
+
if trigger_name != "$chart"
|
760
766
|
if parent_name && (trigger.key? "to")
|
761
767
|
to_name = trigger["to"].to_s
|
762
768
|
trigger["to"] = "#{parent_name}.#{to_name}"
|
@@ -768,7 +774,7 @@ module Engine
|
|
768
774
|
end
|
769
775
|
end
|
770
776
|
|
771
|
-
if state.key? "$chart"
|
777
|
+
if state.key? "$chart"
|
772
778
|
transform qualified_name, triggers, start_state, state["$chart"], rules
|
773
779
|
elsif state.key? :$chart
|
774
780
|
transform qualified_name, triggers, start_state, state[:$chart], rules
|
@@ -809,7 +815,7 @@ module Engine
|
|
809
815
|
else
|
810
816
|
all_trigger = trigger["all"]
|
811
817
|
end
|
812
|
-
rule[:all] = all_trigger.dup
|
818
|
+
rule[:all] = all_trigger.dup
|
813
819
|
rule[:all] << state_test
|
814
820
|
elsif (trigger.key? :any) || (trigger.key? "any")
|
815
821
|
any_trigger = nil
|
@@ -819,10 +825,10 @@ module Engine
|
|
819
825
|
any_trigger = trigger["any"]
|
820
826
|
end
|
821
827
|
rule[:all] = [state_test, {"m$any" => any_trigger}]
|
822
|
-
else
|
828
|
+
else
|
823
829
|
rule[:all] = [state_test]
|
824
830
|
end
|
825
|
-
|
831
|
+
|
826
832
|
if (trigger.key? "run") || (trigger.key? :run)
|
827
833
|
trigger_run = nil
|
828
834
|
if trigger.key? :run
|
@@ -837,7 +843,7 @@ module Engine
|
|
837
843
|
rule[:run] = trigger_run
|
838
844
|
elsif trigger_run.kind_of? Proc
|
839
845
|
rule[:run] = Promise.new trigger_run
|
840
|
-
end
|
846
|
+
end
|
841
847
|
end
|
842
848
|
|
843
849
|
if (trigger.key? "to") || (trigger.key? :to)
|
@@ -917,10 +923,10 @@ module Engine
|
|
917
923
|
end
|
918
924
|
else
|
919
925
|
for transition_name, transition in stage_to do
|
920
|
-
if (transition_name == stage_name) ||
|
921
|
-
|
922
|
-
|
923
|
-
|
926
|
+
if (transition_name == stage_name) ||
|
927
|
+
(transition.key? :count) || (transition.key? "count") ||
|
928
|
+
(transition.key? :cap) || (transition.key? "cap") ||
|
929
|
+
(transition.key? :span) || (transition.key? "span")
|
924
930
|
reflexive_stages[stage_name] = true
|
925
931
|
end
|
926
932
|
end
|
@@ -933,7 +939,7 @@ module Engine
|
|
933
939
|
if reflexive_stages.key? stage_name
|
934
940
|
from_stage = stage_name
|
935
941
|
end
|
936
|
-
|
942
|
+
|
937
943
|
stage_name = stage_name.to_s
|
938
944
|
stage_test = {:chart_context => {:$and => [{:label => stage_name}, {:chart => 1}]}}
|
939
945
|
if (stage.key? :to) || (stage.key? "to")
|
@@ -1004,7 +1010,7 @@ module Engine
|
|
1004
1010
|
else
|
1005
1011
|
all_transition = transition["all"]
|
1006
1012
|
end
|
1007
|
-
rule[:all] = all_transition.dup
|
1013
|
+
rule[:all] = all_transition.dup
|
1008
1014
|
rule[:all] << stage_test
|
1009
1015
|
elsif (transition.key? :any) || (transition.key? "any")
|
1010
1016
|
any_transition = nil
|
@@ -1014,7 +1020,7 @@ module Engine
|
|
1014
1020
|
any_transition = transition["any"]
|
1015
1021
|
end
|
1016
1022
|
rule[:all] = [stage_test, {"m$any" => any_transition}]
|
1017
|
-
else
|
1023
|
+
else
|
1018
1024
|
rule[:all] = [stage_test]
|
1019
1025
|
end
|
1020
1026
|
|
@@ -1178,7 +1184,7 @@ module Engine
|
|
1178
1184
|
rulesets = Ruleset.create_rulesets(parent_name, self, ruleset_definitions, @state_cache_size)
|
1179
1185
|
for ruleset_name, ruleset in rulesets do
|
1180
1186
|
if @ruleset_directory.key? ruleset_name
|
1181
|
-
raise ArgumentError, "Ruleset with name #{ruleset_name} already registered"
|
1187
|
+
raise ArgumentError, "Ruleset with name #{ruleset_name} already registered"
|
1182
1188
|
end
|
1183
1189
|
|
1184
1190
|
@ruleset_directory[ruleset_name] = ruleset
|
@@ -1190,42 +1196,103 @@ module Engine
|
|
1190
1196
|
end
|
1191
1197
|
|
1192
1198
|
def start!
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1199
|
+
|
1200
|
+
start_dispatch_ruleset_thread
|
1201
|
+
|
1202
|
+
start_dispatch_timers_thread
|
1203
|
+
|
1204
|
+
end
|
1205
|
+
|
1206
|
+
private
|
1207
|
+
|
1208
|
+
def start_dispatch_timers_thread
|
1209
|
+
|
1210
|
+
timer = Timers::Group.new
|
1211
|
+
|
1212
|
+
thread_lambda = -> c {
|
1213
|
+
|
1214
|
+
callback = -> e, w {
|
1215
|
+
inner_wait = Thread.current[:wait]
|
1216
|
+
if e
|
1217
|
+
puts "unexpected error #{e}"
|
1218
|
+
elsif !w
|
1219
|
+
inner_wait = false
|
1220
|
+
end
|
1221
|
+
|
1222
|
+
if (Thread.current[:index] == (@ruleset_list.length-1)) & inner_wait
|
1223
|
+
Thread.current[:index] = (Thread.current[:index] + 1) % @ruleset_list.length
|
1224
|
+
Thread.current[:wait] = inner_wait
|
1225
|
+
timer.after 0.25, &thread_lambda
|
1202
1226
|
else
|
1203
|
-
index
|
1204
|
-
|
1227
|
+
Thread.current[:index] = (Thread.current[:index] + 1) % @ruleset_list.length
|
1228
|
+
Thread.current[:wait] = inner_wait
|
1229
|
+
timer.after 0, &thread_lambda
|
1205
1230
|
end
|
1206
1231
|
}
|
1207
1232
|
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1233
|
+
if @ruleset_list.length > 0
|
1234
|
+
ruleset = @ruleset_list[Thread.current[:index]]
|
1235
|
+
Thread.current[:wait] = true unless Thread.current[:index] > 0
|
1236
|
+
ruleset.dispatch_timers callback
|
1237
|
+
else
|
1238
|
+
timer.after 0.5, &thread_lambda
|
1239
|
+
end
|
1240
|
+
|
1241
|
+
}
|
1242
|
+
|
1243
|
+
timer.after 0.1, &thread_lambda
|
1244
|
+
|
1245
|
+
Thread.new do
|
1246
|
+
Thread.current[:index] = 0
|
1247
|
+
Thread.current[:wait] = 0
|
1248
|
+
loop { timer.wait }
|
1249
|
+
end
|
1250
|
+
|
1251
|
+
end
|
1252
|
+
|
1253
|
+
def start_dispatch_ruleset_thread
|
1254
|
+
|
1255
|
+
timer = Timers::Group.new
|
1256
|
+
|
1257
|
+
thread_lambda = -> c {
|
1258
|
+
|
1259
|
+
callback = -> e, w {
|
1260
|
+
inner_wait = Thread.current[:wait]
|
1261
|
+
if e
|
1262
|
+
puts "unexpected error #{e}"
|
1263
|
+
puts e.backtrace
|
1264
|
+
elsif !w
|
1265
|
+
inner_wait = false
|
1266
|
+
end
|
1267
|
+
if (Thread.current[:index] == (@ruleset_list.length-1)) & inner_wait
|
1268
|
+
Thread.current[:index] = ( Thread.current[:index] + 1 ) % @ruleset_list.length
|
1269
|
+
Thread.current[:wait] = inner_wait
|
1270
|
+
timer.after 0.25, &thread_lambda
|
1212
1271
|
else
|
1213
|
-
|
1272
|
+
Thread.current[:index] = ( Thread.current[:index] + 1 ) % @ruleset_list.length
|
1273
|
+
Thread.current[:wait] = inner_wait
|
1274
|
+
timer.after 0, &thread_lambda
|
1214
1275
|
end
|
1215
1276
|
}
|
1216
1277
|
|
1217
|
-
if @ruleset_list.
|
1218
|
-
|
1219
|
-
ruleset.dispatch timers_callback
|
1278
|
+
if @ruleset_list.empty?
|
1279
|
+
timer.after 0.5, &thread_lambda
|
1220
1280
|
else
|
1221
|
-
|
1281
|
+
ruleset = @ruleset_list[Thread.current[:index]]
|
1282
|
+
Thread.current[:wait] = true if (Thread.current[:index] > 0)
|
1283
|
+
ruleset.dispatch callback
|
1222
1284
|
end
|
1285
|
+
|
1223
1286
|
}
|
1224
1287
|
|
1225
|
-
|
1288
|
+
timer.after 0.1, &thread_lambda
|
1289
|
+
|
1226
1290
|
Thread.new do
|
1227
|
-
|
1291
|
+
Thread.current[:index] = 0
|
1292
|
+
Thread.current[:wait] = 0
|
1293
|
+
loop { timer.wait }
|
1228
1294
|
end
|
1295
|
+
|
1229
1296
|
end
|
1230
1297
|
|
1231
1298
|
end
|
@@ -1237,11 +1304,11 @@ module Engine
|
|
1237
1304
|
@handle = Rules.create_client @_ruleset_name, state_cache_size
|
1238
1305
|
if database.kind_of? String
|
1239
1306
|
Rules.bind_ruleset @handle, database, 0, nil
|
1240
|
-
else
|
1241
|
-
Rules.bind_ruleset @handle, database[:host], database[:port], database[:password]
|
1307
|
+
else
|
1308
|
+
Rules.bind_ruleset @handle, database[:host], database[:port], database[:password]
|
1242
1309
|
end
|
1243
1310
|
end
|
1244
|
-
|
1311
|
+
|
1245
1312
|
def post(message)
|
1246
1313
|
sid = (message.key? :sid) ? message[:sid]: message['sid']
|
1247
1314
|
Rules.queue_assert_event @handle, sid.to_s, @_ruleset_name, JSON.generate(message)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: durable_rules
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.34.
|
4
|
+
version: 0.34.07
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jesus Ruiz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|