durable_rules 0.34.10 → 0.34.11
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/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)
|