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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/librb/engine.rb +152 -85
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 298dc30af9fa87b5556c63f3e9053887fdcec4c7
4
- data.tar.gz: 47c61f7ada560539a88ce3dc1166b535c0f70604
3
+ metadata.gz: f801482db85dfb25b213d116aa0d014cdad42084
4
+ data.tar.gz: 409a2fcaed3552123300f4198d33f4a31fc77cbd
5
5
  SHA512:
6
- metadata.gz: 3f753cbf98f4486f7a08d551d32d7509f9a039ba0b2038e808a9d2ece43ba9c0bc7b9f8e3b1b15791998975e701744f6c80d090f951d33b96f239dd1a4afbf3a
7
- data.tar.gz: 946c9b9283724ded8302763689de2d41d333c2dc869742c07e63464a8d3998e6521aae09a5ba70677b2c850fb7bac3691fb983ec58f8deff9652d14d06c1ad75
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
- result_container = {}
548
+ state = nil
548
549
  action_handle = nil
549
550
  action_binding = nil
550
- state = nil
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
- complete.call e
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 "internal error #{e}"
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
- ((trigger.key? "to") && (trigger["to"] == state_name)) ||
737
- (trigger.key? :count) || (trigger.key? "count") ||
738
- (trigger.key? :cap) || (trigger.key? "cap") ||
739
- (trigger.key? :span) || (trigger.key? "span")
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
- (transition.key? :count) || (transition.key? "count") ||
922
- (transition.key? :cap) || (transition.key? "cap") ||
923
- (transition.key? :span) || (transition.key? "span")
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
- index = 1
1194
- timers = Timers::Group.new
1195
-
1196
- dispatch_ruleset = -> c {
1197
-
1198
- callback = -> e {
1199
- if index % 5 == 0
1200
- index += 1
1201
- timers.after 0.01, &dispatch_ruleset
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 += 1
1204
- dispatch_ruleset.call nil
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
- timers_callback = -> e {
1209
- if index % 5 == 0 && @ruleset_list.length > 0
1210
- ruleset = @ruleset_list[(index / 5) % @ruleset_list.length]
1211
- ruleset.dispatch_timers callback
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
- callback.call e
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.length > 0
1218
- ruleset = @ruleset_list[index % @ruleset_list.length]
1219
- ruleset.dispatch timers_callback
1278
+ if @ruleset_list.empty?
1279
+ timer.after 0.5, &thread_lambda
1220
1280
  else
1221
- timers_callback.call nil
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
- timers.after 0.01, &dispatch_ruleset
1288
+ timer.after 0.1, &thread_lambda
1289
+
1226
1290
  Thread.new do
1227
- loop { timers.wait }
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.06
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-14 00:00:00.000000000 Z
11
+ date: 2016-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake