durable_rules 0.34.02 → 0.34.03
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/librb/engine.rb +46 -1
- data/src/rules/json.c +9 -0
- data/src/rules/net.c +1373 -1084
- data/src/rules/net.h +4 -0
- data/src/rules/rules.h +3 -0
- data/src/rules/state.c +10 -0
- data/src/rulesrb/rules.c +16 -0
- 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: e2140bced1252c9b280451f9fc98d586b88af859
|
4
|
+
data.tar.gz: 28c6962e51f7d51d22f26aaa374c5f079e46a91c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c462a03d557ec58f26df72d5c81b6f3026348fa606f75590882a29ef35a4da226337aebff6315695e27dac7d4251937497a7eac778822972ce70a375cfe868bd
|
7
|
+
data.tar.gz: 229e8f7d619835b4c9902f764798b7099fbf0ebe6c5442c36fd4f5aca136a0be488b65c187273dbf2f18b14e88ff821ef48007499fa41a67e71145f19feb8c3f
|
data/librb/engine.rb
CHANGED
@@ -40,7 +40,7 @@ module Engine
|
|
40
40
|
end
|
41
41
|
|
42
42
|
class Closure
|
43
|
-
attr_reader :host, :handle, :ruleset_name, :_timers, :_cancelled_timers, :_branches, :_messages, :_queues, :_facts, :_retract
|
43
|
+
attr_reader :host, :handle, :ruleset_name, :_timers, :_cancelled_timers, :_branches, :_messages, :_queues, :_facts, :_retract, :_deletes, :_deleted
|
44
44
|
attr_accessor :s
|
45
45
|
|
46
46
|
def initialize(host, state, message, handle, ruleset_name)
|
@@ -52,11 +52,13 @@ module Engine
|
|
52
52
|
@_cancelled_timers = {}
|
53
53
|
@_messages = {}
|
54
54
|
@_queues = {}
|
55
|
+
@_deletes = {}
|
55
56
|
@_branches = {}
|
56
57
|
@_facts = {}
|
57
58
|
@_retract = {}
|
58
59
|
@_start_time = Time.now
|
59
60
|
@_completed = false
|
61
|
+
@_deleted = false
|
60
62
|
if message.kind_of? Hash
|
61
63
|
@m = message
|
62
64
|
else
|
@@ -93,6 +95,28 @@ module Engine
|
|
93
95
|
message_list << message
|
94
96
|
end
|
95
97
|
|
98
|
+
def delete(ruleset_name = nil, sid = nil)
|
99
|
+
if !ruleset_name
|
100
|
+
ruleset_name = @ruleset_name
|
101
|
+
end
|
102
|
+
|
103
|
+
if !sid
|
104
|
+
sid = @s.sid
|
105
|
+
end
|
106
|
+
|
107
|
+
if (ruleset_name == @ruleset_name) && (sid == @s.sid)
|
108
|
+
@_deleted = true
|
109
|
+
end
|
110
|
+
|
111
|
+
sid_list = []
|
112
|
+
if @_deletes.key? ruleset_name
|
113
|
+
sid_list = @_deletes[ruleset_name]
|
114
|
+
else
|
115
|
+
@_deletes[ruleset_name] = sid_list
|
116
|
+
end
|
117
|
+
sid_list << sid
|
118
|
+
end
|
119
|
+
|
96
120
|
def get_queue(ruleset_name)
|
97
121
|
if !@_queues.key? ruleset_name
|
98
122
|
@_queues[ruleset_name] = Closure_Queue.new
|
@@ -479,6 +503,10 @@ module Engine
|
|
479
503
|
JSON.parse Rules.get_state(@handle, sid.to_s)
|
480
504
|
end
|
481
505
|
|
506
|
+
def delete_state(sid)
|
507
|
+
Rules.delete_state(@handle, sid.to_s)
|
508
|
+
end
|
509
|
+
|
482
510
|
def renew_action_lease(sid)
|
483
511
|
Rules.renew_action_lease @handle, sid.to_s
|
484
512
|
end
|
@@ -588,6 +616,10 @@ module Engine
|
|
588
616
|
end
|
589
617
|
end
|
590
618
|
|
619
|
+
for ruleset_name, sid in c._deletes do
|
620
|
+
@host.delete_state ruleset_name, sid
|
621
|
+
end
|
622
|
+
|
591
623
|
binding = 0
|
592
624
|
replies = 0
|
593
625
|
pending = {action_binding => 0}
|
@@ -656,6 +688,15 @@ module Engine
|
|
656
688
|
puts e.backtrace
|
657
689
|
complete.call e
|
658
690
|
end
|
691
|
+
|
692
|
+
if c._deleted
|
693
|
+
begin
|
694
|
+
delete_state c.s.sid
|
695
|
+
rescue Exception => e
|
696
|
+
complete.call e
|
697
|
+
end
|
698
|
+
end
|
699
|
+
|
659
700
|
end
|
660
701
|
}
|
661
702
|
result_container[:async] = true
|
@@ -1073,6 +1114,10 @@ module Engine
|
|
1073
1114
|
get_ruleset(ruleset_name).get_state sid
|
1074
1115
|
end
|
1075
1116
|
|
1117
|
+
def delete_state(ruleset_name, sid)
|
1118
|
+
get_ruleset(ruleset_name).delete_state sid
|
1119
|
+
end
|
1120
|
+
|
1076
1121
|
def post_batch(ruleset_name, *events)
|
1077
1122
|
get_ruleset(ruleset_name).assert_events events
|
1078
1123
|
end
|
data/src/rules/json.c
CHANGED
@@ -177,6 +177,15 @@ static unsigned int getValue(char *start, char **first, char **last, unsigned ch
|
|
177
177
|
} else {
|
178
178
|
return ERR_PARSE_STRING;
|
179
179
|
}
|
180
|
+
} else if (start[0] == 'n') {
|
181
|
+
if (strncmp(start, "null", 4) == 0) {
|
182
|
+
*first = start;
|
183
|
+
*last = start + 3;
|
184
|
+
*type = JSON_NIL;
|
185
|
+
return PARSE_OK;
|
186
|
+
} else {
|
187
|
+
return ERR_PARSE_STRING;
|
188
|
+
}
|
180
189
|
} else if (start[0] == '{') {
|
181
190
|
*type = JSON_OBJECT;
|
182
191
|
unsigned int result = getObject(start, first, last);
|
data/src/rules/net.c
CHANGED
@@ -104,6 +104,7 @@ static unsigned int createIdiom(ruleset *tree, jsonValue *newValue, char **idiom
|
|
104
104
|
if (asprintf(idiomString, "%g", newValue->value.d) == -1) {
|
105
105
|
return ERR_OUT_OF_MEMORY;
|
106
106
|
}
|
107
|
+
break;
|
107
108
|
case JSON_BOOL:
|
108
109
|
if (newValue->value.b == 0) {
|
109
110
|
if (asprintf(idiomString, "false") == -1) {
|
@@ -304,7 +305,8 @@ static unsigned int createTest(ruleset *tree, expression *expr, char **test, cha
|
|
304
305
|
return RULES_OK;
|
305
306
|
}
|
306
307
|
|
307
|
-
static unsigned int loadPartitionCommand(ruleset *tree, binding *rulesBinding
|
308
|
+
static unsigned int loadPartitionCommand(ruleset *tree, binding *rulesBinding) {
|
309
|
+
char *name = &tree->stringPool[tree->nameOffset];
|
308
310
|
redisContext *reContext = rulesBinding->reContext;
|
309
311
|
redisReply *reply;
|
310
312
|
char *lua = NULL;
|
@@ -335,7 +337,8 @@ static unsigned int loadPartitionCommand(ruleset *tree, binding *rulesBinding, c
|
|
335
337
|
return RULES_OK;
|
336
338
|
}
|
337
339
|
|
338
|
-
static unsigned int loadRemoveActionCommand(ruleset *tree, binding *rulesBinding
|
340
|
+
static unsigned int loadRemoveActionCommand(ruleset *tree, binding *rulesBinding) {
|
341
|
+
char *name = &tree->stringPool[tree->nameOffset];
|
339
342
|
redisContext *reContext = rulesBinding->reContext;
|
340
343
|
redisReply *reply;
|
341
344
|
char *lua = NULL;
|
@@ -386,7 +389,8 @@ static unsigned int loadRemoveActionCommand(ruleset *tree, binding *rulesBinding
|
|
386
389
|
return RULES_OK;
|
387
390
|
}
|
388
391
|
|
389
|
-
static unsigned int loadTimerCommand(ruleset *tree, binding *rulesBinding
|
392
|
+
static unsigned int loadTimerCommand(ruleset *tree, binding *rulesBinding) {
|
393
|
+
char *name = &tree->stringPool[tree->nameOffset];
|
390
394
|
redisContext *reContext = rulesBinding->reContext;
|
391
395
|
redisReply *reply;
|
392
396
|
char *lua = NULL;
|
@@ -419,7 +423,8 @@ static unsigned int loadTimerCommand(ruleset *tree, binding *rulesBinding, char
|
|
419
423
|
return RULES_OK;
|
420
424
|
}
|
421
425
|
|
422
|
-
static unsigned int loadUpdateActionCommand(ruleset *tree, binding *rulesBinding
|
426
|
+
static unsigned int loadUpdateActionCommand(ruleset *tree, binding *rulesBinding) {
|
427
|
+
char *name = &tree->stringPool[tree->nameOffset];
|
423
428
|
redisContext *reContext = rulesBinding->reContext;
|
424
429
|
redisReply *reply;
|
425
430
|
char *lua = NULL;
|
@@ -448,212 +453,137 @@ static unsigned int loadUpdateActionCommand(ruleset *tree, binding *rulesBinding
|
|
448
453
|
return RULES_OK;
|
449
454
|
}
|
450
455
|
|
451
|
-
static unsigned int
|
452
|
-
|
453
|
-
|
454
|
-
|
456
|
+
static unsigned int loadDeleteSessionCommand(ruleset *tree, binding *rulesBinding) {
|
457
|
+
char *name = &tree->stringPool[tree->nameOffset];
|
458
|
+
redisContext *reContext = rulesBinding->reContext;
|
459
|
+
redisReply *reply;
|
460
|
+
char *lua = NULL;
|
461
|
+
char *deleteSessionLua = NULL;
|
462
|
+
deleteSessionLua = (char*)calloc(1, sizeof(char));
|
463
|
+
if (!deleteSessionLua) {
|
455
464
|
return ERR_OUT_OF_MEMORY;
|
456
465
|
}
|
457
466
|
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
467
|
+
for (unsigned int i = 0; i < tree->nodeOffset; ++i) {
|
468
|
+
node *currentNode = &tree->nodePool[i];
|
469
|
+
|
470
|
+
if (currentNode->type == NODE_ACTION) {
|
471
|
+
char *actionName = &tree->stringPool[currentNode->nameOffset];
|
472
|
+
char *oldDeleteSessionLua = NULL;
|
473
|
+
for (unsigned int ii = 0; ii < currentNode->value.c.joinsLength; ++ii) {
|
474
|
+
unsigned int currentJoinOffset = tree->nextPool[currentNode->value.c.joinsOffset + ii];
|
475
|
+
join *currentJoin = &tree->joinPool[currentJoinOffset];
|
463
476
|
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
477
|
+
oldDeleteSessionLua = deleteSessionLua;
|
478
|
+
if (asprintf(&deleteSessionLua,
|
479
|
+
"%sredis.call(\"del\", \"%s!%d!r!\" .. sid)\n"
|
480
|
+
"redis.call(\"del\", \"%s!%d!r!\" .. sid .. \"!d\")\n",
|
481
|
+
deleteSessionLua,
|
482
|
+
actionName,
|
483
|
+
ii,
|
484
|
+
actionName,
|
485
|
+
ii) == -1) {
|
486
|
+
return ERR_OUT_OF_MEMORY;
|
487
|
+
}
|
488
|
+
free(oldDeleteSessionLua);
|
468
489
|
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
rulesBinding->factsHashset = factsHashset;
|
490
|
+
for (unsigned int iii = 0; iii < currentJoin->expressionsLength; ++iii) {
|
491
|
+
unsigned int expressionOffset = tree->nextPool[currentJoin->expressionsOffset + iii];
|
492
|
+
expression *expr = &tree->expressionPool[expressionOffset];
|
493
|
+
char *currentKey = &tree->stringPool[expr->nameOffset];
|
474
494
|
|
475
|
-
|
476
|
-
|
477
|
-
|
495
|
+
oldDeleteSessionLua = deleteSessionLua;
|
496
|
+
if (asprintf(&deleteSessionLua,
|
497
|
+
"%sdelete_message_keys(\"%s!f!\" .. sid)\n"
|
498
|
+
"delete_message_keys(\"%s!e!\" .. sid)\n"
|
499
|
+
"delete_closure_keys(\"%s!c!\" .. sid)\n"
|
500
|
+
"delete_closure_keys(\"%s!i!\" .. sid)\n",
|
501
|
+
deleteSessionLua,
|
502
|
+
currentKey,
|
503
|
+
currentKey,
|
504
|
+
currentKey,
|
505
|
+
currentKey) == -1) {
|
506
|
+
return ERR_OUT_OF_MEMORY;
|
507
|
+
}
|
508
|
+
free(oldDeleteSessionLua);
|
509
|
+
}
|
510
|
+
}
|
511
|
+
}
|
478
512
|
}
|
479
513
|
|
480
|
-
strncpy(eventsHashset, name, nameLength);
|
481
|
-
eventsHashset[nameLength] = '!';
|
482
|
-
eventsHashset[nameLength + 1] = 'e';
|
483
|
-
eventsHashset[nameLength + 2] = '\0';
|
484
|
-
rulesBinding->eventsHashset = eventsHashset;
|
485
514
|
|
486
|
-
|
487
|
-
|
515
|
+
if (asprintf(&lua,
|
516
|
+
"local sid = ARGV[1]\n"
|
517
|
+
"local delete_message_keys = function(events_key)\n"
|
518
|
+
" local all_keys = redis.call(\"keys\", events_key .. \"!m!*\")\n"
|
519
|
+
" for i = 1, #all_keys, 1 do\n"
|
520
|
+
" redis.call(\"del\", all_keys[i])\n"
|
521
|
+
" end\n"
|
522
|
+
" redis.call(\"del\", events_key)\n"
|
523
|
+
"end\n"
|
524
|
+
"local delete_closure_keys = function(closure_key)\n"
|
525
|
+
" local all_keys = redis.call(\"keys\", closure_key .. \"!*\")\n"
|
526
|
+
" for i = 1, #all_keys, 1 do\n"
|
527
|
+
" redis.call(\"del\", all_keys[i])\n"
|
528
|
+
" end\n"
|
529
|
+
"end\n"
|
530
|
+
"redis.call(\"hdel\", \"%s!s\", sid)\n"
|
531
|
+
"redis.call(\"zrem\", \"%s!a\", sid)\n"
|
532
|
+
"redis.call(\"del\", \"%s!a!\" .. sid)\n"
|
533
|
+
"redis.call(\"del\", \"%s!e!\" .. sid)\n"
|
534
|
+
"redis.call(\"del\", \"%s!f!\" .. sid)\n"
|
535
|
+
"redis.call(\"del\", \"%s!v!\" .. sid)\n%s",
|
536
|
+
name,
|
537
|
+
name,
|
538
|
+
name,
|
539
|
+
name,
|
540
|
+
name,
|
541
|
+
name,
|
542
|
+
deleteSessionLua) == -1) {
|
488
543
|
return ERR_OUT_OF_MEMORY;
|
489
544
|
}
|
490
545
|
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
|
500
|
-
char *name = &tree->stringPool[tree->nameOffset];
|
501
|
-
int nameLength = strlen(name);
|
502
|
-
unsigned int result = loadPartitionCommand(tree, rulesBinding, name);
|
503
|
-
if (result != RULES_OK) {
|
504
|
-
return result;
|
505
|
-
}
|
506
|
-
|
507
|
-
// client queues have no commands to load,
|
508
|
-
if (!tree->stringPool) {
|
509
|
-
return RULES_OK;
|
510
|
-
}
|
511
|
-
|
512
|
-
result = loadRemoveActionCommand(tree, rulesBinding, name);
|
513
|
-
if (result != RULES_OK) {
|
514
|
-
return result;
|
515
|
-
}
|
516
|
-
|
517
|
-
result = loadTimerCommand(tree, rulesBinding, name);
|
518
|
-
if (result != RULES_OK) {
|
519
|
-
return result;
|
520
|
-
}
|
521
|
-
|
522
|
-
result = loadUpdateActionCommand(tree, rulesBinding, name);
|
523
|
-
if (result != RULES_OK) {
|
524
|
-
return result;
|
546
|
+
free(deleteSessionLua);
|
547
|
+
redisAppendCommand(reContext, "SCRIPT LOAD %s", lua);
|
548
|
+
redisGetReply(reContext, (void**)&reply);
|
549
|
+
if (reply->type == REDIS_REPLY_ERROR) {
|
550
|
+
printf("%s\n", reply->str);
|
551
|
+
freeReplyObject(reply);
|
552
|
+
free(lua);
|
553
|
+
return ERR_REDIS_ERROR;
|
525
554
|
}
|
526
555
|
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
556
|
+
strncpy(rulesBinding->deleteSessionHash, reply->str, 40);
|
557
|
+
rulesBinding->deleteSessionHash[40] = '\0';
|
558
|
+
freeReplyObject(reply);
|
559
|
+
free(lua);
|
560
|
+
return RULES_OK;
|
531
561
|
|
562
|
+
}
|
563
|
+
static unsigned int loadAddMessageCommand(ruleset *tree, binding *rulesBinding) {
|
564
|
+
char *name = &tree->stringPool[tree->nameOffset];
|
532
565
|
redisContext *reContext = rulesBinding->reContext;
|
533
566
|
redisReply *reply;
|
534
|
-
#ifdef _WIN32
|
535
|
-
char *actionKey = (char *)_alloca(sizeof(char)*(nameLength + 3));
|
536
|
-
sprintf_s(actionKey, nameLength + 3, "%s!a", name);
|
537
|
-
#else
|
538
|
-
char actionKey[nameLength + 3];
|
539
|
-
snprintf(actionKey, nameLength + 3, "%s!a", name);
|
540
|
-
#endif
|
541
567
|
char *lua = NULL;
|
542
|
-
char *peekActionLua = NULL;
|
543
568
|
char *addMessageLua = NULL;
|
544
|
-
char *oldLua;
|
545
|
-
|
546
|
-
peekActionLua = (char*)calloc(1, sizeof(char));
|
547
|
-
if (!peekActionLua) {
|
548
|
-
return ERR_OUT_OF_MEMORY;
|
549
|
-
}
|
550
|
-
|
551
|
-
lua = (char*)calloc(1, sizeof(char));
|
552
|
-
if (!lua) {
|
553
|
-
return ERR_OUT_OF_MEMORY;
|
554
|
-
}
|
555
|
-
|
556
569
|
addMessageLua = (char*)calloc(1, sizeof(char));
|
557
570
|
if (!addMessageLua) {
|
558
571
|
return ERR_OUT_OF_MEMORY;
|
559
572
|
}
|
560
573
|
|
561
574
|
for (unsigned int i = 0; i < tree->nodeOffset; ++i) {
|
562
|
-
char *oldPeekActionLua;
|
563
575
|
node *currentNode = &tree->nodePool[i];
|
564
576
|
|
565
577
|
if (currentNode->type == NODE_ACTION) {
|
566
|
-
char *packFrameLua = NULL;
|
567
|
-
char *unpackFrameLua = NULL;
|
568
|
-
char *oldPackFrameLua = NULL;
|
569
|
-
char *oldUnpackFrameLua = NULL;
|
570
578
|
char *oldAddMessageLua = NULL;
|
571
|
-
char *actionName = &tree->stringPool[currentNode->nameOffset];
|
572
|
-
char *actionLastName = strchr(actionName, '!');
|
573
|
-
#ifdef _WIN32
|
574
|
-
char *actionAlias = (char *)_alloca(sizeof(char)*(actionLastName - actionName + 1));
|
575
|
-
#else
|
576
|
-
char actionAlias[actionLastName - actionName + 1];
|
577
|
-
#endif
|
578
|
-
|
579
|
-
strncpy(actionAlias, actionName, actionLastName - actionName);
|
580
|
-
actionAlias[actionLastName - actionName] = '\0';
|
581
|
-
|
582
579
|
for (unsigned int ii = 0; ii < currentNode->value.c.joinsLength; ++ii) {
|
583
580
|
unsigned int currentJoinOffset = tree->nextPool[currentNode->value.c.joinsOffset + ii];
|
584
581
|
join *currentJoin = &tree->joinPool[currentJoinOffset];
|
585
|
-
|
586
|
-
oldPeekActionLua = peekActionLua;
|
587
|
-
if (asprintf(&peekActionLua,
|
588
|
-
"%sif input_keys[\"%s!%d!r!\"] then\n"
|
589
|
-
"local context = {}\n"
|
590
|
-
"context_directory[\"%s!%d!r!\"] = context\n"
|
591
|
-
"reviewers = {}\n"
|
592
|
-
"context[\"reviewers\"] = reviewers\n"
|
593
|
-
"keys = {}\n"
|
594
|
-
"context[\"keys\"] = keys\n"
|
595
|
-
"primary_frame_keys = {}\n"
|
596
|
-
"context[\"primary_frame_keys\"] = primary_frame_keys\n",
|
597
|
-
peekActionLua,
|
598
|
-
actionName,
|
599
|
-
ii,
|
600
|
-
actionName,
|
601
|
-
ii) == -1) {
|
602
|
-
return ERR_OUT_OF_MEMORY;
|
603
|
-
}
|
604
|
-
free(oldPeekActionLua);
|
605
|
-
|
606
|
-
oldLua = lua;
|
607
|
-
if (asprintf(&lua,
|
608
|
-
"%stoggle = false\n"
|
609
|
-
"context = {}\n"
|
610
|
-
"reviewers = {}\n"
|
611
|
-
"context[\"reviewers\"] = reviewers\n"
|
612
|
-
"frame_packers = {}\n"
|
613
|
-
"context[\"frame_packers\"] = frame_packers\n"
|
614
|
-
"frame_unpackers = {}\n"
|
615
|
-
"context[\"frame_unpackers\"] = frame_unpackers\n"
|
616
|
-
"primary_message_keys = {}\n"
|
617
|
-
"context[\"primary_message_keys\"] = primary_message_keys\n"
|
618
|
-
"primary_frame_keys = {}\n"
|
619
|
-
"context[\"primary_frame_keys\"] = primary_frame_keys\n"
|
620
|
-
"keys = {}\n"
|
621
|
-
"context[\"keys\"] = keys\n"
|
622
|
-
"inverse_directory = {}\n"
|
623
|
-
"context[\"inverse_directory\"] = inverse_directory\n"
|
624
|
-
"directory = {[\"0\"] = 1}\n"
|
625
|
-
"context[\"directory\"] = directory\n"
|
626
|
-
"context[\"results_key\"] = \"%s!%d!r!\" .. sid\n"
|
627
|
-
"context[\"expressions_count\"] = %d\n",
|
628
|
-
lua,
|
629
|
-
actionName,
|
630
|
-
ii,
|
631
|
-
currentJoin->expressionsLength) == -1) {
|
632
|
-
return ERR_OUT_OF_MEMORY;
|
633
|
-
}
|
634
|
-
free(oldLua);
|
635
582
|
|
636
583
|
for (unsigned int iii = 0; iii < currentJoin->expressionsLength; ++iii) {
|
637
584
|
unsigned int expressionOffset = tree->nextPool[currentJoin->expressionsOffset + iii];
|
638
585
|
expression *expr = &tree->expressionPool[expressionOffset];
|
639
|
-
char *currentAlias = &tree->stringPool[expr->aliasOffset];
|
640
586
|
char *currentKey = &tree->stringPool[expr->nameOffset];
|
641
|
-
char *nextKeyTest;
|
642
|
-
if (iii == (currentJoin->expressionsLength - 1)) {
|
643
|
-
nextKeyTest = (char*)calloc(1, sizeof(char));
|
644
|
-
if (!nextKeyTest) {
|
645
|
-
return ERR_OUT_OF_MEMORY;
|
646
|
-
}
|
647
|
-
} else {
|
648
|
-
unsigned int nextExpressionOffset = tree->nextPool[currentJoin->expressionsOffset + iii + 1];
|
649
|
-
expression *nextExpr = &tree->expressionPool[nextExpressionOffset];
|
650
|
-
if (asprintf(&nextKeyTest,
|
651
|
-
"or input_keys[\"%s\"]",
|
652
|
-
&tree->stringPool[nextExpr->nameOffset]) == -1) {
|
653
|
-
return ERR_OUT_OF_MEMORY;
|
654
|
-
}
|
655
|
-
}
|
656
|
-
|
657
587
|
if (iii == 0) {
|
658
588
|
oldAddMessageLua = addMessageLua;
|
659
589
|
if (!addMessageLua) {
|
@@ -672,62 +602,175 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
|
|
672
602
|
return ERR_OUT_OF_MEMORY;
|
673
603
|
}
|
674
604
|
free(oldAddMessageLua);
|
605
|
+
} else {
|
606
|
+
char *test = NULL;
|
607
|
+
char *primaryKeyLua = NULL;
|
608
|
+
char *primaryFrameKeyLua = NULL;
|
609
|
+
unsigned int result = createTest(tree, expr, &test, &primaryKeyLua, &primaryFrameKeyLua);
|
610
|
+
if (result != RULES_OK) {
|
611
|
+
return result;
|
612
|
+
}
|
675
613
|
|
676
|
-
|
677
|
-
|
678
|
-
"
|
679
|
-
|
680
|
-
|
614
|
+
oldAddMessageLua = addMessageLua;
|
615
|
+
if (asprintf(&addMessageLua,
|
616
|
+
"%sif input_keys[\"%s\"] then\n"
|
617
|
+
" primary_message_keys[\"%s\"] = function(message)\n"
|
618
|
+
" local result = \"\"\n%s"
|
619
|
+
" return result\n"
|
620
|
+
" end\n"
|
621
|
+
"end\n",
|
622
|
+
addMessageLua,
|
623
|
+
currentKey,
|
624
|
+
currentKey,
|
625
|
+
primaryKeyLua) == -1) {
|
626
|
+
return ERR_OUT_OF_MEMORY;
|
627
|
+
}
|
628
|
+
free(oldAddMessageLua);
|
629
|
+
free(test);
|
630
|
+
free(primaryKeyLua);
|
631
|
+
free(primaryFrameKeyLua);
|
632
|
+
}
|
633
|
+
}
|
634
|
+
}
|
635
|
+
}
|
636
|
+
}
|
681
637
|
|
682
|
-
|
683
|
-
"
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
"
|
691
|
-
"
|
692
|
-
"
|
693
|
-
"
|
694
|
-
"
|
695
|
-
"
|
696
|
-
"
|
697
|
-
"
|
698
|
-
"
|
699
|
-
"
|
638
|
+
if (asprintf(&lua,
|
639
|
+
"local sid = ARGV[1]\n"
|
640
|
+
"local assert_fact = tonumber(ARGV[2])\n"
|
641
|
+
"local keys_count = tonumber(ARGV[3])\n"
|
642
|
+
"local events_hashset = \"%s!e!\" .. sid\n"
|
643
|
+
"local facts_hashset = \"%s!f!\" .. sid\n"
|
644
|
+
"local visited_hashset = \"%s!v!\" .. sid\n"
|
645
|
+
"local message = {}\n"
|
646
|
+
"local primary_message_keys = {}\n"
|
647
|
+
"local input_keys = {}\n"
|
648
|
+
"local save_message = function(current_key, message, events_key, messages_key)\n"
|
649
|
+
" redis.call(\"hsetnx\", messages_key, message[\"id\"], cmsgpack.pack(message))\n"
|
650
|
+
" local primary_key = primary_message_keys[current_key](message)\n"
|
651
|
+
" redis.call(\"lpush\", events_key .. \"!m!\" .. primary_key, message[\"id\"])\n"
|
652
|
+
"end\n"
|
653
|
+
"for index = 4 + keys_count, #ARGV, 3 do\n"
|
654
|
+
" if ARGV[index + 2] == \"1\" then\n"
|
655
|
+
" message[ARGV[index]] = ARGV[index + 1]\n"
|
656
|
+
" elseif ARGV[index + 2] == \"2\" or ARGV[index + 2] == \"3\" then\n"
|
657
|
+
" message[ARGV[index]] = tonumber(ARGV[index + 1])\n"
|
658
|
+
" elseif ARGV[index + 2] == \"4\" then\n"
|
659
|
+
" if ARGV[index + 1] == \"true\" then\n"
|
660
|
+
" message[ARGV[index]] = true\n"
|
661
|
+
" else\n"
|
662
|
+
" message[ARGV[index]] = false\n"
|
700
663
|
" end\n"
|
701
|
-
" return false\n"
|
702
|
-
" end\n"
|
703
|
-
" frame_packers[1] = function(frame, full_encode)\n"
|
704
|
-
" local result = {}\n%s"
|
705
|
-
" return cmsgpack.pack(result)\n"
|
706
664
|
" end\n"
|
707
|
-
"
|
708
|
-
"
|
709
|
-
"
|
710
|
-
"
|
665
|
+
"end\n"
|
666
|
+
"local mid = message[\"id\"]\n"
|
667
|
+
"if redis.call(\"hsetnx\", visited_hashset, message[\"id\"], 1) == 0 then\n"
|
668
|
+
" if assert_fact == 0 then\n"
|
669
|
+
" if not redis.call(\"hget\", events_hashset, mid) then\n"
|
670
|
+
" return false\n"
|
671
|
+
" end\n"
|
672
|
+
" else\n"
|
673
|
+
" if not redis.call(\"hget\", facts_hashset, mid) then\n"
|
674
|
+
" return false\n"
|
675
|
+
" end\n"
|
711
676
|
" end\n"
|
712
|
-
"
|
713
|
-
"
|
677
|
+
"end\n"
|
678
|
+
"for index = 4, 3 + keys_count, 1 do\n"
|
679
|
+
" input_keys[ARGV[index]] = true\n"
|
680
|
+
"end\n"
|
681
|
+
"%sif assert_fact == 1 then\n"
|
682
|
+
" message[\"$f\"] = 1\n"
|
683
|
+
" for index = 4, 3 + keys_count, 1 do\n"
|
684
|
+
" local key = ARGV[index]\n"
|
685
|
+
" save_message(key, message, key .. \"!f!\" .. sid, facts_hashset)\n"
|
714
686
|
" end\n"
|
715
|
-
"
|
716
|
-
"
|
687
|
+
"else\n"
|
688
|
+
" for index = 4, 3 + keys_count, 1 do\n"
|
689
|
+
" local key = ARGV[index]\n"
|
690
|
+
" save_message(key, message, key .. \"!e!\" .. sid, events_hashset)\n"
|
717
691
|
" end\n"
|
718
692
|
"end\n",
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
693
|
+
name,
|
694
|
+
name,
|
695
|
+
name,
|
696
|
+
addMessageLua) == -1) {
|
697
|
+
return ERR_OUT_OF_MEMORY;
|
698
|
+
}
|
699
|
+
|
700
|
+
free(addMessageLua);
|
701
|
+
redisAppendCommand(reContext, "SCRIPT LOAD %s", lua);
|
702
|
+
redisGetReply(reContext, (void**)&reply);
|
703
|
+
if (reply->type == REDIS_REPLY_ERROR) {
|
704
|
+
printf("%s\n", reply->str);
|
705
|
+
freeReplyObject(reply);
|
706
|
+
free(lua);
|
707
|
+
return ERR_REDIS_ERROR;
|
708
|
+
}
|
709
|
+
|
710
|
+
strncpy(rulesBinding->addMessageHash, reply->str, 40);
|
711
|
+
rulesBinding->addMessageHash[40] = '\0';
|
712
|
+
freeReplyObject(reply);
|
713
|
+
free(lua);
|
714
|
+
return RULES_OK;
|
715
|
+
}
|
716
|
+
|
717
|
+
static unsigned int loadPeekActionCommand(ruleset *tree, binding *rulesBinding) {
|
718
|
+
char *name = &tree->stringPool[tree->nameOffset];
|
719
|
+
redisContext *reContext = rulesBinding->reContext;
|
720
|
+
redisReply *reply;
|
721
|
+
char *lua = NULL;
|
722
|
+
|
723
|
+
char *peekActionLua = NULL;
|
724
|
+
peekActionLua = (char*)calloc(1, sizeof(char));
|
725
|
+
if (!peekActionLua) {
|
726
|
+
return ERR_OUT_OF_MEMORY;
|
727
|
+
}
|
728
|
+
|
729
|
+
for (unsigned int i = 0; i < tree->nodeOffset; ++i) {
|
730
|
+
char *oldPeekActionLua;
|
731
|
+
node *currentNode = &tree->nodePool[i];
|
732
|
+
|
733
|
+
if (currentNode->type == NODE_ACTION) {
|
734
|
+
char *unpackFrameLua = NULL;
|
735
|
+
char *oldUnpackFrameLua = NULL;
|
736
|
+
char *actionName = &tree->stringPool[currentNode->nameOffset];
|
737
|
+
for (unsigned int ii = 0; ii < currentNode->value.c.joinsLength; ++ii) {
|
738
|
+
unsigned int currentJoinOffset = tree->nextPool[currentNode->value.c.joinsOffset + ii];
|
739
|
+
join *currentJoin = &tree->joinPool[currentJoinOffset];
|
740
|
+
|
741
|
+
oldPeekActionLua = peekActionLua;
|
742
|
+
if (asprintf(&peekActionLua,
|
743
|
+
"%sif input_keys[\"%s!%d!r!\"] then\n"
|
744
|
+
"local context = {}\n"
|
745
|
+
"context_directory[\"%s!%d!r!\"] = context\n"
|
746
|
+
"reviewers = {}\n"
|
747
|
+
"context[\"reviewers\"] = reviewers\n"
|
748
|
+
"keys = {}\n"
|
749
|
+
"context[\"keys\"] = keys\n"
|
750
|
+
"primary_frame_keys = {}\n"
|
751
|
+
"context[\"primary_frame_keys\"] = primary_frame_keys\n",
|
752
|
+
peekActionLua,
|
753
|
+
actionName,
|
754
|
+
ii,
|
755
|
+
actionName,
|
756
|
+
ii) == -1) {
|
757
|
+
return ERR_OUT_OF_MEMORY;
|
758
|
+
}
|
759
|
+
free(oldPeekActionLua);
|
760
|
+
|
761
|
+
for (unsigned int iii = 0; iii < currentJoin->expressionsLength; ++iii) {
|
762
|
+
unsigned int expressionOffset = tree->nextPool[currentJoin->expressionsOffset + iii];
|
763
|
+
expression *expr = &tree->expressionPool[expressionOffset];
|
764
|
+
char *currentAlias = &tree->stringPool[expr->aliasOffset];
|
765
|
+
char *currentKey = &tree->stringPool[expr->nameOffset];
|
766
|
+
|
767
|
+
if (iii == 0) {
|
768
|
+
if (expr->not) {
|
769
|
+
if (asprintf(&unpackFrameLua,
|
770
|
+
" result[\"%s\"] = \"$n\"\n",
|
771
|
+
currentAlias) == -1) {
|
728
772
|
return ERR_OUT_OF_MEMORY;
|
729
773
|
}
|
730
|
-
free(oldLua);
|
731
774
|
|
732
775
|
oldPeekActionLua = peekActionLua;
|
733
776
|
if (!peekActionLua) {
|
@@ -750,19 +793,7 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
|
|
750
793
|
return ERR_OUT_OF_MEMORY;
|
751
794
|
}
|
752
795
|
free(oldPeekActionLua);
|
753
|
-
// not (expr->not)
|
754
796
|
} else {
|
755
|
-
if (asprintf(&packFrameLua,
|
756
|
-
" message = frame[\"%s\"]\n"
|
757
|
-
" if full_encode and not message[\"$f\"] then\n"
|
758
|
-
" result[1] = message\n"
|
759
|
-
" else\n"
|
760
|
-
" result[1] = message[\"id\"]\n"
|
761
|
-
" end\n",
|
762
|
-
currentAlias) == -1) {
|
763
|
-
return ERR_OUT_OF_MEMORY;
|
764
|
-
}
|
765
|
-
|
766
797
|
if (asprintf(&unpackFrameLua,
|
767
798
|
" message = fetch_message(frame[1])\n"
|
768
799
|
" if not message then\n"
|
@@ -773,87 +804,16 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
|
|
773
804
|
return ERR_OUT_OF_MEMORY;
|
774
805
|
}
|
775
806
|
|
776
|
-
oldLua = lua;
|
777
|
-
if (asprintf(&lua,
|
778
|
-
"%sif input_keys[\"%s\"] %s then\n"
|
779
|
-
" toggle = true\n"
|
780
|
-
" context_directory[\"%s\"] = context\n"
|
781
|
-
" keys[1] = \"%s\"\n"
|
782
|
-
" inverse_directory[1] = true\n"
|
783
|
-
" directory[\"%s\"] = 1\n"
|
784
|
-
" reviewers[1] = function(message, frame, index)\n"
|
785
|
-
" if message then\n"
|
786
|
-
" frame[\"%s\"] = message\n"
|
787
|
-
" return true\n"
|
788
|
-
" end\n"
|
789
|
-
" return false\n"
|
790
|
-
" end\n"
|
791
|
-
" frame_packers[1] = function(frame, full_encode)\n"
|
792
|
-
" local result = {}\n"
|
793
|
-
" local message\n%s"
|
794
|
-
" return cmsgpack.pack(result)\n"
|
795
|
-
" end\n"
|
796
|
-
" frame_unpackers[1] = function(packed_frame)\n"
|
797
|
-
" local frame = cmsgpack.unpack(packed_frame)\n"
|
798
|
-
" local result = {}\n"
|
799
|
-
" local message\n%s"
|
800
|
-
" return result\n"
|
801
|
-
" end\n"
|
802
|
-
" primary_message_keys[1] = function(message)\n"
|
803
|
-
" return \"\"\n"
|
804
|
-
" end\n"
|
805
|
-
" primary_frame_keys[1] = function(frame)\n"
|
806
|
-
" return \"\"\n"
|
807
|
-
" end\n"
|
808
|
-
"end\n",
|
809
|
-
lua,
|
810
|
-
currentKey,
|
811
|
-
nextKeyTest,
|
812
|
-
currentKey,
|
813
|
-
currentKey,
|
814
|
-
currentKey,
|
815
|
-
currentAlias,
|
816
|
-
packFrameLua,
|
817
|
-
unpackFrameLua) == -1) {
|
818
|
-
return ERR_OUT_OF_MEMORY;
|
819
|
-
}
|
820
|
-
free(oldLua);
|
821
807
|
}
|
822
|
-
// not (iii == 0)
|
823
808
|
} else {
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
oldAddMessageLua = addMessageLua;
|
833
|
-
if (asprintf(&addMessageLua,
|
834
|
-
"%sif input_keys[\"%s\"] then\n"
|
835
|
-
" primary_message_keys[\"%s\"] = function(message)\n"
|
836
|
-
" local result = \"\"\n%s"
|
837
|
-
" return result\n"
|
838
|
-
" end\n"
|
839
|
-
"end\n",
|
840
|
-
addMessageLua,
|
841
|
-
currentKey,
|
842
|
-
currentKey,
|
843
|
-
primaryKeyLua) == -1) {
|
844
|
-
return ERR_OUT_OF_MEMORY;
|
845
|
-
}
|
846
|
-
free(oldAddMessageLua);
|
847
|
-
|
848
|
-
if (expr->not) {
|
849
|
-
oldPackFrameLua = packFrameLua;
|
850
|
-
if (asprintf(&packFrameLua,
|
851
|
-
"%s result[%d] = \"$n\"\n",
|
852
|
-
packFrameLua,
|
853
|
-
iii + 1) == -1) {
|
854
|
-
return ERR_OUT_OF_MEMORY;
|
809
|
+
if (expr->not) {
|
810
|
+
char *test = NULL;
|
811
|
+
char *primaryKeyLua = NULL;
|
812
|
+
char *primaryFrameKeyLua = NULL;
|
813
|
+
unsigned int result = createTest(tree, expr, &test, &primaryKeyLua, &primaryFrameKeyLua);
|
814
|
+
if (result != RULES_OK) {
|
815
|
+
return result;
|
855
816
|
}
|
856
|
-
free(oldPackFrameLua);
|
857
817
|
|
858
818
|
oldUnpackFrameLua = unpackFrameLua;
|
859
819
|
if (asprintf(&unpackFrameLua,
|
@@ -864,64 +824,6 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
|
|
864
824
|
}
|
865
825
|
free(oldUnpackFrameLua);
|
866
826
|
|
867
|
-
oldLua = lua;
|
868
|
-
if (asprintf(&lua,
|
869
|
-
"%sif toggle %s then\n"
|
870
|
-
" toggle = true\n"
|
871
|
-
" context_directory[\"%s\"] = context\n"
|
872
|
-
" keys[%d] = \"%s\"\n"
|
873
|
-
" inverse_directory[%d] = true\n"
|
874
|
-
" directory[\"%s\"] = %d\n"
|
875
|
-
" reviewers[%d] = function(message, frame, index)\n"
|
876
|
-
" if not message or not (%s) then\n"
|
877
|
-
" frame[\"%s\"] = \"$n\"\n"
|
878
|
-
" return true\n"
|
879
|
-
" end\n"
|
880
|
-
" return false\n"
|
881
|
-
" end\n"
|
882
|
-
" frame_packers[%d] = function(frame, full_encode)\n"
|
883
|
-
" local result = {}\n"
|
884
|
-
" local message\n%s"
|
885
|
-
" return cmsgpack.pack(result)\n"
|
886
|
-
" end\n"
|
887
|
-
" frame_unpackers[%d] = function(packed_frame)\n"
|
888
|
-
" local frame = cmsgpack.unpack(packed_frame)\n"
|
889
|
-
" local result = {}\n"
|
890
|
-
" local message\n%s"
|
891
|
-
" return result\n"
|
892
|
-
" end\n"
|
893
|
-
" primary_message_keys[%d] = function(message)\n"
|
894
|
-
" local result = \"\"\n%s"
|
895
|
-
" return result\n"
|
896
|
-
" end\n"
|
897
|
-
" primary_frame_keys[%d] = function(frame)\n"
|
898
|
-
" local result = \"\"\n%s"
|
899
|
-
" return result\n"
|
900
|
-
" end\n"
|
901
|
-
"end\n",
|
902
|
-
lua,
|
903
|
-
nextKeyTest,
|
904
|
-
currentKey,
|
905
|
-
iii + 1,
|
906
|
-
currentKey,
|
907
|
-
iii + 1,
|
908
|
-
currentKey,
|
909
|
-
iii + 1,
|
910
|
-
iii + 1,
|
911
|
-
test,
|
912
|
-
currentAlias,
|
913
|
-
iii + 1,
|
914
|
-
packFrameLua,
|
915
|
-
iii + 1,
|
916
|
-
unpackFrameLua,
|
917
|
-
iii + 1,
|
918
|
-
primaryKeyLua,
|
919
|
-
iii + 1,
|
920
|
-
primaryFrameKeyLua) == -1) {
|
921
|
-
return ERR_OUT_OF_MEMORY;
|
922
|
-
}
|
923
|
-
free(oldLua);
|
924
|
-
|
925
827
|
oldPeekActionLua = peekActionLua;
|
926
828
|
if (asprintf(&peekActionLua,
|
927
829
|
"%skeys[%d] = \"%s\"\n"
|
@@ -945,25 +847,10 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
|
|
945
847
|
return ERR_OUT_OF_MEMORY;
|
946
848
|
}
|
947
849
|
free(oldPeekActionLua);
|
948
|
-
|
949
|
-
|
850
|
+
free(test);
|
851
|
+
free(primaryKeyLua);
|
852
|
+
free(primaryFrameKeyLua);
|
950
853
|
} else {
|
951
|
-
oldPackFrameLua = packFrameLua;
|
952
|
-
if (asprintf(&packFrameLua,
|
953
|
-
"%s message = frame[\"%s\"]\n"
|
954
|
-
" if full_encode and not message[\"$f\"] then\n"
|
955
|
-
" result[%d] = message\n"
|
956
|
-
" else\n"
|
957
|
-
" result[%d] = message[\"id\"]\n"
|
958
|
-
" end\n",
|
959
|
-
packFrameLua,
|
960
|
-
currentAlias,
|
961
|
-
iii + 1,
|
962
|
-
iii + 1) == -1) {
|
963
|
-
return ERR_OUT_OF_MEMORY;
|
964
|
-
}
|
965
|
-
free(oldPackFrameLua);
|
966
|
-
|
967
854
|
oldUnpackFrameLua = unpackFrameLua;
|
968
855
|
if (asprintf(&unpackFrameLua,
|
969
856
|
"%s message = fetch_message(frame[%d])\n"
|
@@ -977,69 +864,7 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
|
|
977
864
|
return ERR_OUT_OF_MEMORY;
|
978
865
|
}
|
979
866
|
free(oldUnpackFrameLua);
|
980
|
-
|
981
|
-
oldLua = lua;
|
982
|
-
if (asprintf(&lua,
|
983
|
-
"%sif toggle %s then\n"
|
984
|
-
" toggle = true\n"
|
985
|
-
" context_directory[\"%s\"] = context\n"
|
986
|
-
" keys[%d] = \"%s\"\n"
|
987
|
-
" directory[\"%s\"] = %d\n"
|
988
|
-
" reviewers[%d] = function(message, frame, index)\n"
|
989
|
-
" if message and %s then\n"
|
990
|
-
" frame[\"%s\"] = message\n"
|
991
|
-
" return true\n"
|
992
|
-
" end\n"
|
993
|
-
" return false\n"
|
994
|
-
" end\n"
|
995
|
-
" frame_packers[%d] = function(frame, full_encode)\n"
|
996
|
-
" local result = {}\n"
|
997
|
-
" local message\n%s"
|
998
|
-
" return cmsgpack.pack(result)\n"
|
999
|
-
" end\n"
|
1000
|
-
" frame_unpackers[%d] = function(packed_frame)\n"
|
1001
|
-
" local frame = cmsgpack.unpack(packed_frame)\n"
|
1002
|
-
" local result = {}\n"
|
1003
|
-
" local message\n%s"
|
1004
|
-
" return result\n"
|
1005
|
-
" end\n"
|
1006
|
-
" primary_message_keys[%d] = function(message)\n"
|
1007
|
-
" local result = \"\"\n%s"
|
1008
|
-
" return result\n"
|
1009
|
-
" end\n"
|
1010
|
-
" primary_frame_keys[%d] = function(frame)\n"
|
1011
|
-
" local result = \"\"\n%s"
|
1012
|
-
" return result\n"
|
1013
|
-
" end\n"
|
1014
|
-
"end\n",
|
1015
|
-
lua,
|
1016
|
-
nextKeyTest,
|
1017
|
-
currentKey,
|
1018
|
-
iii + 1,
|
1019
|
-
currentKey,
|
1020
|
-
currentKey,
|
1021
|
-
iii + 1,
|
1022
|
-
iii + 1,
|
1023
|
-
test,
|
1024
|
-
currentAlias,
|
1025
|
-
iii + 1,
|
1026
|
-
packFrameLua,
|
1027
|
-
iii + 1,
|
1028
|
-
unpackFrameLua,
|
1029
|
-
iii + 1,
|
1030
|
-
primaryKeyLua,
|
1031
|
-
iii + 1,
|
1032
|
-
primaryFrameKeyLua) == -1) {
|
1033
|
-
return ERR_OUT_OF_MEMORY;
|
1034
|
-
}
|
1035
|
-
free(oldLua);
|
1036
|
-
// done not (expr->not)
|
1037
867
|
}
|
1038
|
-
free(nextKeyTest);
|
1039
|
-
free(test);
|
1040
|
-
free(primaryKeyLua);
|
1041
|
-
free(primaryFrameKeyLua);
|
1042
|
-
// done not (iii == 0)
|
1043
868
|
}
|
1044
869
|
}
|
1045
870
|
|
@@ -1057,103 +882,29 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
|
|
1057
882
|
}
|
1058
883
|
free(oldPeekActionLua);
|
1059
884
|
|
1060
|
-
if (currentNode->value.c.span > 0) {
|
1061
|
-
oldLua = lua;
|
1062
|
-
if (asprintf(&lua,
|
1063
|
-
"%sif toggle then\n"
|
1064
|
-
" context[\"process_key\"] = process_key_with_span\n"
|
1065
|
-
" context[\"process_key_count\"] = %d\n"
|
1066
|
-
"end\n",
|
1067
|
-
lua,
|
1068
|
-
currentNode->value.c.span) == -1) {
|
1069
|
-
return ERR_OUT_OF_MEMORY;
|
1070
|
-
}
|
1071
|
-
free(oldLua);
|
1072
|
-
|
1073
|
-
} else if (currentNode->value.c.cap > 0) {
|
1074
|
-
oldLua = lua;
|
1075
|
-
if (asprintf(&lua,
|
1076
|
-
"%sif toggle then\n"
|
1077
|
-
" context[\"process_key\"] = process_key_with_cap\n"
|
1078
|
-
" context[\"process_key_count\"] = %d\n"
|
1079
|
-
"end\n",
|
1080
|
-
lua,
|
1081
|
-
currentNode->value.c.cap) == -1) {
|
1082
|
-
return ERR_OUT_OF_MEMORY;
|
1083
|
-
}
|
1084
|
-
free(oldLua);
|
1085
|
-
|
1086
|
-
} else {
|
1087
|
-
oldLua = lua;
|
1088
|
-
if (asprintf(&lua,
|
1089
|
-
"%sif toggle then\n"
|
1090
|
-
" context[\"process_key\"] = process_key_with_window\n"
|
1091
|
-
" context[\"process_key_count\"] = %d\n"
|
1092
|
-
"end\n",
|
1093
|
-
lua,
|
1094
|
-
currentNode->value.c.count) == -1) {
|
1095
|
-
return ERR_OUT_OF_MEMORY;
|
1096
|
-
}
|
1097
|
-
free(oldLua);
|
1098
|
-
}
|
1099
885
|
}
|
1100
886
|
|
1101
887
|
free(unpackFrameLua);
|
1102
|
-
free(packFrameLua);
|
1103
888
|
}
|
1104
889
|
}
|
1105
890
|
|
1106
|
-
|
1107
|
-
|
1108
|
-
"local
|
1109
|
-
"local
|
1110
|
-
"local score = tonumber(ARGV[3])\n"
|
1111
|
-
"local assert_fact = tonumber(ARGV[4])\n"
|
1112
|
-
"local keys_count = tonumber(ARGV[5])\n"
|
1113
|
-
"local events_hashset = \"%s!e!\" .. sid\n"
|
1114
|
-
"local facts_hashset = \"%s!f!\" .. sid\n"
|
1115
|
-
"local visited_hashset = \"%s!v!\" .. sid\n"
|
1116
|
-
"local actions_key = \"%s!a\"\n"
|
891
|
+
if (asprintf(&lua,
|
892
|
+
"local facts_key = \"%s!f!\"\n"
|
893
|
+
"local events_key = \"%s!e!\"\n"
|
894
|
+
"local action_key = \"%s!a\"\n"
|
1117
895
|
"local state_key = \"%s!s\"\n"
|
1118
|
-
"local
|
1119
|
-
"local facts_message_cache = {}\n"
|
1120
|
-
"local events_message_cache = {}\n"
|
1121
|
-
"local facts_mids_cache = {}\n"
|
1122
|
-
"local events_mids_cache = {}\n"
|
896
|
+
"local timers_key = \"%s!t\"\n"
|
1123
897
|
"local context_directory = {}\n"
|
1124
|
-
"local input_keys = {}\n"
|
1125
|
-
"local toggle\n"
|
1126
|
-
"local expressions_count\n"
|
1127
|
-
"local results\n"
|
1128
|
-
"local unpacked_results\n"
|
1129
|
-
"local context\n"
|
1130
898
|
"local keys\n"
|
1131
899
|
"local reviewers\n"
|
1132
|
-
"local frame_packers\n"
|
1133
|
-
"local frame_unpackers\n"
|
1134
|
-
"local primary_message_keys\n"
|
1135
900
|
"local primary_frame_keys\n"
|
1136
|
-
"local
|
1137
|
-
"local
|
1138
|
-
"local
|
1139
|
-
"local
|
1140
|
-
"local
|
1141
|
-
"
|
1142
|
-
"
|
1143
|
-
" local new_mids = event_mids[primary_key]\n"
|
1144
|
-
" local result_mids = {}\n"
|
1145
|
-
" for i = 1, #new_mids, 1 do\n"
|
1146
|
-
" local new_mid = new_mids[i]\n"
|
1147
|
-
" if message_cache[new_mid] ~= false then\n"
|
1148
|
-
" table.insert(result_mids, new_mid)\n"
|
1149
|
-
" end\n"
|
1150
|
-
" end\n"
|
1151
|
-
" event_mids[primary_key] = result_mids\n"
|
1152
|
-
" redis.call(\"del\", events_key .. \"!m!\" .. primary_key)\n"
|
1153
|
-
" for i = 1, #result_mids, 1 do\n"
|
1154
|
-
" redis.call(\"rpush\", events_key .. \"!m!\" .. primary_key, result_mids[i])\n"
|
1155
|
-
" end\n"
|
1156
|
-
"end\n"
|
901
|
+
"local facts_hashset\n"
|
902
|
+
"local events_hashset\n"
|
903
|
+
"local events_message_cache = {}\n"
|
904
|
+
"local facts_message_cache = {}\n"
|
905
|
+
"local facts_mids_cache = {}\n"
|
906
|
+
"local events_mids_cache = {}\n"
|
907
|
+
"local get_context\n"
|
1157
908
|
"local get_mids = function(index, frame, events_key, messages_key, mids_cache, message_cache)\n"
|
1158
909
|
" local event_mids = mids_cache[events_key]\n"
|
1159
910
|
" local primary_key = primary_frame_keys[index](frame)\n"
|
@@ -1185,412 +936,697 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
|
|
1185
936
|
" return message\n"
|
1186
937
|
"end\n"
|
1187
938
|
"local fetch_message = function(new_mid)\n"
|
1188
|
-
"
|
1189
|
-
"
|
1190
|
-
" message = get_message(new_mid, facts_hashset, facts_message_cache)\n"
|
939
|
+
" if type(new_mid) == \"table\" then\n"
|
940
|
+
" return new_mid\n"
|
1191
941
|
" end\n"
|
1192
|
-
" return
|
1193
|
-
"end\n"
|
1194
|
-
"local save_message = function(index, message, events_key, messages_key)\n"
|
1195
|
-
" redis.call(\"hsetnx\", messages_key, message[\"id\"], cmsgpack.pack(message))\n"
|
1196
|
-
" local primary_key = primary_message_keys[index](message)\n"
|
1197
|
-
" redis.call(\"lpush\", events_key .. \"!m!\" .. primary_key, message[\"id\"])\n"
|
942
|
+
" return get_message(new_mid, facts_hashset, facts_message_cache)\n"
|
1198
943
|
"end\n"
|
1199
|
-
"local
|
1200
|
-
"
|
1201
|
-
"
|
1202
|
-
"
|
1203
|
-
" if message
|
1204
|
-
"
|
1205
|
-
|
1206
|
-
"
|
944
|
+
"local validate_frame_for_key = function(packed_frame, frame, index, events_list_key, messages_key, mids_cache, message_cache, sid)\n"
|
945
|
+
" local new_mids = get_mids(index, frame, events_list_key, messages_key, mids_cache, message_cache)\n"
|
946
|
+
" for i = 1, #new_mids, 1 do\n"
|
947
|
+
" local message = get_message(new_mids[i], messages_key, message_cache)\n"
|
948
|
+
" if message and not reviewers[index](message, frame, index) then\n"
|
949
|
+
" local frames_key = keys[index] .. \"!i!\" .. sid .. \"!\" .. new_mids[i]\n"
|
950
|
+
" redis.call(\"rpush\", frames_key, packed_frame)\n"
|
951
|
+
" return false\n"
|
1207
952
|
" end\n"
|
1208
953
|
" end\n"
|
954
|
+
" return true\n"
|
1209
955
|
"end\n"
|
1210
|
-
"local
|
1211
|
-
" local
|
1212
|
-
"
|
1213
|
-
"
|
1214
|
-
" return false\n"
|
1215
|
-
" end\n"
|
1216
|
-
" message_count = message_count + 1\n"
|
1217
|
-
" end\n"
|
1218
|
-
" return (message_count == index - 1)\n"
|
956
|
+
"local validate_frame = function(packed_frame, frame, index, sid)\n"
|
957
|
+
" local first_result = validate_frame_for_key(packed_frame, frame, index, keys[index] .. \"!e!\" .. sid, events_hashset, events_mids_cache, events_message_cache, sid)\n"
|
958
|
+
" local second_result = validate_frame_for_key(packed_frame, frame, index, keys[index] ..\"!f!\" .. sid, facts_hashset, facts_mids_cache, facts_message_cache, sid)\n"
|
959
|
+
" return first_result and second_result\n"
|
1219
960
|
"end\n"
|
1220
|
-
"local
|
1221
|
-
"local
|
1222
|
-
" local
|
1223
|
-
" local
|
1224
|
-
"
|
1225
|
-
"
|
961
|
+
"local review_frame = function(frame, rule_action_key, sid, max_score)\n"
|
962
|
+
" local indexes = {}\n"
|
963
|
+
" local action_id = string.sub(rule_action_key, 1, (string.len(sid) + 1) * -1)\n"
|
964
|
+
" local context = get_context(action_id)\n"
|
965
|
+
" local full_frame = {}\n"
|
966
|
+
" local cancel = false\n"
|
967
|
+
" events_hashset = events_key .. sid\n"
|
968
|
+
" facts_hashset = facts_key .. sid\n"
|
969
|
+
" keys = context[\"keys\"]\n"
|
970
|
+
" reviewers = context[\"reviewers\"]\n"
|
971
|
+
" primary_frame_keys = context[\"primary_frame_keys\"]\n"
|
972
|
+
" if not context[\"frame_restore\"](frame, full_frame) then\n"
|
973
|
+
" cancel = true\n"
|
974
|
+
" else\n"
|
975
|
+
" for i = 1, #frame, 1 do\n"
|
976
|
+
" if frame[i] == \"$n\" then\n"
|
977
|
+
" if not validate_frame(frame, full_frame, i, sid) then\n"
|
978
|
+
" cancel = true\n"
|
979
|
+
" break\n"
|
980
|
+
" end\n"
|
981
|
+
" end\n"
|
982
|
+
" end\n"
|
1226
983
|
" end\n"
|
1227
|
-
" if
|
1228
|
-
"
|
1229
|
-
"
|
1230
|
-
"
|
1231
|
-
"
|
1232
|
-
" result = process_frame(new_frame, index + 1, use_facts)\n"
|
1233
|
-
" if result == 0 or use_facts then\n"
|
1234
|
-
" local frames_key\n"
|
1235
|
-
" local primary_key = primary_frame_keys[index + 1](new_frame)\n"
|
1236
|
-
" frames_key = keys[index + 1] .. \"!c!\" .. sid .. \"!\" .. primary_key\n"
|
1237
|
-
" redis.call(\"rpush\", frames_key, frame_packers[index](new_frame))\n"
|
984
|
+
" if cancel then\n"
|
985
|
+
" for i = 1, #frame, 1 do\n"
|
986
|
+
" if type(frame[i]) == \"table\" then\n"
|
987
|
+
" redis.call(\"hsetnx\", events_hashset, frame[i][\"id\"], cmsgpack.pack(frame[i]))\n"
|
988
|
+
" redis.call(\"zadd\", timers_key, max_score, \"p:\" .. cjson.encode(frame[i]))\n"
|
1238
989
|
" end\n"
|
1239
990
|
" end\n"
|
991
|
+
" full_frame = nil\n"
|
1240
992
|
" end\n"
|
1241
|
-
" return
|
993
|
+
" return full_frame\n"
|
1242
994
|
"end\n"
|
1243
|
-
"local
|
1244
|
-
" local
|
1245
|
-
" local
|
1246
|
-
" local
|
1247
|
-
" local
|
1248
|
-
"
|
1249
|
-
"
|
1250
|
-
"
|
1251
|
-
" messages_key = facts_hashset\n"
|
1252
|
-
" message_cache = facts_message_cache\n"
|
1253
|
-
" mids_cache = facts_mids_cache\n"
|
995
|
+
"local load_frame_from_rule = function(rule_action_key, raw_count, sid, max_score)\n"
|
996
|
+
" local frames = {}\n"
|
997
|
+
" local packed_frames = {}\n"
|
998
|
+
" local unwrap = true\n"
|
999
|
+
" local count = 1\n"
|
1000
|
+
" if raw_count ~= \"single\" then\n"
|
1001
|
+
" count = tonumber(raw_count)\n"
|
1002
|
+
" unwrap = false\n"
|
1254
1003
|
" end\n"
|
1255
|
-
" if
|
1256
|
-
" local
|
1257
|
-
"
|
1258
|
-
"
|
1259
|
-
"
|
1260
|
-
"
|
1261
|
-
"
|
1262
|
-
" local message = get_message(new_mids[i], messages_key, message_cache)\n"
|
1263
|
-
" if not message then\n"
|
1264
|
-
" cleanup = true\n"
|
1265
|
-
" elseif not reviewers[index](message, new_frame, index) then\n"
|
1266
|
-
" local frames_key = keys[index] .. \"!i!\" .. sid .. \"!\" .. new_mids[i]\n"
|
1267
|
-
" redis.call(\"rpush\", frames_key, frame_packers[index - 1](new_frame))\n"
|
1268
|
-
" result = 0\n"
|
1269
|
-
" break\n"
|
1004
|
+
" if count == 0 then\n"
|
1005
|
+
" local packed_frame = redis.call(\"lpop\", rule_action_key)\n"
|
1006
|
+
" while packed_frame ~= \"0\" do\n"
|
1007
|
+
" local frame = review_frame(cmsgpack.unpack(packed_frame), rule_action_key, sid, max_score)\n"
|
1008
|
+
" if frame then\n"
|
1009
|
+
" table.insert(frames, frame)\n"
|
1010
|
+
" table.insert(packed_frames, packed_frame)\n"
|
1270
1011
|
" end\n"
|
1012
|
+
" packed_frame = redis.call(\"lpop\", rule_action_key)\n"
|
1013
|
+
" end\n"
|
1014
|
+
" if #packed_frames > 0 then\n"
|
1015
|
+
" redis.call(\"lpush\", rule_action_key, 0)\n"
|
1271
1016
|
" end\n"
|
1272
1017
|
" else\n"
|
1273
|
-
"
|
1274
|
-
"
|
1275
|
-
"
|
1276
|
-
"
|
1277
|
-
" cleanup = true\n"
|
1018
|
+
" while count > 0 do\n"
|
1019
|
+
" local packed_frame = redis.call(\"rpop\", rule_action_key)\n"
|
1020
|
+
" if not packed_frame then\n"
|
1021
|
+
" break\n"
|
1278
1022
|
" else\n"
|
1279
|
-
" local
|
1280
|
-
" if
|
1281
|
-
"
|
1282
|
-
"
|
1283
|
-
"
|
1284
|
-
" if not is_pure_fact(frame, index) then\n"
|
1285
|
-
" break\n"
|
1023
|
+
" local frame = review_frame(cmsgpack.unpack(packed_frame), rule_action_key, sid, max_score)\n"
|
1024
|
+
" if frame then\n"
|
1025
|
+
" table.insert(frames, frame)\n"
|
1026
|
+
" table.insert(packed_frames, packed_frame)\n"
|
1027
|
+
" count = count - 1\n"
|
1286
1028
|
" end\n"
|
1287
1029
|
" end\n"
|
1288
1030
|
" end\n"
|
1289
1031
|
" end\n"
|
1290
|
-
"
|
1291
|
-
"
|
1032
|
+
" for i = #packed_frames, 1, -1 do\n"
|
1033
|
+
" redis.call(\"rpush\", rule_action_key, packed_frames[i])\n"
|
1292
1034
|
" end\n"
|
1293
|
-
"
|
1294
|
-
"
|
1295
|
-
"
|
1296
|
-
" local
|
1297
|
-
"
|
1298
|
-
"
|
1299
|
-
" return process_event_and_frame(nil, frame, index, use_facts)\n"
|
1300
|
-
" elseif not first_result then\n"
|
1301
|
-
" return second_result\n"
|
1302
|
-
" elseif not second_result then\n"
|
1303
|
-
" return first_result\n"
|
1035
|
+
" if #packed_frames == 0 then\n"
|
1036
|
+
" return nil, nil\n"
|
1037
|
+
" end\n"
|
1038
|
+
" local last_name = string.find(rule_action_key, \"!\") - 1\n"
|
1039
|
+
" if unwrap then\n"
|
1040
|
+
" return string.sub(rule_action_key, 1, last_name), frames[1]\n"
|
1304
1041
|
" else\n"
|
1305
|
-
" return
|
1042
|
+
" return string.sub(rule_action_key, 1, last_name), frames\n"
|
1306
1043
|
" end\n"
|
1307
1044
|
"end\n"
|
1308
|
-
"local
|
1309
|
-
" local
|
1310
|
-
" local
|
1311
|
-
" if
|
1312
|
-
"
|
1045
|
+
"local load_frame_from_sid = function(sid, max_score)\n"
|
1046
|
+
" local action_list = action_key .. \"!\" .. sid\n"
|
1047
|
+
" local rule_action_key = redis.call(\"lpop\", action_list)\n"
|
1048
|
+
" if not rule_action_key then\n"
|
1049
|
+
" return nil, nil\n"
|
1313
1050
|
" end\n"
|
1314
|
-
" redis.call(\"
|
1315
|
-
"
|
1316
|
-
"
|
1317
|
-
"
|
1318
|
-
"
|
1319
|
-
"
|
1320
|
-
" for i = 1, packed_frames_len, 1 do\n"
|
1321
|
-
" local packed_frame = redis.call(\"rpop\", frames_key)\n"
|
1322
|
-
" local frame = frame_unpackers[index - 1](packed_frame)\n"
|
1323
|
-
" if frame then\n"
|
1324
|
-
" result = result + process_frame(frame, index, use_facts)\n"
|
1325
|
-
" end\n"
|
1051
|
+
" local count = redis.call(\"lpop\", action_list)\n"
|
1052
|
+
" local name, frame = load_frame_from_rule(rule_action_key, count, sid, max_score)\n"
|
1053
|
+
" while not frame do\n"
|
1054
|
+
" rule_action_key = redis.call(\"lpop\", action_list)\n"
|
1055
|
+
" if not rule_action_key then\n"
|
1056
|
+
" return nil, nil\n"
|
1326
1057
|
" end\n"
|
1058
|
+
" count = redis.call(\"lpop\", action_list)\n"
|
1059
|
+
" name, frame = load_frame_from_rule(rule_action_key, count, sid, max_score)\n"
|
1327
1060
|
" end\n"
|
1328
|
-
"
|
1061
|
+
" redis.call(\"lpush\", action_list, count)\n"
|
1062
|
+
" redis.call(\"lpush\", action_list, rule_action_key)\n"
|
1063
|
+
" return name, frame\n"
|
1329
1064
|
"end\n"
|
1330
|
-
"local
|
1331
|
-
" local
|
1332
|
-
"
|
1333
|
-
"
|
1334
|
-
" messages_key = facts_hashset\n"
|
1065
|
+
"local load_frame = function(max_score)\n"
|
1066
|
+
" local current_action = redis.call(\"zrange\", action_key, 0, 0, \"withscores\")\n"
|
1067
|
+
" if (#current_action == 0) or (tonumber(current_action[2]) > (max_score + 5)) then\n"
|
1068
|
+
" return nil, nil, nil\n"
|
1335
1069
|
" end\n"
|
1336
|
-
"
|
1337
|
-
"
|
1338
|
-
"
|
1339
|
-
"
|
1340
|
-
"
|
1341
|
-
" if
|
1342
|
-
"
|
1343
|
-
" else\n"
|
1344
|
-
" frames_key = keys[index] .. \"!c!\" .. sid\n"
|
1345
|
-
" end\n"
|
1346
|
-
" local packed_frames_len = redis.call(\"llen\", frames_key)\n"
|
1347
|
-
" for i = 1, packed_frames_len, 1 do\n"
|
1348
|
-
" local packed_frame = redis.call(\"rpop\", frames_key)\n"
|
1349
|
-
" local frame = frame_unpackers[index - 1](packed_frame)\n"
|
1350
|
-
" if frame then\n"
|
1351
|
-
" local count = process_event_and_frame(message, frame, index, use_facts)\n"
|
1352
|
-
" result = result + count\n"
|
1353
|
-
" if count == 0 or use_facts then\n"
|
1354
|
-
" redis.call(\"lpush\", frames_key, packed_frame)\n"
|
1355
|
-
" else\n"
|
1356
|
-
" break\n"
|
1357
|
-
" end\n"
|
1358
|
-
" end\n"
|
1070
|
+
" local sid = current_action[1]\n"
|
1071
|
+
" local name, frame = load_frame_from_sid(sid, max_score)\n"
|
1072
|
+
" while not frame do\n"
|
1073
|
+
" redis.call(\"zremrangebyrank\", action_key, 0, 0)\n"
|
1074
|
+
" current_action = redis.call(\"zrange\", action_key, 0, 0, \"withscores\")\n"
|
1075
|
+
" if #current_action == 0 or (tonumber(current_action[2]) > (max_score + 5)) then\n"
|
1076
|
+
" return nil, nil, nil\n"
|
1359
1077
|
" end\n"
|
1078
|
+
" sid = current_action[1]\n"
|
1079
|
+
" name, frame = load_frame_from_sid(sid, max_score)\n"
|
1360
1080
|
" end\n"
|
1361
|
-
"
|
1362
|
-
"
|
1081
|
+
" return sid, name, frame\n"
|
1082
|
+
"end\n"
|
1083
|
+
"get_context = function(action_key)\n"
|
1084
|
+
" if context_directory[action_key] then\n"
|
1085
|
+
" return context_directory[action_key]\n"
|
1363
1086
|
" end\n"
|
1364
|
-
"
|
1087
|
+
" local input_keys = {[action_key] = true}\n%s"
|
1365
1088
|
"end\n"
|
1366
|
-
"local
|
1367
|
-
"
|
1368
|
-
"
|
1369
|
-
"
|
1370
|
-
"
|
1371
|
-
"
|
1372
|
-
" redis.call(\"set\", results_key .. \"!d\", score)\n"
|
1373
|
-
" else\n"
|
1374
|
-
" local new_score = last_score + span\n"
|
1375
|
-
" if score > new_score then\n"
|
1376
|
-
" redis.call(\"rpush\", results_key, 0)\n"
|
1377
|
-
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, results_key)\n"
|
1378
|
-
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, 0)\n"
|
1379
|
-
" local span_count, span_remain = math.modf((score - new_score) / span)\n"
|
1380
|
-
" last_score = new_score + span_count * span\n"
|
1381
|
-
" redis.call(\"set\", results_key .. \"!d\", last_score)\n"
|
1382
|
-
" queue_lock = true\n"
|
1383
|
-
" end\n"
|
1384
|
-
" end\n"
|
1385
|
-
" local count = 0\n"
|
1386
|
-
" if not message then\n"
|
1387
|
-
" if assert_fact == 0 then\n"
|
1388
|
-
" count = process_inverse_event(message, index, keys[index] .. \"!e!\" .. sid, false)\n"
|
1389
|
-
" else\n"
|
1390
|
-
" count = process_inverse_event(message, index, keys[index] .. \"!f!\" .. sid, true)\n"
|
1391
|
-
" end\n"
|
1392
|
-
" else\n"
|
1393
|
-
" if assert_fact == 0 then\n"
|
1394
|
-
" count = process_event(message, index, keys[index] .. \"!e!\" .. sid, false)\n"
|
1395
|
-
" else\n"
|
1396
|
-
" count = process_event(message, index, keys[index] .. \"!f!\" .. sid, true)\n"
|
1397
|
-
" end\n"
|
1398
|
-
" end\n"
|
1399
|
-
" if (count > 0) then\n"
|
1400
|
-
" for i = 1, #results, 1 do\n"
|
1401
|
-
" redis.call(\"rpush\", results_key, results[i])\n"
|
1402
|
-
" end\n"
|
1403
|
-
" end\n"
|
1404
|
-
" end\n"
|
1405
|
-
" return queue_lock\n"
|
1089
|
+
"local new_sid, action_name, frame\n"
|
1090
|
+
"if #ARGV == 3 then\n"
|
1091
|
+
" new_sid = ARGV[3]\n"
|
1092
|
+
" action_name, frame = load_frame_from_sid(new_sid, tonumber(ARGV[2]))\n"
|
1093
|
+
"else\n"
|
1094
|
+
" new_sid, action_name, frame = load_frame(tonumber(ARGV[2]))\n"
|
1406
1095
|
"end\n"
|
1407
|
-
"
|
1408
|
-
"
|
1409
|
-
"
|
1410
|
-
"
|
1411
|
-
"
|
1412
|
-
"
|
1413
|
-
"
|
1414
|
-
" count = process_inverse_event(message, index, keys[index] .. \"!e!\" .. sid, false)\n"
|
1415
|
-
" else\n"
|
1416
|
-
" count = process_inverse_event(message, index, keys[index] .. \"!f!\" .. sid, true)\n"
|
1417
|
-
" end\n"
|
1418
|
-
" else\n"
|
1419
|
-
" if assert_fact == 0 then\n"
|
1420
|
-
" count = process_event(message, index, keys[index] .. \"!e!\" .. sid, false)\n"
|
1421
|
-
" else\n"
|
1422
|
-
" count = process_event(message, index, keys[index] .. \"!f!\" .. sid, true)\n"
|
1423
|
-
" end\n"
|
1424
|
-
" end\n"
|
1425
|
-
" if (count > 0) then\n"
|
1426
|
-
" for i = #results, 1, -1 do\n"
|
1427
|
-
" redis.call(\"lpush\", results_key, results[i])\n"
|
1428
|
-
" end\n"
|
1429
|
-
" local diff\n"
|
1430
|
-
" local new_count, new_remain = math.modf(#results / cap)\n"
|
1431
|
-
" local new_remain = #results %% cap\n"
|
1432
|
-
" if new_count > 0 then\n"
|
1433
|
-
" for i = 1, new_count, 1 do\n"
|
1434
|
-
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, results_key)\n"
|
1435
|
-
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, cap)\n"
|
1436
|
-
" end\n"
|
1437
|
-
" end\n"
|
1438
|
-
" if new_remain > 0 then\n"
|
1439
|
-
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, results_key)\n"
|
1440
|
-
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, new_remain)\n"
|
1441
|
-
" end\n"
|
1442
|
-
" if new_count > 0 or new_remain > 0 then\n"
|
1443
|
-
" queue_lock = true\n"
|
1444
|
-
" end\n"
|
1445
|
-
" end\n"
|
1096
|
+
"if frame then\n"
|
1097
|
+
" redis.call(\"zadd\", action_key, tonumber(ARGV[1]), new_sid)\n"
|
1098
|
+
" if #ARGV == 2 then\n"
|
1099
|
+
" local state = redis.call(\"hget\", state_key, new_sid)\n"
|
1100
|
+
" return {new_sid, state, cjson.encode({[action_name] = frame})}\n"
|
1101
|
+
" else\n"
|
1102
|
+
" return {new_sid, cjson.encode({[action_name] = frame})}\n"
|
1446
1103
|
" end\n"
|
1447
|
-
"
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1104
|
+
"end\n",
|
1105
|
+
name,
|
1106
|
+
name,
|
1107
|
+
name,
|
1108
|
+
name,
|
1109
|
+
name,
|
1110
|
+
peekActionLua) == -1) {
|
1111
|
+
return ERR_OUT_OF_MEMORY;
|
1112
|
+
}
|
1113
|
+
free(peekActionLua);
|
1114
|
+
redisAppendCommand(reContext, "SCRIPT LOAD %s", lua);
|
1115
|
+
redisGetReply(reContext, (void**)&reply);
|
1116
|
+
if (reply->type == REDIS_REPLY_ERROR) {
|
1117
|
+
printf("%s\n", reply->str);
|
1118
|
+
freeReplyObject(reply);
|
1119
|
+
free(lua);
|
1120
|
+
return ERR_REDIS_ERROR;
|
1121
|
+
}
|
1122
|
+
|
1123
|
+
strncpy(rulesBinding->peekActionHash, reply->str, 40);
|
1124
|
+
rulesBinding->peekActionHash[40] = '\0';
|
1125
|
+
freeReplyObject(reply);
|
1126
|
+
free(lua);
|
1127
|
+
return RULES_OK;
|
1128
|
+
}
|
1129
|
+
|
1130
|
+
static unsigned int loadEvalMessageCommand(ruleset *tree, binding *rulesBinding) {
|
1131
|
+
char *name = &tree->stringPool[tree->nameOffset];
|
1132
|
+
int nameLength = strlen(name);
|
1133
|
+
redisContext *reContext = rulesBinding->reContext;
|
1134
|
+
redisReply *reply;
|
1135
|
+
char *lua = NULL;
|
1136
|
+
char *oldLua;
|
1137
|
+
|
1138
|
+
#ifdef _WIN32
|
1139
|
+
char *actionKey = (char *)_alloca(sizeof(char)*(nameLength + 3));
|
1140
|
+
sprintf_s(actionKey, nameLength + 3, "%s!a", name);
|
1141
|
+
#else
|
1142
|
+
char actionKey[nameLength + 3];
|
1143
|
+
snprintf(actionKey, nameLength + 3, "%s!a", name);
|
1144
|
+
#endif
|
1145
|
+
|
1146
|
+
lua = (char*)calloc(1, sizeof(char));
|
1147
|
+
if (!lua) {
|
1148
|
+
return ERR_OUT_OF_MEMORY;
|
1149
|
+
}
|
1150
|
+
|
1151
|
+
for (unsigned int i = 0; i < tree->nodeOffset; ++i) {
|
1152
|
+
node *currentNode = &tree->nodePool[i];
|
1153
|
+
|
1154
|
+
if (currentNode->type == NODE_ACTION) {
|
1155
|
+
char *packFrameLua = NULL;
|
1156
|
+
char *unpackFrameLua = NULL;
|
1157
|
+
char *oldPackFrameLua = NULL;
|
1158
|
+
char *oldUnpackFrameLua = NULL;
|
1159
|
+
char *actionName = &tree->stringPool[currentNode->nameOffset];
|
1160
|
+
char *actionLastName = strchr(actionName, '!');
|
1161
|
+
#ifdef _WIN32
|
1162
|
+
char *actionAlias = (char *)_alloca(sizeof(char)*(actionLastName - actionName + 1));
|
1163
|
+
#else
|
1164
|
+
char actionAlias[actionLastName - actionName + 1];
|
1165
|
+
#endif
|
1166
|
+
|
1167
|
+
strncpy(actionAlias, actionName, actionLastName - actionName);
|
1168
|
+
actionAlias[actionLastName - actionName] = '\0';
|
1169
|
+
|
1170
|
+
for (unsigned int ii = 0; ii < currentNode->value.c.joinsLength; ++ii) {
|
1171
|
+
unsigned int currentJoinOffset = tree->nextPool[currentNode->value.c.joinsOffset + ii];
|
1172
|
+
join *currentJoin = &tree->joinPool[currentJoinOffset];
|
1173
|
+
oldLua = lua;
|
1174
|
+
if (asprintf(&lua,
|
1175
|
+
"%stoggle = false\n"
|
1176
|
+
"context = {}\n"
|
1177
|
+
"reviewers = {}\n"
|
1178
|
+
"context[\"reviewers\"] = reviewers\n"
|
1179
|
+
"frame_packers = {}\n"
|
1180
|
+
"context[\"frame_packers\"] = frame_packers\n"
|
1181
|
+
"frame_unpackers = {}\n"
|
1182
|
+
"context[\"frame_unpackers\"] = frame_unpackers\n"
|
1183
|
+
"primary_message_keys = {}\n"
|
1184
|
+
"context[\"primary_message_keys\"] = primary_message_keys\n"
|
1185
|
+
"primary_frame_keys = {}\n"
|
1186
|
+
"context[\"primary_frame_keys\"] = primary_frame_keys\n"
|
1187
|
+
"keys = {}\n"
|
1188
|
+
"context[\"keys\"] = keys\n"
|
1189
|
+
"inverse_directory = {}\n"
|
1190
|
+
"context[\"inverse_directory\"] = inverse_directory\n"
|
1191
|
+
"directory = {[\"0\"] = 1}\n"
|
1192
|
+
"context[\"directory\"] = directory\n"
|
1193
|
+
"context[\"results_key\"] = \"%s!%d!r!\" .. sid\n"
|
1194
|
+
"context[\"expressions_count\"] = %d\n",
|
1195
|
+
lua,
|
1196
|
+
actionName,
|
1197
|
+
ii,
|
1198
|
+
currentJoin->expressionsLength) == -1) {
|
1199
|
+
return ERR_OUT_OF_MEMORY;
|
1200
|
+
}
|
1201
|
+
free(oldLua);
|
1202
|
+
|
1203
|
+
for (unsigned int iii = 0; iii < currentJoin->expressionsLength; ++iii) {
|
1204
|
+
unsigned int expressionOffset = tree->nextPool[currentJoin->expressionsOffset + iii];
|
1205
|
+
expression *expr = &tree->expressionPool[expressionOffset];
|
1206
|
+
char *currentAlias = &tree->stringPool[expr->aliasOffset];
|
1207
|
+
char *currentKey = &tree->stringPool[expr->nameOffset];
|
1208
|
+
char *nextKeyTest;
|
1209
|
+
if (iii == (currentJoin->expressionsLength - 1)) {
|
1210
|
+
nextKeyTest = (char*)calloc(1, sizeof(char));
|
1211
|
+
if (!nextKeyTest) {
|
1212
|
+
return ERR_OUT_OF_MEMORY;
|
1213
|
+
}
|
1214
|
+
} else {
|
1215
|
+
unsigned int nextExpressionOffset = tree->nextPool[currentJoin->expressionsOffset + iii + 1];
|
1216
|
+
expression *nextExpr = &tree->expressionPool[nextExpressionOffset];
|
1217
|
+
if (asprintf(&nextKeyTest,
|
1218
|
+
"or input_keys[\"%s\"]",
|
1219
|
+
&tree->stringPool[nextExpr->nameOffset]) == -1) {
|
1220
|
+
return ERR_OUT_OF_MEMORY;
|
1221
|
+
}
|
1222
|
+
}
|
1223
|
+
|
1224
|
+
if (iii == 0) {
|
1225
|
+
if (expr->not) {
|
1226
|
+
if (asprintf(&packFrameLua,
|
1227
|
+
" result[1] = \"$n\"\n") == -1) {
|
1228
|
+
return ERR_OUT_OF_MEMORY;
|
1229
|
+
}
|
1230
|
+
|
1231
|
+
if (asprintf(&unpackFrameLua,
|
1232
|
+
" result[\"%s\"] = \"$n\"\n",
|
1233
|
+
currentAlias) == -1) {
|
1234
|
+
return ERR_OUT_OF_MEMORY;
|
1235
|
+
}
|
1236
|
+
|
1237
|
+
oldLua = lua;
|
1238
|
+
if (asprintf(&lua,
|
1239
|
+
"%sif input_keys[\"%s\"] %s then\n"
|
1240
|
+
" toggle = true\n"
|
1241
|
+
" context_directory[\"%s\"] = context\n"
|
1242
|
+
" keys[1] = \"%s\"\n"
|
1243
|
+
" inverse_directory[1] = true\n"
|
1244
|
+
" directory[\"%s\"] = 1\n"
|
1245
|
+
" reviewers[1] = function(message, frame, index)\n"
|
1454
1246
|
" if not message then\n"
|
1455
|
-
"
|
1456
|
-
"
|
1457
|
-
" else\n"
|
1458
|
-
" count = process_inverse_event(message, index, keys[index] .. \"!f!\" .. sid, true)\n"
|
1459
|
-
" end\n"
|
1460
|
-
" else\n"
|
1461
|
-
" if assert_fact == 0 then\n"
|
1462
|
-
" count = process_event(message, index, keys[index] .. \"!e!\" .. sid, false)\n"
|
1463
|
-
" else\n"
|
1464
|
-
" count = process_event(message, index, keys[index] .. \"!f!\" .. sid, true)\n"
|
1465
|
-
" end\n"
|
1247
|
+
" frame[\"%s\"] = \"$n\"\n"
|
1248
|
+
" return true\n"
|
1466
1249
|
" end\n"
|
1467
|
-
"
|
1468
|
-
"
|
1469
|
-
"
|
1470
|
-
"
|
1471
|
-
"
|
1472
|
-
"
|
1473
|
-
"
|
1474
|
-
"
|
1475
|
-
"
|
1476
|
-
"
|
1477
|
-
"
|
1478
|
-
"
|
1479
|
-
"
|
1480
|
-
"
|
1481
|
-
"
|
1482
|
-
"
|
1483
|
-
"
|
1484
|
-
"
|
1485
|
-
|
1486
|
-
|
1250
|
+
" return false\n"
|
1251
|
+
" end\n"
|
1252
|
+
" frame_packers[1] = function(frame, full_encode)\n"
|
1253
|
+
" local result = {}\n%s"
|
1254
|
+
" return cmsgpack.pack(result)\n"
|
1255
|
+
" end\n"
|
1256
|
+
" frame_unpackers[1] = function(packed_frame)\n"
|
1257
|
+
" local frame = cmsgpack.unpack(packed_frame)\n"
|
1258
|
+
" local result = {}\n%s"
|
1259
|
+
" return result\n"
|
1260
|
+
" end\n"
|
1261
|
+
" primary_message_keys[1] = function(message)\n"
|
1262
|
+
" return \"\"\n"
|
1263
|
+
" end\n"
|
1264
|
+
" primary_frame_keys[1] = function(frame)\n"
|
1265
|
+
" return \"\"\n"
|
1266
|
+
" end\n"
|
1267
|
+
"end\n",
|
1268
|
+
lua,
|
1269
|
+
currentKey,
|
1270
|
+
nextKeyTest,
|
1271
|
+
currentKey,
|
1272
|
+
currentKey,
|
1273
|
+
currentKey,
|
1274
|
+
currentAlias,
|
1275
|
+
packFrameLua,
|
1276
|
+
unpackFrameLua) == -1) {
|
1277
|
+
return ERR_OUT_OF_MEMORY;
|
1278
|
+
}
|
1279
|
+
free(oldLua);
|
1280
|
+
// not (expr->not)
|
1281
|
+
} else {
|
1282
|
+
if (asprintf(&packFrameLua,
|
1283
|
+
" message = frame[\"%s\"]\n"
|
1284
|
+
" if full_encode and not message[\"$f\"] then\n"
|
1285
|
+
" result[1] = message\n"
|
1286
|
+
" else\n"
|
1287
|
+
" result[1] = message[\"id\"]\n"
|
1288
|
+
" end\n",
|
1289
|
+
currentAlias) == -1) {
|
1290
|
+
return ERR_OUT_OF_MEMORY;
|
1291
|
+
}
|
1292
|
+
|
1293
|
+
if (asprintf(&unpackFrameLua,
|
1294
|
+
" message = fetch_message(frame[1])\n"
|
1295
|
+
" if not message then\n"
|
1296
|
+
" return nil\n"
|
1297
|
+
" end\n"
|
1298
|
+
" result[\"%s\"] = message\n",
|
1299
|
+
currentAlias) == -1) {
|
1300
|
+
return ERR_OUT_OF_MEMORY;
|
1301
|
+
}
|
1302
|
+
|
1303
|
+
oldLua = lua;
|
1304
|
+
if (asprintf(&lua,
|
1305
|
+
"%sif input_keys[\"%s\"] %s then\n"
|
1306
|
+
" toggle = true\n"
|
1307
|
+
" context_directory[\"%s\"] = context\n"
|
1308
|
+
" keys[1] = \"%s\"\n"
|
1309
|
+
" inverse_directory[1] = true\n"
|
1310
|
+
" directory[\"%s\"] = 1\n"
|
1311
|
+
" reviewers[1] = function(message, frame, index)\n"
|
1312
|
+
" if message then\n"
|
1313
|
+
" frame[\"%s\"] = message\n"
|
1314
|
+
" return true\n"
|
1487
1315
|
" end\n"
|
1316
|
+
" return false\n"
|
1488
1317
|
" end\n"
|
1489
|
-
"
|
1490
|
-
"
|
1491
|
-
"local message
|
1492
|
-
"
|
1493
|
-
" message = {}\n"
|
1494
|
-
" for index = 6 + keys_count, #ARGV, 3 do\n"
|
1495
|
-
" if ARGV[index + 2] == \"1\" then\n"
|
1496
|
-
" message[ARGV[index]] = ARGV[index + 1]\n"
|
1497
|
-
" elseif ARGV[index + 2] == \"2\" or ARGV[index + 2] == \"3\" then\n"
|
1498
|
-
" message[ARGV[index]] = tonumber(ARGV[index + 1])\n"
|
1499
|
-
" elseif ARGV[index + 2] == \"4\" then\n"
|
1500
|
-
" if ARGV[index + 1] == \"true\" then\n"
|
1501
|
-
" message[ARGV[index]] = true\n"
|
1502
|
-
" else\n"
|
1503
|
-
" message[ARGV[index]] = false\n"
|
1504
|
-
" end\n"
|
1505
|
-
" end\n"
|
1318
|
+
" frame_packers[1] = function(frame, full_encode)\n"
|
1319
|
+
" local result = {}\n"
|
1320
|
+
" local message\n%s"
|
1321
|
+
" return cmsgpack.pack(result)\n"
|
1506
1322
|
" end\n"
|
1507
|
-
"
|
1508
|
-
"
|
1323
|
+
" frame_unpackers[1] = function(packed_frame)\n"
|
1324
|
+
" local frame = cmsgpack.unpack(packed_frame)\n"
|
1325
|
+
" local result = {}\n"
|
1326
|
+
" local message\n%s"
|
1327
|
+
" return result\n"
|
1509
1328
|
" end\n"
|
1510
|
-
"
|
1511
|
-
"
|
1512
|
-
"
|
1513
|
-
"
|
1514
|
-
"
|
1329
|
+
" primary_message_keys[1] = function(message)\n"
|
1330
|
+
" return \"\"\n"
|
1331
|
+
" end\n"
|
1332
|
+
" primary_frame_keys[1] = function(frame)\n"
|
1333
|
+
" return \"\"\n"
|
1334
|
+
" end\n"
|
1335
|
+
"end\n",
|
1336
|
+
lua,
|
1337
|
+
currentKey,
|
1338
|
+
nextKeyTest,
|
1339
|
+
currentKey,
|
1340
|
+
currentKey,
|
1341
|
+
currentKey,
|
1342
|
+
currentAlias,
|
1343
|
+
packFrameLua,
|
1344
|
+
unpackFrameLua) == -1) {
|
1345
|
+
return ERR_OUT_OF_MEMORY;
|
1346
|
+
}
|
1347
|
+
free(oldLua);
|
1348
|
+
}
|
1349
|
+
// not (iii == 0)
|
1350
|
+
} else {
|
1351
|
+
char *test = NULL;
|
1352
|
+
char *primaryKeyLua = NULL;
|
1353
|
+
char *primaryFrameKeyLua = NULL;
|
1354
|
+
unsigned int result = createTest(tree, expr, &test, &primaryKeyLua, &primaryFrameKeyLua);
|
1355
|
+
if (result != RULES_OK) {
|
1356
|
+
return result;
|
1357
|
+
}
|
1358
|
+
|
1359
|
+
if (expr->not) {
|
1360
|
+
oldPackFrameLua = packFrameLua;
|
1361
|
+
if (asprintf(&packFrameLua,
|
1362
|
+
"%s result[%d] = \"$n\"\n",
|
1363
|
+
packFrameLua,
|
1364
|
+
iii + 1) == -1) {
|
1365
|
+
return ERR_OUT_OF_MEMORY;
|
1366
|
+
}
|
1367
|
+
free(oldPackFrameLua);
|
1368
|
+
|
1369
|
+
oldUnpackFrameLua = unpackFrameLua;
|
1370
|
+
if (asprintf(&unpackFrameLua,
|
1371
|
+
"%s result[\"%s\"] = \"$n\"\n",
|
1372
|
+
unpackFrameLua,
|
1373
|
+
currentAlias) == -1) {
|
1374
|
+
return ERR_OUT_OF_MEMORY;
|
1375
|
+
}
|
1376
|
+
free(oldUnpackFrameLua);
|
1377
|
+
|
1378
|
+
oldLua = lua;
|
1379
|
+
if (asprintf(&lua,
|
1380
|
+
"%sif toggle %s then\n"
|
1381
|
+
" toggle = true\n"
|
1382
|
+
" context_directory[\"%s\"] = context\n"
|
1383
|
+
" keys[%d] = \"%s\"\n"
|
1384
|
+
" inverse_directory[%d] = true\n"
|
1385
|
+
" directory[\"%s\"] = %d\n"
|
1386
|
+
" reviewers[%d] = function(message, frame, index)\n"
|
1387
|
+
" if not message or not (%s) then\n"
|
1388
|
+
" frame[\"%s\"] = \"$n\"\n"
|
1389
|
+
" return true\n"
|
1515
1390
|
" end\n"
|
1391
|
+
" return false\n"
|
1392
|
+
" end\n"
|
1393
|
+
" frame_packers[%d] = function(frame, full_encode)\n"
|
1394
|
+
" local result = {}\n"
|
1395
|
+
" local message\n%s"
|
1396
|
+
" return cmsgpack.pack(result)\n"
|
1397
|
+
" end\n"
|
1398
|
+
" frame_unpackers[%d] = function(packed_frame)\n"
|
1399
|
+
" local frame = cmsgpack.unpack(packed_frame)\n"
|
1400
|
+
" local result = {}\n"
|
1401
|
+
" local message\n%s"
|
1402
|
+
" return result\n"
|
1403
|
+
" end\n"
|
1404
|
+
" primary_message_keys[%d] = function(message)\n"
|
1405
|
+
" local result = \"\"\n%s"
|
1406
|
+
" return result\n"
|
1407
|
+
" end\n"
|
1408
|
+
" primary_frame_keys[%d] = function(frame)\n"
|
1409
|
+
" local result = \"\"\n%s"
|
1410
|
+
" return result\n"
|
1411
|
+
" end\n"
|
1412
|
+
"end\n",
|
1413
|
+
lua,
|
1414
|
+
nextKeyTest,
|
1415
|
+
currentKey,
|
1416
|
+
iii + 1,
|
1417
|
+
currentKey,
|
1418
|
+
iii + 1,
|
1419
|
+
currentKey,
|
1420
|
+
iii + 1,
|
1421
|
+
iii + 1,
|
1422
|
+
test,
|
1423
|
+
currentAlias,
|
1424
|
+
iii + 1,
|
1425
|
+
packFrameLua,
|
1426
|
+
iii + 1,
|
1427
|
+
unpackFrameLua,
|
1428
|
+
iii + 1,
|
1429
|
+
primaryKeyLua,
|
1430
|
+
iii + 1,
|
1431
|
+
primaryFrameKeyLua) == -1) {
|
1432
|
+
return ERR_OUT_OF_MEMORY;
|
1433
|
+
}
|
1434
|
+
free(oldLua);
|
1435
|
+
|
1436
|
+
// not (expr->not)
|
1437
|
+
} else {
|
1438
|
+
oldPackFrameLua = packFrameLua;
|
1439
|
+
if (asprintf(&packFrameLua,
|
1440
|
+
"%s message = frame[\"%s\"]\n"
|
1441
|
+
" if full_encode and not message[\"$f\"] then\n"
|
1442
|
+
" result[%d] = message\n"
|
1516
1443
|
" else\n"
|
1517
|
-
"
|
1518
|
-
"
|
1444
|
+
" result[%d] = message[\"id\"]\n"
|
1445
|
+
" end\n",
|
1446
|
+
packFrameLua,
|
1447
|
+
currentAlias,
|
1448
|
+
iii + 1,
|
1449
|
+
iii + 1) == -1) {
|
1450
|
+
return ERR_OUT_OF_MEMORY;
|
1451
|
+
}
|
1452
|
+
free(oldPackFrameLua);
|
1453
|
+
|
1454
|
+
oldUnpackFrameLua = unpackFrameLua;
|
1455
|
+
if (asprintf(&unpackFrameLua,
|
1456
|
+
"%s message = fetch_message(frame[%d])\n"
|
1457
|
+
" if not message then\n"
|
1458
|
+
" return nil\n"
|
1459
|
+
" end\n"
|
1460
|
+
" result[\"%s\"] = message\n",
|
1461
|
+
unpackFrameLua,
|
1462
|
+
iii + 1,
|
1463
|
+
currentAlias) == -1) {
|
1464
|
+
return ERR_OUT_OF_MEMORY;
|
1465
|
+
}
|
1466
|
+
free(oldUnpackFrameLua);
|
1467
|
+
|
1468
|
+
oldLua = lua;
|
1469
|
+
if (asprintf(&lua,
|
1470
|
+
"%sif toggle %s then\n"
|
1471
|
+
" toggle = true\n"
|
1472
|
+
" context_directory[\"%s\"] = context\n"
|
1473
|
+
" keys[%d] = \"%s\"\n"
|
1474
|
+
" directory[\"%s\"] = %d\n"
|
1475
|
+
" reviewers[%d] = function(message, frame, index)\n"
|
1476
|
+
" if message and %s then\n"
|
1477
|
+
" frame[\"%s\"] = message\n"
|
1478
|
+
" return true\n"
|
1519
1479
|
" end\n"
|
1480
|
+
" return false\n"
|
1520
1481
|
" end\n"
|
1521
|
-
"
|
1522
|
-
"
|
1523
|
-
"
|
1524
|
-
"
|
1525
|
-
"%sfor index = 6, 5 + keys_count, 1 do\n"
|
1526
|
-
" results = {}\n"
|
1527
|
-
" unpacked_results = {}\n"
|
1528
|
-
" key = ARGV[index]\n"
|
1529
|
-
" context = context_directory[key]\n"
|
1530
|
-
" keys = context[\"keys\"]\n"
|
1531
|
-
" reviewers = context[\"reviewers\"]\n"
|
1532
|
-
" frame_packers = context[\"frame_packers\"]\n"
|
1533
|
-
" frame_unpackers = context[\"frame_unpackers\"]\n"
|
1534
|
-
" primary_message_keys = context[\"primary_message_keys\"]\n"
|
1535
|
-
" primary_frame_keys = context[\"primary_frame_keys\"]\n"
|
1536
|
-
" directory = context[\"directory\"]\n"
|
1537
|
-
" results_key = context[\"results_key\"]\n"
|
1538
|
-
" inverse_directory = context[\"inverse_directory\"]\n"
|
1539
|
-
" expressions_count = context[\"expressions_count\"]\n"
|
1540
|
-
" local process_key = context[\"process_key\"]\n"
|
1541
|
-
" local process_key_count = context[\"process_key_count\"]\n"
|
1542
|
-
" queue_action = process_key(message, process_key_count)\n"
|
1543
|
-
" if assert_fact == 0 and events_message_cache[tostring(message[\"id\"])] == false then\n"
|
1544
|
-
" break\n"
|
1482
|
+
" frame_packers[%d] = function(frame, full_encode)\n"
|
1483
|
+
" local result = {}\n"
|
1484
|
+
" local message\n%s"
|
1485
|
+
" return cmsgpack.pack(result)\n"
|
1545
1486
|
" end\n"
|
1546
|
-
"
|
1547
|
-
"
|
1548
|
-
"
|
1549
|
-
"
|
1487
|
+
" frame_unpackers[%d] = function(packed_frame)\n"
|
1488
|
+
" local frame = cmsgpack.unpack(packed_frame)\n"
|
1489
|
+
" local result = {}\n"
|
1490
|
+
" local message\n%s"
|
1491
|
+
" return result\n"
|
1550
1492
|
" end\n"
|
1551
|
-
"
|
1552
|
-
"
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1493
|
+
" primary_message_keys[%d] = function(message)\n"
|
1494
|
+
" local result = \"\"\n%s"
|
1495
|
+
" return result\n"
|
1496
|
+
" end\n"
|
1497
|
+
" primary_frame_keys[%d] = function(frame)\n"
|
1498
|
+
" local result = \"\"\n%s"
|
1499
|
+
" return result\n"
|
1500
|
+
" end\n"
|
1501
|
+
"end\n",
|
1502
|
+
lua,
|
1503
|
+
nextKeyTest,
|
1504
|
+
currentKey,
|
1505
|
+
iii + 1,
|
1506
|
+
currentKey,
|
1507
|
+
currentKey,
|
1508
|
+
iii + 1,
|
1509
|
+
iii + 1,
|
1510
|
+
test,
|
1511
|
+
currentAlias,
|
1512
|
+
iii + 1,
|
1513
|
+
packFrameLua,
|
1514
|
+
iii + 1,
|
1515
|
+
unpackFrameLua,
|
1516
|
+
iii + 1,
|
1517
|
+
primaryKeyLua,
|
1518
|
+
iii + 1,
|
1519
|
+
primaryFrameKeyLua) == -1) {
|
1520
|
+
return ERR_OUT_OF_MEMORY;
|
1521
|
+
}
|
1522
|
+
free(oldLua);
|
1523
|
+
// done not (expr->not)
|
1524
|
+
}
|
1525
|
+
free(nextKeyTest);
|
1526
|
+
free(test);
|
1527
|
+
free(primaryKeyLua);
|
1528
|
+
free(primaryFrameKeyLua);
|
1529
|
+
// done not (iii == 0)
|
1530
|
+
}
|
1531
|
+
}
|
1561
1532
|
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1533
|
+
if (currentNode->value.c.span > 0) {
|
1534
|
+
oldLua = lua;
|
1535
|
+
if (asprintf(&lua,
|
1536
|
+
"%sif toggle then\n"
|
1537
|
+
" context[\"process_key\"] = process_key_with_span\n"
|
1538
|
+
" context[\"process_key_count\"] = %d\n"
|
1539
|
+
"end\n",
|
1540
|
+
lua,
|
1541
|
+
currentNode->value.c.span) == -1) {
|
1542
|
+
return ERR_OUT_OF_MEMORY;
|
1543
|
+
}
|
1544
|
+
free(oldLua);
|
1571
1545
|
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1546
|
+
} else if (currentNode->value.c.cap > 0) {
|
1547
|
+
oldLua = lua;
|
1548
|
+
if (asprintf(&lua,
|
1549
|
+
"%sif toggle then\n"
|
1550
|
+
" context[\"process_key\"] = process_key_with_cap\n"
|
1551
|
+
" context[\"process_key_count\"] = %d\n"
|
1552
|
+
"end\n",
|
1553
|
+
lua,
|
1554
|
+
currentNode->value.c.cap) == -1) {
|
1555
|
+
return ERR_OUT_OF_MEMORY;
|
1556
|
+
}
|
1557
|
+
free(oldLua);
|
1576
1558
|
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
"
|
1559
|
+
} else {
|
1560
|
+
oldLua = lua;
|
1561
|
+
if (asprintf(&lua,
|
1562
|
+
"%sif toggle then\n"
|
1563
|
+
" context[\"process_key\"] = process_key_with_window\n"
|
1564
|
+
" context[\"process_key_count\"] = %d\n"
|
1565
|
+
"end\n",
|
1566
|
+
lua,
|
1567
|
+
currentNode->value.c.count) == -1) {
|
1568
|
+
return ERR_OUT_OF_MEMORY;
|
1569
|
+
}
|
1570
|
+
free(oldLua);
|
1571
|
+
}
|
1572
|
+
}
|
1573
|
+
|
1574
|
+
free(unpackFrameLua);
|
1575
|
+
free(packFrameLua);
|
1576
|
+
}
|
1577
|
+
}
|
1578
|
+
|
1579
|
+
oldLua = lua;
|
1580
|
+
if (asprintf(&lua,
|
1581
|
+
"local sid = ARGV[1]\n"
|
1582
|
+
"local mid = ARGV[2]\n"
|
1583
|
+
"local score = tonumber(ARGV[3])\n"
|
1584
|
+
"local assert_fact = tonumber(ARGV[4])\n"
|
1585
|
+
"local keys_count = tonumber(ARGV[5])\n"
|
1586
|
+
"local events_hashset = \"%s!e!\" .. sid\n"
|
1587
|
+
"local facts_hashset = \"%s!f!\" .. sid\n"
|
1588
|
+
"local visited_hashset = \"%s!v!\" .. sid\n"
|
1589
|
+
"local actions_key = \"%s!a\"\n"
|
1581
1590
|
"local state_key = \"%s!s\"\n"
|
1582
|
-
"local
|
1591
|
+
"local queue_action = false\n"
|
1592
|
+
"local facts_message_cache = {}\n"
|
1593
|
+
"local events_message_cache = {}\n"
|
1594
|
+
"local facts_mids_cache = {}\n"
|
1595
|
+
"local events_mids_cache = {}\n"
|
1583
1596
|
"local context_directory = {}\n"
|
1597
|
+
"local input_keys = {}\n"
|
1598
|
+
"local toggle\n"
|
1599
|
+
"local expressions_count\n"
|
1600
|
+
"local results\n"
|
1601
|
+
"local unpacked_results\n"
|
1602
|
+
"local context\n"
|
1584
1603
|
"local keys\n"
|
1585
1604
|
"local reviewers\n"
|
1605
|
+
"local frame_packers\n"
|
1606
|
+
"local frame_unpackers\n"
|
1607
|
+
"local primary_message_keys\n"
|
1586
1608
|
"local primary_frame_keys\n"
|
1587
|
-
"local
|
1588
|
-
"local
|
1589
|
-
"local
|
1590
|
-
"local
|
1591
|
-
"local
|
1592
|
-
"local
|
1593
|
-
"local
|
1609
|
+
"local directory\n"
|
1610
|
+
"local results_key\n"
|
1611
|
+
"local inverse_directory\n"
|
1612
|
+
"local key\n"
|
1613
|
+
"local cleanup_mids = function(index, frame, events_key, messages_key, mids_cache, message_cache)\n"
|
1614
|
+
" local event_mids = mids_cache[events_key]\n"
|
1615
|
+
" local primary_key = primary_frame_keys[index](frame)\n"
|
1616
|
+
" local new_mids = event_mids[primary_key]\n"
|
1617
|
+
" local result_mids = {}\n"
|
1618
|
+
" for i = 1, #new_mids, 1 do\n"
|
1619
|
+
" local new_mid = new_mids[i]\n"
|
1620
|
+
" if message_cache[new_mid] ~= false then\n"
|
1621
|
+
" table.insert(result_mids, new_mid)\n"
|
1622
|
+
" end\n"
|
1623
|
+
" end\n"
|
1624
|
+
" event_mids[primary_key] = result_mids\n"
|
1625
|
+
" redis.call(\"del\", events_key .. \"!m!\" .. primary_key)\n"
|
1626
|
+
" for i = 1, #result_mids, 1 do\n"
|
1627
|
+
" redis.call(\"rpush\", events_key .. \"!m!\" .. primary_key, result_mids[i])\n"
|
1628
|
+
" end\n"
|
1629
|
+
"end\n"
|
1594
1630
|
"local get_mids = function(index, frame, events_key, messages_key, mids_cache, message_cache)\n"
|
1595
1631
|
" local event_mids = mids_cache[events_key]\n"
|
1596
1632
|
" local primary_key = primary_frame_keys[index](frame)\n"
|
@@ -1622,258 +1658,381 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
|
|
1622
1658
|
" return message\n"
|
1623
1659
|
"end\n"
|
1624
1660
|
"local fetch_message = function(new_mid)\n"
|
1625
|
-
"
|
1626
|
-
"
|
1661
|
+
" local message = get_message(new_mid, events_hashset, events_message_cache)\n"
|
1662
|
+
" if not message then\n"
|
1663
|
+
" message = get_message(new_mid, facts_hashset, facts_message_cache)\n"
|
1627
1664
|
" end\n"
|
1628
|
-
" return
|
1665
|
+
" return message\n"
|
1629
1666
|
"end\n"
|
1630
|
-
"local
|
1631
|
-
"
|
1632
|
-
"
|
1633
|
-
"
|
1634
|
-
"
|
1635
|
-
"
|
1636
|
-
"
|
1637
|
-
"
|
1667
|
+
"local save_message = function(index, message, events_key, messages_key)\n"
|
1668
|
+
" redis.call(\"hsetnx\", messages_key, message[\"id\"], cmsgpack.pack(message))\n"
|
1669
|
+
" local primary_key = primary_message_keys[index](message)\n"
|
1670
|
+
" redis.call(\"lpush\", events_key .. \"!m!\" .. primary_key, message[\"id\"])\n"
|
1671
|
+
"end\n"
|
1672
|
+
"local save_result = function(frame, index)\n"
|
1673
|
+
" table.insert(results, 1, frame_packers[index](frame, true))\n"
|
1674
|
+
" table.insert(unpacked_results, 1, frame)\n"
|
1675
|
+
" for name, message in pairs(frame) do\n"
|
1676
|
+
" if message ~= \"$n\" and not message[\"$f\"] then\n"
|
1677
|
+
" redis.call(\"hdel\", events_hashset, message[\"id\"])\n"
|
1678
|
+
// message cache always looked up using strings
|
1679
|
+
" events_message_cache[tostring(message[\"id\"])] = false\n"
|
1638
1680
|
" end\n"
|
1639
1681
|
" end\n"
|
1640
|
-
" return true\n"
|
1641
1682
|
"end\n"
|
1642
|
-
"local
|
1643
|
-
" local
|
1644
|
-
"
|
1645
|
-
"
|
1646
|
-
"
|
1647
|
-
"local review_frame = function(frame, rule_action_key, sid, max_score)\n"
|
1648
|
-
" local indexes = {}\n"
|
1649
|
-
" local action_id = string.sub(rule_action_key, 1, (string.len(sid) + 1) * -1)\n"
|
1650
|
-
" local context = get_context(action_id)\n"
|
1651
|
-
" local full_frame = {}\n"
|
1652
|
-
" local cancel = false\n"
|
1653
|
-
" events_hashset = events_key .. sid\n"
|
1654
|
-
" facts_hashset = facts_key .. sid\n"
|
1655
|
-
" keys = context[\"keys\"]\n"
|
1656
|
-
" reviewers = context[\"reviewers\"]\n"
|
1657
|
-
" primary_frame_keys = context[\"primary_frame_keys\"]\n"
|
1658
|
-
" if not context[\"frame_restore\"](frame, full_frame) then\n"
|
1659
|
-
" cancel = true\n"
|
1660
|
-
" else\n"
|
1661
|
-
" for i = 1, #frame, 1 do\n"
|
1662
|
-
" if frame[i] == \"$n\" then\n"
|
1663
|
-
" if not validate_frame(frame, full_frame, i, sid) then\n"
|
1664
|
-
" cancel = true\n"
|
1665
|
-
" break\n"
|
1666
|
-
" end\n"
|
1667
|
-
" end\n"
|
1683
|
+
"local is_pure_fact = function(frame, index)\n"
|
1684
|
+
" local message_count = 0\n"
|
1685
|
+
" for name, message in pairs(frame) do\n"
|
1686
|
+
" if message ~= 1 and message[\"$f\"] ~= 1 then\n"
|
1687
|
+
" return false\n"
|
1668
1688
|
" end\n"
|
1689
|
+
" message_count = message_count + 1\n"
|
1690
|
+
" end\n"
|
1691
|
+
" return (message_count == index - 1)\n"
|
1692
|
+
"end\n"
|
1693
|
+
"local process_frame\n"
|
1694
|
+
"local process_event_and_frame = function(message, frame, index, use_facts)\n"
|
1695
|
+
" local result = 0\n"
|
1696
|
+
" local new_frame = {}\n"
|
1697
|
+
" for name, new_message in pairs(frame) do\n"
|
1698
|
+
" new_frame[name] = new_message\n"
|
1669
1699
|
" end\n"
|
1670
|
-
" if
|
1671
|
-
"
|
1672
|
-
"
|
1673
|
-
"
|
1674
|
-
"
|
1700
|
+
" if reviewers[index](message, new_frame, index) then\n"
|
1701
|
+
" if (index == expressions_count) then\n"
|
1702
|
+
" save_result(new_frame, index)\n"
|
1703
|
+
" return 1\n"
|
1704
|
+
" else\n"
|
1705
|
+
" result = process_frame(new_frame, index + 1, use_facts)\n"
|
1706
|
+
" if result == 0 or use_facts then\n"
|
1707
|
+
" local frames_key\n"
|
1708
|
+
" local primary_key = primary_frame_keys[index + 1](new_frame)\n"
|
1709
|
+
" frames_key = keys[index + 1] .. \"!c!\" .. sid .. \"!\" .. primary_key\n"
|
1710
|
+
" redis.call(\"rpush\", frames_key, frame_packers[index](new_frame))\n"
|
1675
1711
|
" end\n"
|
1676
1712
|
" end\n"
|
1677
|
-
" full_frame = nil\n"
|
1678
1713
|
" end\n"
|
1679
|
-
" return
|
1714
|
+
" return result\n"
|
1680
1715
|
"end\n"
|
1681
|
-
"local
|
1682
|
-
" local
|
1683
|
-
" local
|
1684
|
-
" local
|
1685
|
-
" local
|
1686
|
-
"
|
1687
|
-
"
|
1688
|
-
"
|
1716
|
+
"local process_frame_for_key = function(frame, index, events_key, use_facts)\n"
|
1717
|
+
" local result = nil\n"
|
1718
|
+
" local inverse = inverse_directory[index]\n"
|
1719
|
+
" local messages_key = events_hashset\n"
|
1720
|
+
" local message_cache = events_message_cache\n"
|
1721
|
+
" local mids_cache = events_mids_cache\n"
|
1722
|
+
" local cleanup = false\n"
|
1723
|
+
" if use_facts then\n"
|
1724
|
+
" messages_key = facts_hashset\n"
|
1725
|
+
" message_cache = facts_message_cache\n"
|
1726
|
+
" mids_cache = facts_mids_cache\n"
|
1689
1727
|
" end\n"
|
1690
|
-
" if
|
1691
|
-
" local
|
1692
|
-
"
|
1693
|
-
"
|
1694
|
-
"
|
1695
|
-
"
|
1696
|
-
"
|
1728
|
+
" if inverse then\n"
|
1729
|
+
" local new_frame = {}\n"
|
1730
|
+
" for name, new_message in pairs(frame) do\n"
|
1731
|
+
" new_frame[name] = new_message\n"
|
1732
|
+
" end\n"
|
1733
|
+
" local new_mids = get_mids(index, frame, events_key, messages_key, mids_cache, message_cache)\n"
|
1734
|
+
" for i = 1, #new_mids, 1 do\n"
|
1735
|
+
" local message = get_message(new_mids[i], messages_key, message_cache)\n"
|
1736
|
+
" if not message then\n"
|
1737
|
+
" cleanup = true\n"
|
1738
|
+
" elseif not reviewers[index](message, new_frame, index) then\n"
|
1739
|
+
" local frames_key = keys[index] .. \"!i!\" .. sid .. \"!\" .. new_mids[i]\n"
|
1740
|
+
" redis.call(\"rpush\", frames_key, frame_packers[index - 1](new_frame))\n"
|
1741
|
+
" result = 0\n"
|
1742
|
+
" break\n"
|
1697
1743
|
" end\n"
|
1698
|
-
" packed_frame = redis.call(\"lpop\", rule_action_key)\n"
|
1699
|
-
" end\n"
|
1700
|
-
" if #packed_frames > 0 then\n"
|
1701
|
-
" redis.call(\"lpush\", rule_action_key, 0)\n"
|
1702
1744
|
" end\n"
|
1703
1745
|
" else\n"
|
1704
|
-
"
|
1705
|
-
"
|
1706
|
-
"
|
1707
|
-
"
|
1746
|
+
" local new_mids = get_mids(index, frame, events_key, messages_key, mids_cache, message_cache)\n"
|
1747
|
+
" for i = 1, #new_mids, 1 do\n"
|
1748
|
+
" local message = get_message(new_mids[i], messages_key, message_cache)\n"
|
1749
|
+
" if not message then\n"
|
1750
|
+
" cleanup = true\n"
|
1708
1751
|
" else\n"
|
1709
|
-
" local
|
1710
|
-
" if
|
1711
|
-
"
|
1712
|
-
"
|
1713
|
-
"
|
1752
|
+
" local count = process_event_and_frame(message, frame, index, use_facts)\n"
|
1753
|
+
" if not result then\n"
|
1754
|
+
" result = 0\n"
|
1755
|
+
" end\n"
|
1756
|
+
" result = result + count\n"
|
1757
|
+
" if not is_pure_fact(frame, index) then\n"
|
1758
|
+
" break\n"
|
1714
1759
|
" end\n"
|
1715
1760
|
" end\n"
|
1716
1761
|
" end\n"
|
1717
1762
|
" end\n"
|
1718
|
-
"
|
1719
|
-
"
|
1720
|
-
" end\n"
|
1721
|
-
" if #packed_frames == 0 then\n"
|
1722
|
-
" return nil, nil\n"
|
1763
|
+
" if cleanup then\n"
|
1764
|
+
" cleanup_mids(index, frame, events_key, messages_key, mids_cache, message_cache)\n"
|
1723
1765
|
" end\n"
|
1724
|
-
"
|
1725
|
-
"
|
1726
|
-
"
|
1766
|
+
" return result\n"
|
1767
|
+
"end\n"
|
1768
|
+
"process_frame = function(frame, index, use_facts)\n"
|
1769
|
+
" local first_result = process_frame_for_key(frame, index, keys[index] .. \"!e!\" .. sid, false)\n"
|
1770
|
+
" local second_result = process_frame_for_key(frame, index, keys[index] .. \"!f!\" .. sid, true)\n"
|
1771
|
+
" if not first_result and not second_result then\n"
|
1772
|
+
" return process_event_and_frame(nil, frame, index, use_facts)\n"
|
1773
|
+
" elseif not first_result then\n"
|
1774
|
+
" return second_result\n"
|
1775
|
+
" elseif not second_result then\n"
|
1776
|
+
" return first_result\n"
|
1727
1777
|
" else\n"
|
1728
|
-
" return
|
1778
|
+
" return first_result + second_result\n"
|
1729
1779
|
" end\n"
|
1730
1780
|
"end\n"
|
1731
|
-
"local
|
1732
|
-
" local
|
1733
|
-
" local
|
1734
|
-
" if
|
1735
|
-
"
|
1781
|
+
"local process_inverse_event = function(message, index, events_key, use_facts)\n"
|
1782
|
+
" local result = 0\n"
|
1783
|
+
" local messages_key = events_hashset\n"
|
1784
|
+
" if use_facts then\n"
|
1785
|
+
" messages_key = facts_hashset\n"
|
1736
1786
|
" end\n"
|
1737
|
-
"
|
1738
|
-
"
|
1739
|
-
"
|
1740
|
-
"
|
1741
|
-
"
|
1742
|
-
"
|
1787
|
+
" redis.call(\"hdel\", messages_key, mid)\n"
|
1788
|
+
" if index == 1 then\n"
|
1789
|
+
" result = process_frame({}, 1, use_facts)\n"
|
1790
|
+
" else\n"
|
1791
|
+
" local frames_key = keys[index] .. \"!i!\" .. sid .. \"!\" .. mid\n"
|
1792
|
+
" local packed_frames_len = redis.call(\"llen\", frames_key)\n"
|
1793
|
+
" for i = 1, packed_frames_len, 1 do\n"
|
1794
|
+
" local packed_frame = redis.call(\"rpop\", frames_key)\n"
|
1795
|
+
" local frame = frame_unpackers[index - 1](packed_frame)\n"
|
1796
|
+
" if frame then\n"
|
1797
|
+
" result = result + process_frame(frame, index, use_facts)\n"
|
1798
|
+
" end\n"
|
1743
1799
|
" end\n"
|
1744
|
-
" count = redis.call(\"lpop\", action_list)\n"
|
1745
|
-
" name, frame = load_frame_from_rule(rule_action_key, count, sid, max_score)\n"
|
1746
1800
|
" end\n"
|
1747
|
-
"
|
1748
|
-
" redis.call(\"lpush\", action_list, rule_action_key)\n"
|
1749
|
-
" return name, frame\n"
|
1801
|
+
" return result\n"
|
1750
1802
|
"end\n"
|
1751
|
-
"local
|
1752
|
-
" local
|
1753
|
-
"
|
1754
|
-
"
|
1803
|
+
"local process_event = function(message, index, events_key, use_facts)\n"
|
1804
|
+
" local result = 0\n"
|
1805
|
+
" local messages_key = events_hashset\n"
|
1806
|
+
" if use_facts then\n"
|
1807
|
+
" messages_key = facts_hashset\n"
|
1755
1808
|
" end\n"
|
1756
|
-
"
|
1757
|
-
"
|
1758
|
-
"
|
1759
|
-
"
|
1760
|
-
"
|
1761
|
-
" if
|
1762
|
-
"
|
1809
|
+
" if index == 1 then\n"
|
1810
|
+
" result = process_event_and_frame(message, {}, 1, use_facts)\n"
|
1811
|
+
" else\n"
|
1812
|
+
" local frames_key\n"
|
1813
|
+
" local primary_key = primary_message_keys[index](message)\n"
|
1814
|
+
" if primary_key then\n"
|
1815
|
+
" frames_key = keys[index] .. \"!c!\" .. sid .. \"!\" .. primary_key\n"
|
1816
|
+
" else\n"
|
1817
|
+
" frames_key = keys[index] .. \"!c!\" .. sid\n"
|
1818
|
+
" end\n"
|
1819
|
+
" local packed_frames_len = redis.call(\"llen\", frames_key)\n"
|
1820
|
+
" for i = 1, packed_frames_len, 1 do\n"
|
1821
|
+
" local packed_frame = redis.call(\"rpop\", frames_key)\n"
|
1822
|
+
" local frame = frame_unpackers[index - 1](packed_frame)\n"
|
1823
|
+
" if frame then\n"
|
1824
|
+
" local count = process_event_and_frame(message, frame, index, use_facts)\n"
|
1825
|
+
" result = result + count\n"
|
1826
|
+
" if count == 0 or use_facts then\n"
|
1827
|
+
" redis.call(\"lpush\", frames_key, packed_frame)\n"
|
1828
|
+
" else\n"
|
1829
|
+
" break\n"
|
1830
|
+
" end\n"
|
1831
|
+
" end\n"
|
1763
1832
|
" end\n"
|
1764
|
-
" sid = current_action[1]\n"
|
1765
|
-
" name, frame = load_frame_from_sid(sid, max_score)\n"
|
1766
1833
|
" end\n"
|
1767
|
-
"
|
1768
|
-
"
|
1769
|
-
"get_context = function(action_key)\n"
|
1770
|
-
" if context_directory[action_key] then\n"
|
1771
|
-
" return context_directory[action_key]\n"
|
1834
|
+
" if result == 0 or use_facts then\n"
|
1835
|
+
" save_message(index, message, events_key, messages_key)\n"
|
1772
1836
|
" end\n"
|
1773
|
-
"
|
1774
|
-
"end\n"
|
1775
|
-
"local new_sid, action_name, frame\n"
|
1776
|
-
"if #ARGV == 3 then\n"
|
1777
|
-
" new_sid = ARGV[3]\n"
|
1778
|
-
" action_name, frame = load_frame_from_sid(new_sid, tonumber(ARGV[2]))\n"
|
1779
|
-
"else\n"
|
1780
|
-
" new_sid, action_name, frame = load_frame(tonumber(ARGV[2]))\n"
|
1837
|
+
" return result\n"
|
1781
1838
|
"end\n"
|
1782
|
-
"
|
1783
|
-
"
|
1784
|
-
"
|
1785
|
-
"
|
1786
|
-
"
|
1787
|
-
"
|
1788
|
-
"
|
1839
|
+
"local process_key_with_span = function(message, span)\n"
|
1840
|
+
" local index = directory[key]\n"
|
1841
|
+
" local queue_lock = false\n"
|
1842
|
+
" if index then\n"
|
1843
|
+
" local last_score = redis.call(\"get\", results_key .. \"!d\")\n"
|
1844
|
+
" if not last_score then\n"
|
1845
|
+
" redis.call(\"set\", results_key .. \"!d\", score)\n"
|
1846
|
+
" else\n"
|
1847
|
+
" local new_score = last_score + span\n"
|
1848
|
+
" if score > new_score then\n"
|
1849
|
+
" redis.call(\"rpush\", results_key, 0)\n"
|
1850
|
+
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, results_key)\n"
|
1851
|
+
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, 0)\n"
|
1852
|
+
" local span_count, span_remain = math.modf((score - new_score) / span)\n"
|
1853
|
+
" last_score = new_score + span_count * span\n"
|
1854
|
+
" redis.call(\"set\", results_key .. \"!d\", last_score)\n"
|
1855
|
+
" queue_lock = true\n"
|
1856
|
+
" end\n"
|
1857
|
+
" end\n"
|
1858
|
+
" local count = 0\n"
|
1859
|
+
" if not message then\n"
|
1860
|
+
" if assert_fact == 0 then\n"
|
1861
|
+
" count = process_inverse_event(message, index, keys[index] .. \"!e!\" .. sid, false)\n"
|
1862
|
+
" else\n"
|
1863
|
+
" count = process_inverse_event(message, index, keys[index] .. \"!f!\" .. sid, true)\n"
|
1864
|
+
" end\n"
|
1865
|
+
" else\n"
|
1866
|
+
" if assert_fact == 0 then\n"
|
1867
|
+
" count = process_event(message, index, keys[index] .. \"!e!\" .. sid, false)\n"
|
1868
|
+
" else\n"
|
1869
|
+
" count = process_event(message, index, keys[index] .. \"!f!\" .. sid, true)\n"
|
1870
|
+
" end\n"
|
1871
|
+
" end\n"
|
1872
|
+
" if (count > 0) then\n"
|
1873
|
+
" for i = 1, #results, 1 do\n"
|
1874
|
+
" redis.call(\"rpush\", results_key, results[i])\n"
|
1875
|
+
" end\n"
|
1876
|
+
" end\n"
|
1789
1877
|
" end\n"
|
1790
|
-
"
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1806
|
-
|
1807
|
-
|
1808
|
-
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
"local
|
1816
|
-
"local
|
1817
|
-
"
|
1818
|
-
"
|
1819
|
-
"
|
1820
|
-
"
|
1821
|
-
"
|
1822
|
-
"
|
1823
|
-
"
|
1824
|
-
"
|
1825
|
-
"
|
1826
|
-
"
|
1827
|
-
"
|
1878
|
+
" return queue_lock\n"
|
1879
|
+
"end\n"
|
1880
|
+
"local process_key_with_cap = function(message, cap)\n"
|
1881
|
+
" local index = directory[key]\n"
|
1882
|
+
" local queue_lock = false\n"
|
1883
|
+
" if index then\n"
|
1884
|
+
" local count = 0\n"
|
1885
|
+
" if not message then\n"
|
1886
|
+
" if assert_fact == 0 then\n"
|
1887
|
+
" count = process_inverse_event(message, index, keys[index] .. \"!e!\" .. sid, false)\n"
|
1888
|
+
" else\n"
|
1889
|
+
" count = process_inverse_event(message, index, keys[index] .. \"!f!\" .. sid, true)\n"
|
1890
|
+
" end\n"
|
1891
|
+
" else\n"
|
1892
|
+
" if assert_fact == 0 then\n"
|
1893
|
+
" count = process_event(message, index, keys[index] .. \"!e!\" .. sid, false)\n"
|
1894
|
+
" else\n"
|
1895
|
+
" count = process_event(message, index, keys[index] .. \"!f!\" .. sid, true)\n"
|
1896
|
+
" end\n"
|
1897
|
+
" end\n"
|
1898
|
+
" if (count > 0) then\n"
|
1899
|
+
" for i = #results, 1, -1 do\n"
|
1900
|
+
" redis.call(\"lpush\", results_key, results[i])\n"
|
1901
|
+
" end\n"
|
1902
|
+
" local diff\n"
|
1903
|
+
" local new_count, new_remain = math.modf(#results / cap)\n"
|
1904
|
+
" local new_remain = #results %% cap\n"
|
1905
|
+
" if new_count > 0 then\n"
|
1906
|
+
" for i = 1, new_count, 1 do\n"
|
1907
|
+
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, results_key)\n"
|
1908
|
+
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, cap)\n"
|
1909
|
+
" end\n"
|
1910
|
+
" end\n"
|
1911
|
+
" if new_remain > 0 then\n"
|
1912
|
+
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, results_key)\n"
|
1913
|
+
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, new_remain)\n"
|
1914
|
+
" end\n"
|
1915
|
+
" if new_count > 0 or new_remain > 0 then\n"
|
1916
|
+
" queue_lock = true\n"
|
1917
|
+
" end\n"
|
1918
|
+
" end\n"
|
1919
|
+
" end\n"
|
1920
|
+
" return queue_lock\n"
|
1828
1921
|
"end\n"
|
1829
|
-
"
|
1830
|
-
"
|
1831
|
-
"
|
1832
|
-
"
|
1833
|
-
"
|
1834
|
-
"
|
1835
|
-
"
|
1836
|
-
"
|
1922
|
+
"local process_key_with_window = function(message, window)\n"
|
1923
|
+
" local index = directory[key]\n"
|
1924
|
+
" local queue_lock = false\n"
|
1925
|
+
" if index then\n"
|
1926
|
+
" local count = 0\n"
|
1927
|
+
" if not message then\n"
|
1928
|
+
" if assert_fact == 0 then\n"
|
1929
|
+
" count = process_inverse_event(message, index, keys[index] .. \"!e!\" .. sid, false)\n"
|
1930
|
+
" else\n"
|
1931
|
+
" count = process_inverse_event(message, index, keys[index] .. \"!f!\" .. sid, true)\n"
|
1932
|
+
" end\n"
|
1837
1933
|
" else\n"
|
1838
|
-
"
|
1934
|
+
" if assert_fact == 0 then\n"
|
1935
|
+
" count = process_event(message, index, keys[index] .. \"!e!\" .. sid, false)\n"
|
1936
|
+
" else\n"
|
1937
|
+
" count = process_event(message, index, keys[index] .. \"!f!\" .. sid, true)\n"
|
1938
|
+
" end\n"
|
1939
|
+
" end\n"
|
1940
|
+
" if (count > 0) then\n"
|
1941
|
+
" for i = #results, 1, -1 do\n"
|
1942
|
+
" redis.call(\"lpush\", results_key, results[i])\n"
|
1943
|
+
" end\n"
|
1944
|
+
" local diff\n"
|
1945
|
+
" local length = redis.call(\"llen\", results_key)\n"
|
1946
|
+
" local prev_count, prev_remain = math.modf((length - count) / window)\n"
|
1947
|
+
" local new_count, prev_remain = math.modf(length / window)\n"
|
1948
|
+
" diff = new_count - prev_count\n"
|
1949
|
+
" if diff > 0 then\n"
|
1950
|
+
" for i = 0, diff - 1, 1 do\n"
|
1951
|
+
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, results_key)\n"
|
1952
|
+
" if window == 1 then\n"
|
1953
|
+
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, \"single\")\n"
|
1954
|
+
" else\n"
|
1955
|
+
" redis.call(\"rpush\", actions_key .. \"!\" .. sid, window)\n"
|
1956
|
+
" end\n"
|
1957
|
+
" end\n"
|
1958
|
+
" queue_lock = true\n"
|
1959
|
+
" end\n"
|
1839
1960
|
" end\n"
|
1840
1961
|
" end\n"
|
1962
|
+
" return queue_lock\n"
|
1841
1963
|
"end\n"
|
1842
|
-
"local
|
1843
|
-
"if
|
1964
|
+
"local message = nil\n"
|
1965
|
+
"if #ARGV > (6 + keys_count) then\n"
|
1966
|
+
" message = {}\n"
|
1967
|
+
" for index = 6 + keys_count, #ARGV, 3 do\n"
|
1968
|
+
" if ARGV[index + 2] == \"1\" then\n"
|
1969
|
+
" message[ARGV[index]] = ARGV[index + 1]\n"
|
1970
|
+
" elseif ARGV[index + 2] == \"2\" or ARGV[index + 2] == \"3\" then\n"
|
1971
|
+
" message[ARGV[index]] = tonumber(ARGV[index + 1])\n"
|
1972
|
+
" elseif ARGV[index + 2] == \"4\" then\n"
|
1973
|
+
" if ARGV[index + 1] == \"true\" then\n"
|
1974
|
+
" message[ARGV[index]] = true\n"
|
1975
|
+
" else\n"
|
1976
|
+
" message[ARGV[index]] = false\n"
|
1977
|
+
" end\n"
|
1978
|
+
" end\n"
|
1979
|
+
" end\n"
|
1980
|
+
" if assert_fact == 1 then\n"
|
1981
|
+
" message[\"$f\"] = 1\n"
|
1982
|
+
" end\n"
|
1983
|
+
"end\n"
|
1984
|
+
"if redis.call(\"hsetnx\", visited_hashset, mid, 1) == 0 then\n"
|
1844
1985
|
" if assert_fact == 0 then\n"
|
1845
|
-
" if
|
1986
|
+
" if message and redis.call(\"hexists\", events_hashset, mid) == 0 then\n"
|
1846
1987
|
" return false\n"
|
1847
1988
|
" end\n"
|
1848
1989
|
" else\n"
|
1849
|
-
" if
|
1990
|
+
" if message and redis.call(\"hexists\", facts_hashset, mid) == 0 then\n"
|
1850
1991
|
" return false\n"
|
1851
1992
|
" end\n"
|
1852
1993
|
" end\n"
|
1853
1994
|
"end\n"
|
1854
|
-
"for index =
|
1995
|
+
"for index = 6, 5 + keys_count, 1 do\n"
|
1855
1996
|
" input_keys[ARGV[index]] = true\n"
|
1856
1997
|
"end\n"
|
1857
|
-
"%
|
1858
|
-
"
|
1859
|
-
"
|
1860
|
-
"
|
1861
|
-
"
|
1998
|
+
"%sfor index = 6, 5 + keys_count, 1 do\n"
|
1999
|
+
" results = {}\n"
|
2000
|
+
" unpacked_results = {}\n"
|
2001
|
+
" key = ARGV[index]\n"
|
2002
|
+
" context = context_directory[key]\n"
|
2003
|
+
" keys = context[\"keys\"]\n"
|
2004
|
+
" reviewers = context[\"reviewers\"]\n"
|
2005
|
+
" frame_packers = context[\"frame_packers\"]\n"
|
2006
|
+
" frame_unpackers = context[\"frame_unpackers\"]\n"
|
2007
|
+
" primary_message_keys = context[\"primary_message_keys\"]\n"
|
2008
|
+
" primary_frame_keys = context[\"primary_frame_keys\"]\n"
|
2009
|
+
" directory = context[\"directory\"]\n"
|
2010
|
+
" results_key = context[\"results_key\"]\n"
|
2011
|
+
" inverse_directory = context[\"inverse_directory\"]\n"
|
2012
|
+
" expressions_count = context[\"expressions_count\"]\n"
|
2013
|
+
" local process_key = context[\"process_key\"]\n"
|
2014
|
+
" local process_key_count = context[\"process_key_count\"]\n"
|
2015
|
+
" queue_action = process_key(message, process_key_count)\n"
|
2016
|
+
" if assert_fact == 0 and events_message_cache[tostring(message[\"id\"])] == false then\n"
|
2017
|
+
" break\n"
|
1862
2018
|
" end\n"
|
1863
|
-
"
|
1864
|
-
"
|
1865
|
-
"
|
1866
|
-
"
|
2019
|
+
"end\n"
|
2020
|
+
"if queue_action then\n"
|
2021
|
+
" if not redis.call(\"zscore\", actions_key, sid) then\n"
|
2022
|
+
" redis.call(\"zadd\", actions_key , score, sid)\n"
|
1867
2023
|
" end\n"
|
1868
|
-
"end\n"
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
2024
|
+
"end\n"
|
2025
|
+
"return nil\n",
|
2026
|
+
name,
|
2027
|
+
name,
|
2028
|
+
name,
|
2029
|
+
name,
|
2030
|
+
name,
|
2031
|
+
lua) == -1) {
|
1873
2032
|
return ERR_OUT_OF_MEMORY;
|
1874
2033
|
}
|
1875
2034
|
|
1876
|
-
free(
|
2035
|
+
free(oldLua);
|
1877
2036
|
redisAppendCommand(reContext, "SCRIPT LOAD %s", lua);
|
1878
2037
|
redisGetReply(reContext, (void**)&reply);
|
1879
2038
|
if (reply->type == REDIS_REPLY_ERROR) {
|
@@ -1883,10 +2042,112 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
|
|
1883
2042
|
return ERR_REDIS_ERROR;
|
1884
2043
|
}
|
1885
2044
|
|
1886
|
-
strncpy(rulesBinding->
|
1887
|
-
rulesBinding->
|
2045
|
+
strncpy(rulesBinding->evalMessageHash, reply->str, 40);
|
2046
|
+
rulesBinding->evalMessageHash[40] = '\0';
|
1888
2047
|
freeReplyObject(reply);
|
1889
2048
|
free(lua);
|
2049
|
+
return RULES_OK;
|
2050
|
+
}
|
2051
|
+
|
2052
|
+
static unsigned int setNames(ruleset *tree, binding *rulesBinding) {
|
2053
|
+
char *name = &tree->stringPool[tree->nameOffset];
|
2054
|
+
int nameLength = strlen(name);
|
2055
|
+
char *sessionHashset = malloc((nameLength + 3) * sizeof(char));
|
2056
|
+
if (!sessionHashset) {
|
2057
|
+
return ERR_OUT_OF_MEMORY;
|
2058
|
+
}
|
2059
|
+
|
2060
|
+
strncpy(sessionHashset, name, nameLength);
|
2061
|
+
sessionHashset[nameLength] = '!';
|
2062
|
+
sessionHashset[nameLength + 1] = 's';
|
2063
|
+
sessionHashset[nameLength + 2] = '\0';
|
2064
|
+
rulesBinding->sessionHashset = sessionHashset;
|
2065
|
+
|
2066
|
+
char *factsHashset = malloc((nameLength + 3) * sizeof(char));
|
2067
|
+
if (!factsHashset) {
|
2068
|
+
return ERR_OUT_OF_MEMORY;
|
2069
|
+
}
|
2070
|
+
|
2071
|
+
strncpy(factsHashset, name, nameLength);
|
2072
|
+
factsHashset[nameLength] = '!';
|
2073
|
+
factsHashset[nameLength + 1] = 'f';
|
2074
|
+
factsHashset[nameLength + 2] = '\0';
|
2075
|
+
rulesBinding->factsHashset = factsHashset;
|
2076
|
+
|
2077
|
+
char *eventsHashset = malloc((nameLength + 3) * sizeof(char));
|
2078
|
+
if (!eventsHashset) {
|
2079
|
+
return ERR_OUT_OF_MEMORY;
|
2080
|
+
}
|
2081
|
+
|
2082
|
+
strncpy(eventsHashset, name, nameLength);
|
2083
|
+
eventsHashset[nameLength] = '!';
|
2084
|
+
eventsHashset[nameLength + 1] = 'e';
|
2085
|
+
eventsHashset[nameLength + 2] = '\0';
|
2086
|
+
rulesBinding->eventsHashset = eventsHashset;
|
2087
|
+
|
2088
|
+
char *timersSortedset = malloc((nameLength + 3) * sizeof(char));
|
2089
|
+
if (!timersSortedset) {
|
2090
|
+
return ERR_OUT_OF_MEMORY;
|
2091
|
+
}
|
2092
|
+
|
2093
|
+
strncpy(timersSortedset, name, nameLength);
|
2094
|
+
timersSortedset[nameLength] = '!';
|
2095
|
+
timersSortedset[nameLength + 1] = 't';
|
2096
|
+
timersSortedset[nameLength + 2] = '\0';
|
2097
|
+
rulesBinding->timersSortedset = timersSortedset;
|
2098
|
+
return RULES_OK;
|
2099
|
+
}
|
2100
|
+
|
2101
|
+
static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
|
2102
|
+
unsigned int result = loadPartitionCommand(tree, rulesBinding);
|
2103
|
+
if (result != RULES_OK) {
|
2104
|
+
return result;
|
2105
|
+
}
|
2106
|
+
|
2107
|
+
// client queues have no commands to load,
|
2108
|
+
if (!tree->stringPool) {
|
2109
|
+
return RULES_OK;
|
2110
|
+
}
|
2111
|
+
|
2112
|
+
result = loadTimerCommand(tree, rulesBinding);
|
2113
|
+
if (result != RULES_OK) {
|
2114
|
+
return result;
|
2115
|
+
}
|
2116
|
+
|
2117
|
+
result = loadEvalMessageCommand(tree, rulesBinding);
|
2118
|
+
if (result != RULES_OK) {
|
2119
|
+
return result;
|
2120
|
+
}
|
2121
|
+
|
2122
|
+
result = loadAddMessageCommand(tree, rulesBinding);
|
2123
|
+
if (result != RULES_OK) {
|
2124
|
+
return result;
|
2125
|
+
}
|
2126
|
+
|
2127
|
+
result = loadPeekActionCommand(tree, rulesBinding);
|
2128
|
+
if (result != RULES_OK) {
|
2129
|
+
return result;
|
2130
|
+
}
|
2131
|
+
|
2132
|
+
result = loadUpdateActionCommand(tree, rulesBinding);
|
2133
|
+
if (result != RULES_OK) {
|
2134
|
+
return result;
|
2135
|
+
}
|
2136
|
+
|
2137
|
+
result = loadRemoveActionCommand(tree, rulesBinding);
|
2138
|
+
if (result != RULES_OK) {
|
2139
|
+
return result;
|
2140
|
+
}
|
2141
|
+
|
2142
|
+
result = loadDeleteSessionCommand(tree, rulesBinding);
|
2143
|
+
if (result != RULES_OK) {
|
2144
|
+
return result;
|
2145
|
+
}
|
2146
|
+
|
2147
|
+
result = setNames(tree, rulesBinding);
|
2148
|
+
if (result != RULES_OK) {
|
2149
|
+
return result;
|
2150
|
+
}
|
1890
2151
|
|
1891
2152
|
return RULES_OK;
|
1892
2153
|
}
|
@@ -2719,6 +2980,34 @@ unsigned int getSession(void *rulesBinding, char *sid, char **state) {
|
|
2719
2980
|
return REDIS_OK;
|
2720
2981
|
}
|
2721
2982
|
|
2983
|
+
unsigned int deleteSession(void *rulesBinding, char *sid) {
|
2984
|
+
binding *currentBinding = (binding*)rulesBinding;
|
2985
|
+
redisContext *reContext = currentBinding->reContext;
|
2986
|
+
|
2987
|
+
int result = redisAppendCommand(reContext,
|
2988
|
+
"evalsha %s 0 %s",
|
2989
|
+
currentBinding->deleteSessionHash,
|
2990
|
+
sid);
|
2991
|
+
if (result != REDIS_OK) {
|
2992
|
+
return ERR_REDIS_ERROR;
|
2993
|
+
}
|
2994
|
+
|
2995
|
+
redisReply *reply;
|
2996
|
+
result = tryGetReply(reContext, &reply);
|
2997
|
+
if (result != RULES_OK) {
|
2998
|
+
return result;
|
2999
|
+
}
|
3000
|
+
|
3001
|
+
if (reply->type == REDIS_REPLY_ERROR) {
|
3002
|
+
printf("deleteSession err string %s\n", reply->str);
|
3003
|
+
freeReplyObject(reply);
|
3004
|
+
return ERR_REDIS_ERROR;
|
3005
|
+
}
|
3006
|
+
|
3007
|
+
freeReplyObject(reply);
|
3008
|
+
return REDIS_OK;
|
3009
|
+
}
|
3010
|
+
|
2722
3011
|
unsigned int updateAction(void *rulesBinding, char *sid) {
|
2723
3012
|
binding *currentBinding = (binding*)rulesBinding;
|
2724
3013
|
redisContext *reContext = currentBinding->reContext;
|