durable_rules 0.34.10 → 0.34.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/librb/durable.rb +15 -7
- data/librb/engine.rb +5 -1
- data/src/rules/events.c +47 -22
- data/src/rules/net.c +160 -43
- data/src/rules/net.h +6 -1
- data/src/rules/rules.h +2 -1
- data/src/rules/state.c +11 -0
- data/src/rules/state.h +3 -0
- data/src/rulesrb/rules.c +4 -3
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a1c33ac9771e6fd5a65c237fa9ec44043ee2efa
|
4
|
+
data.tar.gz: 92da33c1378bccefc450cf31d0bbff11301fa2e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1557c00a12d9eff3c8d4d0b35c0e6efacf2928f2e1435eb873978e279af3a2f6f9f3b33d82bae98a2a10607469bf218ec942cc6a106f13cc5115d3c12ddb429
|
7
|
+
data.tar.gz: def1bedb13771e6f5546c5043933019cb36f1706293eb8afd79d97a05803dad5366765e085d87098aaa271a4d2e7b5834aeb261aed8bfad84f2b89f7b4893ec8
|
data/librb/durable.rb
CHANGED
@@ -178,7 +178,7 @@ module Durable
|
|
178
178
|
@__name = nil
|
179
179
|
end
|
180
180
|
|
181
|
-
def definition
|
181
|
+
def definition(parent_name=nil)
|
182
182
|
new_definition = nil
|
183
183
|
if @__op == :$or || @__op == :$and
|
184
184
|
new_definition = {@__op => @definitions}
|
@@ -297,25 +297,33 @@ module Durable
|
|
297
297
|
@expressions = expressions
|
298
298
|
end
|
299
299
|
|
300
|
-
def definition
|
300
|
+
def definition(parent_name=nil)
|
301
301
|
index = 0
|
302
302
|
new_definition = []
|
303
303
|
for expression in @expressions do
|
304
304
|
if (expression.kind_of? Expression) && expression.__name
|
305
305
|
expression_name = expression.__name
|
306
306
|
elsif @expressions.length == 1
|
307
|
-
|
307
|
+
if parent_name
|
308
|
+
expression_name = "#{parent_name}.m"
|
309
|
+
else
|
310
|
+
expression_name = "m"
|
311
|
+
end
|
308
312
|
else
|
309
|
-
|
313
|
+
if parent_name
|
314
|
+
expression_name = "#{parent_name}.m_#{index}"
|
315
|
+
else
|
316
|
+
expression_name = "m_#{index}"
|
317
|
+
end
|
310
318
|
end
|
311
319
|
if expression.__type == :$all
|
312
|
-
new_definition << {expression_name + "$all" => expression.definition()}
|
320
|
+
new_definition << {expression_name + "$all" => expression.definition(expression_name)}
|
313
321
|
elsif expression.__type == :$any
|
314
|
-
new_definition << {expression_name + "$any" => expression.definition()}
|
322
|
+
new_definition << {expression_name + "$any" => expression.definition(expression_name)}
|
315
323
|
elsif expression.__type == :$not
|
316
324
|
new_definition << {expression_name + "$not" => expression.definition()[0]["m"]}
|
317
325
|
else
|
318
|
-
new_definition << {expression_name => expression.definition()}
|
326
|
+
new_definition << {expression_name => expression.definition(expression_name)}
|
319
327
|
end
|
320
328
|
index += 1
|
321
329
|
end
|
data/librb/engine.rb
CHANGED
@@ -495,7 +495,11 @@ module Engine
|
|
495
495
|
end
|
496
496
|
|
497
497
|
def assert_state(state)
|
498
|
-
|
498
|
+
if state.key? :sid
|
499
|
+
Rules.assert_state @handle, state[:sid].to_s, JSON.generate(state)
|
500
|
+
else
|
501
|
+
Rules.assert_state @handle, state["sid"].to_s, JSON.generate(state)
|
502
|
+
end
|
499
503
|
end
|
500
504
|
|
501
505
|
def get_state(sid)
|
data/src/rules/events.c
CHANGED
@@ -33,6 +33,7 @@
|
|
33
33
|
#define OP_STRING_STRING 0x0101
|
34
34
|
|
35
35
|
typedef struct actionContext {
|
36
|
+
unsigned long stateVersion;
|
36
37
|
void *rulesBinding;
|
37
38
|
redisReply *reply;
|
38
39
|
} actionContext;
|
@@ -1029,6 +1030,7 @@ static unsigned int handleMessageCore(ruleset *tree,
|
|
1029
1030
|
jsonProperty *sidProperty;
|
1030
1031
|
int sidLength;
|
1031
1032
|
char *storeCommand;
|
1033
|
+
char *versionCommand;
|
1032
1034
|
int result = getId(properties, sidIndex, &sidProperty, &sidLength);
|
1033
1035
|
if (result != RULES_OK) {
|
1034
1036
|
return result;
|
@@ -1064,17 +1066,20 @@ static unsigned int handleMessageCore(ruleset *tree,
|
|
1064
1066
|
}
|
1065
1067
|
}
|
1066
1068
|
|
1067
|
-
|
1068
|
-
return ERR_MAX_COMMAND_COUNT;
|
1069
|
-
}
|
1070
|
-
|
1071
|
-
result = formatStoreSession(*rulesBinding, sid, state, 0, &storeCommand);
|
1069
|
+
result = formatStoreSession(*rulesBinding, sid, state, 0, &storeCommand, &versionCommand);
|
1072
1070
|
if (result != RULES_OK) {
|
1073
1071
|
return result;
|
1074
1072
|
}
|
1075
1073
|
|
1076
1074
|
commands[*commandCount] = storeCommand;
|
1077
1075
|
++*commandCount;
|
1076
|
+
|
1077
|
+
if (*commandCount == MAX_COMMAND_COUNT) {
|
1078
|
+
return ERR_MAX_COMMAND_COUNT;
|
1079
|
+
}
|
1080
|
+
|
1081
|
+
commands[*commandCount] = versionCommand;
|
1082
|
+
++*commandCount;
|
1078
1083
|
}
|
1079
1084
|
char *removeCommand = NULL;
|
1080
1085
|
char *addKeys[MAX_ADD_COUNT];
|
@@ -1220,7 +1225,7 @@ static unsigned int handleMessageCore(ruleset *tree,
|
|
1220
1225
|
return ERR_MAX_COMMAND_COUNT;
|
1221
1226
|
}
|
1222
1227
|
|
1223
|
-
result = formatStoreSession(*rulesBinding, sid, newState, 1, &storeCommand);
|
1228
|
+
result = formatStoreSession(*rulesBinding, sid, newState, 1, &storeCommand, &versionCommand);
|
1224
1229
|
if (result != RULES_OK) {
|
1225
1230
|
return result;
|
1226
1231
|
}
|
@@ -1228,6 +1233,13 @@ static unsigned int handleMessageCore(ruleset *tree,
|
|
1228
1233
|
commands[*commandCount] = storeCommand;
|
1229
1234
|
++*commandCount;
|
1230
1235
|
|
1236
|
+
if (*commandCount == MAX_COMMAND_COUNT) {
|
1237
|
+
return ERR_MAX_COMMAND_COUNT;
|
1238
|
+
}
|
1239
|
+
|
1240
|
+
commands[*commandCount] = versionCommand;
|
1241
|
+
++*commandCount;
|
1242
|
+
|
1231
1243
|
result = handleMessage(tree,
|
1232
1244
|
NULL,
|
1233
1245
|
stateMessage,
|
@@ -1362,7 +1374,8 @@ static unsigned int handleMessages(void *handle,
|
|
1362
1374
|
}
|
1363
1375
|
|
1364
1376
|
static unsigned int handleState(ruleset *tree,
|
1365
|
-
char *state,
|
1377
|
+
char *state,
|
1378
|
+
unsigned long stateVersion,
|
1366
1379
|
char **commands,
|
1367
1380
|
unsigned int *commandCount,
|
1368
1381
|
void **rulesBinding) {
|
@@ -1377,15 +1390,15 @@ static unsigned int handleState(ruleset *tree,
|
|
1377
1390
|
|
1378
1391
|
char *stateMessagePostfix = state + 1;
|
1379
1392
|
#ifdef _WIN32
|
1380
|
-
char *stateMessage = (char *)_alloca(sizeof(char)*(
|
1393
|
+
char *stateMessage = (char *)_alloca(sizeof(char)*(40 + stateLength - 1));
|
1381
1394
|
#else
|
1382
|
-
char stateMessage[
|
1395
|
+
char stateMessage[40 + stateLength - 1];
|
1383
1396
|
#endif
|
1384
|
-
|
1397
|
+
|
1385
1398
|
#ifdef _WIN32
|
1386
|
-
sprintf_s(stateMessage,
|
1399
|
+
sprintf_s(stateMessage, 40 + stateLength - 1, "{\"id\":\"$v-%016lu\", \"$s\":1, %s", stateVersion, stateMessagePostfix);
|
1387
1400
|
#else
|
1388
|
-
snprintf(stateMessage,
|
1401
|
+
snprintf(stateMessage, 40 + stateLength - 1, "{\"id\":\"$v-%016lu\", \"$s\":1, %s", stateVersion, stateMessagePostfix);
|
1389
1402
|
#endif
|
1390
1403
|
unsigned int result = handleMessage(tree,
|
1391
1404
|
state,
|
@@ -1638,15 +1651,22 @@ unsigned int startRetractFacts(void *handle,
|
|
1638
1651
|
return startHandleMessages(handle, messages, ACTION_REMOVE_FACT, rulesBinding, replyCount);
|
1639
1652
|
}
|
1640
1653
|
|
1641
|
-
unsigned int assertState(void *handle, char *state) {
|
1654
|
+
unsigned int assertState(void *handle, char *sid, char *state) {
|
1642
1655
|
char *commands[MAX_COMMAND_COUNT];
|
1643
1656
|
unsigned int commandCount = 0;
|
1644
1657
|
void *rulesBinding = NULL;
|
1645
|
-
unsigned
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1658
|
+
unsigned long stateVersion;
|
1659
|
+
unsigned int result = getStateVersion(handle, sid, &stateVersion);
|
1660
|
+
if (result != RULES_OK) {
|
1661
|
+
return result;
|
1662
|
+
}
|
1663
|
+
|
1664
|
+
result = handleState(handle,
|
1665
|
+
state,
|
1666
|
+
stateVersion,
|
1667
|
+
commands,
|
1668
|
+
&commandCount,
|
1669
|
+
&rulesBinding);
|
1650
1670
|
if (result != RULES_OK && result != ERR_EVENT_NOT_HANDLED) {
|
1651
1671
|
freeCommands(commands, commandCount);
|
1652
1672
|
return result;
|
@@ -1693,13 +1713,14 @@ unsigned int startAction(void *handle,
|
|
1693
1713
|
return result;
|
1694
1714
|
}
|
1695
1715
|
|
1696
|
-
*state = reply->element[
|
1697
|
-
*messages = reply->element[
|
1716
|
+
*state = reply->element[2]->str;
|
1717
|
+
*messages = reply->element[3]->str;
|
1698
1718
|
actionContext *context = malloc(sizeof(actionContext));
|
1699
1719
|
if (!context) {
|
1700
1720
|
return ERR_OUT_OF_MEMORY;
|
1701
1721
|
}
|
1702
1722
|
|
1723
|
+
context->stateVersion = reply->element[1]->integer;
|
1703
1724
|
context->reply = reply;
|
1704
1725
|
context->rulesBinding = rulesBinding;
|
1705
1726
|
*actionHandle = context;
|
@@ -1715,8 +1736,10 @@ unsigned int startUpdateState(void *handle,
|
|
1715
1736
|
char *commands[MAX_COMMAND_COUNT];
|
1716
1737
|
unsigned int result = RULES_OK;
|
1717
1738
|
unsigned int commandCount = 0;
|
1739
|
+
unsigned long stateVersion = ((actionContext*)actionHandle)->stateVersion;
|
1718
1740
|
result = handleState(handle,
|
1719
1741
|
state,
|
1742
|
+
stateVersion,
|
1720
1743
|
commands,
|
1721
1744
|
&commandCount,
|
1722
1745
|
rulesBinding);
|
@@ -1750,7 +1773,8 @@ unsigned int completeAction(void *handle,
|
|
1750
1773
|
|
1751
1774
|
++commandCount;
|
1752
1775
|
result = handleState(handle,
|
1753
|
-
state,
|
1776
|
+
state,
|
1777
|
+
context->stateVersion,
|
1754
1778
|
commands,
|
1755
1779
|
&commandCount,
|
1756
1780
|
&rulesBinding);
|
@@ -1823,7 +1847,8 @@ unsigned int completeAndStartAction(void *handle,
|
|
1823
1847
|
return ERR_NO_ACTION_AVAILABLE;
|
1824
1848
|
}
|
1825
1849
|
|
1826
|
-
*messages = newReply->element[
|
1850
|
+
*messages = newReply->element[2]->str;
|
1851
|
+
context->stateVersion = newReply->element[1]->integer;
|
1827
1852
|
context->reply = newReply;
|
1828
1853
|
return RULES_OK;
|
1829
1854
|
}
|
data/src/rules/net.c
CHANGED
@@ -528,11 +528,13 @@ static unsigned int loadDeleteSessionCommand(ruleset *tree, binding *rulesBindin
|
|
528
528
|
" end\n"
|
529
529
|
"end\n"
|
530
530
|
"redis.call(\"hdel\", \"%s!s\", sid)\n"
|
531
|
+
"redis.call(\"hdel\", \"%s!s!v\", sid)\n"
|
531
532
|
"redis.call(\"zrem\", \"%s!a\", sid)\n"
|
532
533
|
"redis.call(\"del\", \"%s!a!\" .. sid)\n"
|
533
534
|
"redis.call(\"del\", \"%s!e!\" .. sid)\n"
|
534
535
|
"redis.call(\"del\", \"%s!f!\" .. sid)\n"
|
535
536
|
"redis.call(\"del\", \"%s!v!\" .. sid)\n%s",
|
537
|
+
name,
|
536
538
|
name,
|
537
539
|
name,
|
538
540
|
name,
|
@@ -661,6 +663,10 @@ static unsigned int loadAddMessageCommand(ruleset *tree, binding *rulesBinding)
|
|
661
663
|
" else\n"
|
662
664
|
" message[ARGV[index]] = false\n"
|
663
665
|
" end\n"
|
666
|
+
" elseif ARGV[index + 2] == \"5\" then\n"
|
667
|
+
" message[ARGV[index]] = cjson.decode(ARGV[index + 1])\n"
|
668
|
+
" elseif ARGV[index + 2] == \"7\" then\n"
|
669
|
+
" message[ARGV[index]] = \"$null\"\n"
|
664
670
|
" end\n"
|
665
671
|
"end\n"
|
666
672
|
"local mid = message[\"id\"]\n"
|
@@ -763,8 +769,9 @@ static unsigned int loadPeekActionCommand(ruleset *tree, binding *rulesBinding)
|
|
763
769
|
for (unsigned int iii = 0; iii < currentJoin->expressionsLength; ++iii) {
|
764
770
|
unsigned int expressionOffset = tree->nextPool[currentJoin->expressionsOffset + iii];
|
765
771
|
expression *expr = &tree->expressionPool[expressionOffset];
|
766
|
-
char *currentAlias = &tree->stringPool[expr->aliasOffset];
|
767
772
|
char *currentKey = &tree->stringPool[expr->nameOffset];
|
773
|
+
char *currentAlias = &tree->stringPool[expr->aliasOffset];
|
774
|
+
|
768
775
|
|
769
776
|
if (iii == 0) {
|
770
777
|
if (expr->not) {
|
@@ -1083,13 +1090,23 @@ static unsigned int loadPeekActionCommand(ruleset *tree, binding *rulesBinding)
|
|
1083
1090
|
" return sid, name, frame\n"
|
1084
1091
|
"end\n"
|
1085
1092
|
"local fixup_frame = function(frame)\n"
|
1093
|
+
" local new_frame = {}\n"
|
1086
1094
|
" for message_name, message in pairs(frame) do\n"
|
1087
|
-
" if
|
1095
|
+
" if message_name == 1 then\n"
|
1096
|
+
" return frame\n"
|
1097
|
+
" end\n"
|
1098
|
+
" local start\n"
|
1099
|
+
" local name\n"
|
1100
|
+
" local next\n"
|
1101
|
+
" local new_message = {}\n"
|
1102
|
+
" if message == \"$n\" then\n"
|
1103
|
+
" new_message = message\n"
|
1104
|
+
" else\n"
|
1088
1105
|
" for key, value in pairs(message) do\n"
|
1089
|
-
" local
|
1090
|
-
"
|
1091
|
-
"
|
1092
|
-
"
|
1106
|
+
" local sub_message = new_message\n"
|
1107
|
+
" start = 1\n"
|
1108
|
+
" name = key\n"
|
1109
|
+
" next = nil\n"
|
1093
1110
|
" repeat\n"
|
1094
1111
|
" next = string.find(key, \"%%.\", start)\n"
|
1095
1112
|
" if next then\n"
|
@@ -1106,12 +1123,36 @@ static unsigned int loadPeekActionCommand(ruleset *tree, binding *rulesBinding)
|
|
1106
1123
|
" name = string.sub(key, start)\n"
|
1107
1124
|
" end\n"
|
1108
1125
|
" until not next\n"
|
1109
|
-
"
|
1110
|
-
"
|
1126
|
+
" if value == \"$null\" then\n"
|
1127
|
+
" sub_message[name] = cjson.null\n"
|
1128
|
+
" else\n"
|
1129
|
+
" sub_message[name] = value\n"
|
1130
|
+
" end\n"
|
1111
1131
|
" end\n"
|
1112
1132
|
" end\n"
|
1133
|
+
" local sub_frame = new_frame\n"
|
1134
|
+
" name = message_name\n"
|
1135
|
+
" next = nil\n"
|
1136
|
+
" start = 1\n"
|
1137
|
+
" repeat\n"
|
1138
|
+
" next = string.find(message_name, \"%%.\", start)\n"
|
1139
|
+
" if next then\n"
|
1140
|
+
" name = string.sub(message_name, start, next - 1)\n"
|
1141
|
+
" if sub_frame[name] then\n"
|
1142
|
+
" sub_frame = sub_frame[name]\n"
|
1143
|
+
" else\n"
|
1144
|
+
" local new_sub_frame = {}\n"
|
1145
|
+
" sub_frame[name] = new_sub_frame\n"
|
1146
|
+
" sub_frame = new_sub_frame\n"
|
1147
|
+
" end\n"
|
1148
|
+
" start = next + 1\n"
|
1149
|
+
" else\n"
|
1150
|
+
" name = string.sub(message_name, start)\n"
|
1151
|
+
" end\n"
|
1152
|
+
" until not next\n"
|
1153
|
+
" sub_frame[name] = new_message\n"
|
1113
1154
|
" end\n"
|
1114
|
-
" return
|
1155
|
+
" return new_frame\n"
|
1115
1156
|
"end\n"
|
1116
1157
|
"get_context = function(action_key)\n"
|
1117
1158
|
" if context_directory[action_key] then\n"
|
@@ -1128,11 +1169,12 @@ static unsigned int loadPeekActionCommand(ruleset *tree, binding *rulesBinding)
|
|
1128
1169
|
"end\n"
|
1129
1170
|
"if frame then\n"
|
1130
1171
|
" redis.call(\"zadd\", action_key, tonumber(ARGV[1]), new_sid)\n"
|
1172
|
+
" local state_version = redis.call(\"hget\", state_key .. \"!v\", new_sid)\n"
|
1131
1173
|
" if #ARGV == 2 then\n"
|
1132
1174
|
" local state = redis.call(\"hget\", state_key, new_sid)\n"
|
1133
|
-
" return {new_sid, state, cjson.encode({[action_name] = fixup_frame(frame)})}\n"
|
1175
|
+
" return {new_sid, tonumber(state_version), state, cjson.encode({[action_name] = fixup_frame(frame)})}\n"
|
1134
1176
|
" else\n"
|
1135
|
-
" return {new_sid, cjson.encode({[action_name] = fixup_frame(frame)})}\n"
|
1177
|
+
" return {new_sid, tonumber(state_version), cjson.encode({[action_name] = fixup_frame(frame)})}\n"
|
1136
1178
|
" end\n"
|
1137
1179
|
"end\n",
|
1138
1180
|
name,
|
@@ -1168,7 +1210,7 @@ static unsigned int loadEvalMessageCommand(ruleset *tree, binding *rulesBinding)
|
|
1168
1210
|
char *lua = NULL;
|
1169
1211
|
char *oldLua;
|
1170
1212
|
|
1171
|
-
|
1213
|
+
#ifdef _WIN32
|
1172
1214
|
char *actionKey = (char *)_alloca(sizeof(char)*(nameLength + 3));
|
1173
1215
|
sprintf_s(actionKey, nameLength + 3, "%s!a", name);
|
1174
1216
|
#else
|
@@ -1206,6 +1248,7 @@ static unsigned int loadEvalMessageCommand(ruleset *tree, binding *rulesBinding)
|
|
1206
1248
|
oldLua = lua;
|
1207
1249
|
if (asprintf(&lua,
|
1208
1250
|
"%stoggle = false\n"
|
1251
|
+
"context_directory = {}\n"
|
1209
1252
|
"context = {}\n"
|
1210
1253
|
"reviewers = {}\n"
|
1211
1254
|
"context[\"reviewers\"] = reviewers\n"
|
@@ -1236,9 +1279,10 @@ static unsigned int loadEvalMessageCommand(ruleset *tree, binding *rulesBinding)
|
|
1236
1279
|
for (unsigned int iii = 0; iii < currentJoin->expressionsLength; ++iii) {
|
1237
1280
|
unsigned int expressionOffset = tree->nextPool[currentJoin->expressionsOffset + iii];
|
1238
1281
|
expression *expr = &tree->expressionPool[expressionOffset];
|
1239
|
-
char *currentAlias = &tree->stringPool[expr->aliasOffset];
|
1240
1282
|
char *currentKey = &tree->stringPool[expr->nameOffset];
|
1283
|
+
char *currentAlias = &tree->stringPool[expr->aliasOffset];
|
1241
1284
|
char *nextKeyTest;
|
1285
|
+
|
1242
1286
|
if (iii == (currentJoin->expressionsLength - 1)) {
|
1243
1287
|
nextKeyTest = (char*)calloc(1, sizeof(char));
|
1244
1288
|
if (!nextKeyTest) {
|
@@ -1384,6 +1428,7 @@ static unsigned int loadEvalMessageCommand(ruleset *tree, binding *rulesBinding)
|
|
1384
1428
|
char *test = NULL;
|
1385
1429
|
char *primaryKeyLua = NULL;
|
1386
1430
|
char *primaryFrameKeyLua = NULL;
|
1431
|
+
|
1387
1432
|
unsigned int result = createTest(tree, expr, &test, &primaryKeyLua, &primaryFrameKeyLua);
|
1388
1433
|
if (result != RULES_OK) {
|
1389
1434
|
return result;
|
@@ -1569,6 +1614,9 @@ static unsigned int loadEvalMessageCommand(ruleset *tree, binding *rulesBinding)
|
|
1569
1614
|
"%sif toggle then\n"
|
1570
1615
|
" context[\"process_key\"] = process_key_with_span\n"
|
1571
1616
|
" context[\"process_key_count\"] = %d\n"
|
1617
|
+
" if not process_message(message) then\n"
|
1618
|
+
" return\n"
|
1619
|
+
" end\n"
|
1572
1620
|
"end\n",
|
1573
1621
|
lua,
|
1574
1622
|
currentNode->value.c.span) == -1) {
|
@@ -1582,6 +1630,9 @@ static unsigned int loadEvalMessageCommand(ruleset *tree, binding *rulesBinding)
|
|
1582
1630
|
"%sif toggle then\n"
|
1583
1631
|
" context[\"process_key\"] = process_key_with_cap\n"
|
1584
1632
|
" context[\"process_key_count\"] = %d\n"
|
1633
|
+
" if not process_message(message) then\n"
|
1634
|
+
" return\n"
|
1635
|
+
" end\n"
|
1585
1636
|
"end\n",
|
1586
1637
|
lua,
|
1587
1638
|
currentNode->value.c.cap) == -1) {
|
@@ -1595,6 +1646,9 @@ static unsigned int loadEvalMessageCommand(ruleset *tree, binding *rulesBinding)
|
|
1595
1646
|
"%sif toggle then\n"
|
1596
1647
|
" context[\"process_key\"] = process_key_with_window\n"
|
1597
1648
|
" context[\"process_key_count\"] = %d\n"
|
1649
|
+
" if not process_message(message) then\n"
|
1650
|
+
" return\n"
|
1651
|
+
" end\n"
|
1598
1652
|
"end\n",
|
1599
1653
|
lua,
|
1600
1654
|
currentNode->value.c.count) == -1) {
|
@@ -1998,6 +2052,41 @@ static unsigned int loadEvalMessageCommand(ruleset *tree, binding *rulesBinding)
|
|
1998
2052
|
" end\n"
|
1999
2053
|
" return queue_lock\n"
|
2000
2054
|
"end\n"
|
2055
|
+
"local process_message = function(message)\n"
|
2056
|
+
" for index = 6, 5 + keys_count, 1 do\n"
|
2057
|
+
" results = {}\n"
|
2058
|
+
" unpacked_results = {}\n"
|
2059
|
+
" key = ARGV[index]\n"
|
2060
|
+
" context = context_directory[key]\n"
|
2061
|
+
" if context then\n"
|
2062
|
+
" keys = context[\"keys\"]\n"
|
2063
|
+
" reviewers = context[\"reviewers\"]\n"
|
2064
|
+
" frame_packers = context[\"frame_packers\"]\n"
|
2065
|
+
" frame_unpackers = context[\"frame_unpackers\"]\n"
|
2066
|
+
" primary_message_keys = context[\"primary_message_keys\"]\n"
|
2067
|
+
" primary_frame_keys = context[\"primary_frame_keys\"]\n"
|
2068
|
+
" directory = context[\"directory\"]\n"
|
2069
|
+
" results_key = context[\"results_key\"]\n"
|
2070
|
+
" inverse_directory = context[\"inverse_directory\"]\n"
|
2071
|
+
" expressions_count = context[\"expressions_count\"]\n"
|
2072
|
+
" local process_key = context[\"process_key\"]\n"
|
2073
|
+
" local process_key_count = context[\"process_key_count\"]\n"
|
2074
|
+
" queue_action = process_key(message, process_key_count) or queue_action\n"
|
2075
|
+
" if assert_fact == 0 and events_message_cache[tostring(message[\"id\"])] == false then\n"
|
2076
|
+
" break\n"
|
2077
|
+
" end\n"
|
2078
|
+
" end\n"
|
2079
|
+
" end\n"
|
2080
|
+
" if queue_action then\n"
|
2081
|
+
" if not redis.call(\"zscore\", actions_key, sid) then\n"
|
2082
|
+
" redis.call(\"zadd\", actions_key , score, sid)\n"
|
2083
|
+
" end\n"
|
2084
|
+
" if assert_fact == 0 then\n"
|
2085
|
+
" return false\n"
|
2086
|
+
" end\n"
|
2087
|
+
" end\n"
|
2088
|
+
" return true\n"
|
2089
|
+
"end\n"
|
2001
2090
|
"local message = nil\n"
|
2002
2091
|
"if #ARGV > (6 + keys_count) then\n"
|
2003
2092
|
" message = {}\n"
|
@@ -2012,6 +2101,10 @@ static unsigned int loadEvalMessageCommand(ruleset *tree, binding *rulesBinding)
|
|
2012
2101
|
" else\n"
|
2013
2102
|
" message[ARGV[index]] = false\n"
|
2014
2103
|
" end\n"
|
2104
|
+
" elseif ARGV[index + 2] == \"5\" then\n"
|
2105
|
+
" message[ARGV[index]] = cjson.decode(ARGV[index + 1])\n"
|
2106
|
+
" elseif ARGV[index + 2] == \"7\" then\n"
|
2107
|
+
" message[ARGV[index]] = \"$null\"\n"
|
2015
2108
|
" end\n"
|
2016
2109
|
" end\n"
|
2017
2110
|
" if assert_fact == 1 then\n"
|
@@ -2032,33 +2125,7 @@ static unsigned int loadEvalMessageCommand(ruleset *tree, binding *rulesBinding)
|
|
2032
2125
|
"for index = 6, 5 + keys_count, 1 do\n"
|
2033
2126
|
" input_keys[ARGV[index]] = true\n"
|
2034
2127
|
"end\n"
|
2035
|
-
"%
|
2036
|
-
" results = {}\n"
|
2037
|
-
" unpacked_results = {}\n"
|
2038
|
-
" key = ARGV[index]\n"
|
2039
|
-
" context = context_directory[key]\n"
|
2040
|
-
" keys = context[\"keys\"]\n"
|
2041
|
-
" reviewers = context[\"reviewers\"]\n"
|
2042
|
-
" frame_packers = context[\"frame_packers\"]\n"
|
2043
|
-
" frame_unpackers = context[\"frame_unpackers\"]\n"
|
2044
|
-
" primary_message_keys = context[\"primary_message_keys\"]\n"
|
2045
|
-
" primary_frame_keys = context[\"primary_frame_keys\"]\n"
|
2046
|
-
" directory = context[\"directory\"]\n"
|
2047
|
-
" results_key = context[\"results_key\"]\n"
|
2048
|
-
" inverse_directory = context[\"inverse_directory\"]\n"
|
2049
|
-
" expressions_count = context[\"expressions_count\"]\n"
|
2050
|
-
" local process_key = context[\"process_key\"]\n"
|
2051
|
-
" local process_key_count = context[\"process_key_count\"]\n"
|
2052
|
-
" queue_action = process_key(message, process_key_count) or queue_action\n"
|
2053
|
-
" if assert_fact == 0 and events_message_cache[tostring(message[\"id\"])] == false then\n"
|
2054
|
-
" break\n"
|
2055
|
-
" end\n"
|
2056
|
-
"end\n"
|
2057
|
-
"if queue_action then\n"
|
2058
|
-
" if not redis.call(\"zscore\", actions_key, sid) then\n"
|
2059
|
-
" redis.call(\"zadd\", actions_key , score, sid)\n"
|
2060
|
-
" end\n"
|
2061
|
-
"end\n",
|
2128
|
+
"%s\n",
|
2062
2129
|
name,
|
2063
2130
|
name,
|
2064
2131
|
name,
|
@@ -2493,22 +2560,40 @@ unsigned int formatStoreSession(void *rulesBinding,
|
|
2493
2560
|
char *sid,
|
2494
2561
|
char *state,
|
2495
2562
|
unsigned char tryExists,
|
2496
|
-
char **
|
2563
|
+
char **storeCommand,
|
2564
|
+
char **versionCommand) {
|
2497
2565
|
binding *currentBinding = (binding*)rulesBinding;
|
2498
2566
|
|
2499
2567
|
int result;
|
2500
2568
|
if (tryExists) {
|
2501
|
-
result = redisFormatCommand(
|
2569
|
+
result = redisFormatCommand(storeCommand,
|
2502
2570
|
"hsetnx %s %s %s",
|
2503
2571
|
currentBinding->sessionHashset,
|
2504
2572
|
sid,
|
2505
2573
|
state);
|
2574
|
+
if (result == 0) {
|
2575
|
+
return ERR_OUT_OF_MEMORY;
|
2576
|
+
}
|
2577
|
+
|
2578
|
+
result = redisFormatCommand(versionCommand,
|
2579
|
+
"hsetnx %s!v %s 0",
|
2580
|
+
currentBinding->sessionHashset,
|
2581
|
+
sid);
|
2506
2582
|
} else {
|
2507
|
-
result = redisFormatCommand(
|
2583
|
+
result = redisFormatCommand(storeCommand,
|
2508
2584
|
"hset %s %s %s",
|
2509
2585
|
currentBinding->sessionHashset,
|
2510
2586
|
sid,
|
2511
2587
|
state);
|
2588
|
+
|
2589
|
+
if (result == 0) {
|
2590
|
+
return ERR_OUT_OF_MEMORY;
|
2591
|
+
}
|
2592
|
+
|
2593
|
+
result = redisFormatCommand(versionCommand,
|
2594
|
+
"hincrby %s!v %s 1",
|
2595
|
+
currentBinding->sessionHashset,
|
2596
|
+
sid);
|
2512
2597
|
}
|
2513
2598
|
|
2514
2599
|
if (result == 0) {
|
@@ -3028,6 +3113,38 @@ unsigned int getSession(void *rulesBinding, char *sid, char **state) {
|
|
3028
3113
|
return REDIS_OK;
|
3029
3114
|
}
|
3030
3115
|
|
3116
|
+
unsigned int getSessionVersion(void *rulesBinding, char *sid, unsigned long *stateVersion) {
|
3117
|
+
binding *currentBinding = (binding*)rulesBinding;
|
3118
|
+
redisContext *reContext = currentBinding->reContext;
|
3119
|
+
unsigned int result = redisAppendCommand(reContext,
|
3120
|
+
"hget %s!v %s",
|
3121
|
+
currentBinding->sessionHashset,
|
3122
|
+
sid);
|
3123
|
+
if (result != REDIS_OK) {
|
3124
|
+
return ERR_REDIS_ERROR;
|
3125
|
+
}
|
3126
|
+
|
3127
|
+
redisReply *reply;
|
3128
|
+
result = tryGetReply(reContext, &reply);
|
3129
|
+
if (result != RULES_OK) {
|
3130
|
+
return result;
|
3131
|
+
}
|
3132
|
+
|
3133
|
+
if (reply->type == REDIS_REPLY_ERROR) {
|
3134
|
+
freeReplyObject(reply);
|
3135
|
+
return ERR_REDIS_ERROR;
|
3136
|
+
}
|
3137
|
+
|
3138
|
+
if (reply->type != REDIS_REPLY_INTEGER) {
|
3139
|
+
*stateVersion = 0;
|
3140
|
+
} else {
|
3141
|
+
*stateVersion = reply->integer;
|
3142
|
+
}
|
3143
|
+
|
3144
|
+
freeReplyObject(reply);
|
3145
|
+
return REDIS_OK;
|
3146
|
+
}
|
3147
|
+
|
3031
3148
|
unsigned int deleteSession(void *rulesBinding, char *sid) {
|
3032
3149
|
binding *currentBinding = (binding*)rulesBinding;
|
3033
3150
|
redisContext *reContext = currentBinding->reContext;
|
data/src/rules/net.h
CHANGED
@@ -74,7 +74,8 @@ unsigned int formatStoreSession(void *rulesBinding,
|
|
74
74
|
char *sid,
|
75
75
|
char *state,
|
76
76
|
unsigned char tryExists,
|
77
|
-
char **
|
77
|
+
char **storeCommand,
|
78
|
+
char **versionCommand);
|
78
79
|
|
79
80
|
unsigned int formatStoreSessionFact(void *rulesBinding,
|
80
81
|
char *sid,
|
@@ -148,6 +149,10 @@ unsigned int getSession(void *rulesBinding,
|
|
148
149
|
char *sid,
|
149
150
|
char **state);
|
150
151
|
|
152
|
+
unsigned int getSessionVersion(void *rulesBinding,
|
153
|
+
char *sid,
|
154
|
+
unsigned long *stateVersion);
|
155
|
+
|
151
156
|
unsigned int deleteSession(void *rulesBinding,
|
152
157
|
char *sid);
|
153
158
|
|
data/src/rules/rules.h
CHANGED
@@ -131,7 +131,8 @@ unsigned int startUpdateState(void *handle,
|
|
131
131
|
void **rulesBinding,
|
132
132
|
unsigned int *replyCount);
|
133
133
|
|
134
|
-
unsigned int assertState(void *handle,
|
134
|
+
unsigned int assertState(void *handle,
|
135
|
+
char *sid,
|
135
136
|
char *state);
|
136
137
|
|
137
138
|
unsigned int startAction(void *handle,
|
data/src/rules/state.c
CHANGED
@@ -453,6 +453,17 @@ unsigned int getState(void *handle, char *sid, char **state) {
|
|
453
453
|
return getSession(rulesBinding, sid, state);
|
454
454
|
}
|
455
455
|
|
456
|
+
unsigned int getStateVersion(void *handle, char *sid, unsigned long *stateVersion) {
|
457
|
+
void *rulesBinding = NULL;
|
458
|
+
unsigned int result = resolveBinding(handle, sid, &rulesBinding);
|
459
|
+
if (result != RULES_OK) {
|
460
|
+
return result;
|
461
|
+
}
|
462
|
+
|
463
|
+
return getSessionVersion(rulesBinding, sid, stateVersion);
|
464
|
+
}
|
465
|
+
|
466
|
+
|
456
467
|
unsigned int deleteState(void *handle, char *sid) {
|
457
468
|
void *rulesBinding = NULL;
|
458
469
|
unsigned int result = resolveBinding(handle, sid, &rulesBinding);
|
data/src/rules/state.h
CHANGED
data/src/rulesrb/rules.c
CHANGED
@@ -420,11 +420,12 @@ static VALUE rbRetractFacts(VALUE self, VALUE handle, VALUE facts) {
|
|
420
420
|
return Qnil;
|
421
421
|
}
|
422
422
|
|
423
|
-
static VALUE rbAssertState(VALUE self, VALUE handle, VALUE state) {
|
423
|
+
static VALUE rbAssertState(VALUE self, VALUE handle, VALUE sid, VALUE state) {
|
424
424
|
Check_Type(handle, T_FIXNUM);
|
425
|
+
Check_Type(sid, T_STRING);
|
425
426
|
Check_Type(state, T_STRING);
|
426
427
|
|
427
|
-
unsigned int result = assertState((void *)FIX2LONG(handle), RSTRING_PTR(state));
|
428
|
+
unsigned int result = assertState((void *)FIX2LONG(handle), RSTRING_PTR(sid), RSTRING_PTR(state));
|
428
429
|
if (result == RULES_OK || result == ERR_EVENT_NOT_HANDLED || result == ERR_EVENT_OBSERVED) {
|
429
430
|
return INT2FIX(result);
|
430
431
|
} else {
|
@@ -671,7 +672,7 @@ void Init_rules() {
|
|
671
672
|
rb_define_singleton_method(rulesModule, "queue_retract_fact", rbQueueRetractFact, 4);
|
672
673
|
rb_define_singleton_method(rulesModule, "start_retract_facts", rbStartRetractFacts, 2);
|
673
674
|
rb_define_singleton_method(rulesModule, "retract_facts", rbRetractFacts, 2);
|
674
|
-
rb_define_singleton_method(rulesModule, "assert_state", rbAssertState,
|
675
|
+
rb_define_singleton_method(rulesModule, "assert_state", rbAssertState, 3);
|
675
676
|
rb_define_singleton_method(rulesModule, "start_update_state", rbStartUpdateState, 3);
|
676
677
|
rb_define_singleton_method(rulesModule, "start_action", rbStartAction, 1);
|
677
678
|
rb_define_singleton_method(rulesModule, "complete_action", rbCompleteAction, 3);
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: durable_rules
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.34.
|
4
|
+
version: 0.34.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jesus Ruiz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -129,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
129
|
version: '0'
|
130
130
|
requirements: []
|
131
131
|
rubyforge_project:
|
132
|
-
rubygems_version: 2.0.14
|
132
|
+
rubygems_version: 2.0.14.1
|
133
133
|
signing_key:
|
134
134
|
specification_version: 4
|
135
135
|
summary: for real time analytics (a Ruby Rules Engine)
|