durable_rules 0.33.13 → 0.34.01

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.
data/src/rules/net.c CHANGED
@@ -2,6 +2,7 @@
2
2
  #include <stdlib.h>
3
3
  #include <string.h>
4
4
  #include <time.h>
5
+ #include <errno.h>
5
6
  #include "net.h"
6
7
  #include "rules.h"
7
8
  #include "json.h"
@@ -894,7 +895,6 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
894
895
  "local events_mids_cache = {}\n"
895
896
  "local context_directory = {}\n"
896
897
  "local input_keys = {}\n"
897
- "local candidate = nil\n"
898
898
  "local toggle\n"
899
899
  "local expressions_count\n"
900
900
  "local results\n"
@@ -1138,7 +1138,6 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1138
1138
  "end\n"
1139
1139
  "local process_key_with_span = function(message, span)\n"
1140
1140
  " local index = directory[key]\n"
1141
- " local next_result = nil\n"
1142
1141
  " local queue_lock = false\n"
1143
1142
  " if index then\n"
1144
1143
  " local last_score = redis.call(\"get\", results_key .. \"!d\")\n"
@@ -1176,11 +1175,10 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1176
1175
  " end\n"
1177
1176
  " end\n"
1178
1177
  " end\n"
1179
- " return queue_lock, next_result\n"
1178
+ " return queue_lock\n"
1180
1179
  "end\n"
1181
1180
  "local process_key_with_cap = function(message, cap)\n"
1182
1181
  " local index = directory[key]\n"
1183
- " local next_result = nil\n"
1184
1182
  " local queue_lock = false\n"
1185
1183
  " if index then\n"
1186
1184
  " local count = 0\n"
@@ -1204,20 +1202,6 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1204
1202
  " local diff\n"
1205
1203
  " local new_count, new_remain = math.modf(#results / cap)\n"
1206
1204
  " local new_remain = #results %% cap\n"
1207
- " if redis.call(\"llen\", actions_key .. \"!\" .. sid) == 2 then\n"
1208
- " local frames = {}\n"
1209
- " if new_count > 0 then\n"
1210
- " for i = 0, cap - 1, 1 do\n"
1211
- " table.insert(frames, unpacked_results[#unpacked_results - i])\n"
1212
- " end\n"
1213
- " else\n"
1214
- " for i = 0, new_remain - 1, 1 do\n"
1215
- " table.insert(frames, unpacked_results[#unpacked_results - i])\n"
1216
- " end\n"
1217
- " end\n"
1218
- " local last_name = string.find(results_key, \"!\") - 1\n"
1219
- " next_result = {[string.sub(results_key, 1, last_name)] = frames}\n"
1220
- " end\n"
1221
1205
  " if new_count > 0 then\n"
1222
1206
  " for i = 1, new_count, 1 do\n"
1223
1207
  " redis.call(\"rpush\", actions_key .. \"!\" .. sid, results_key)\n"
@@ -1233,11 +1217,10 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1233
1217
  " end\n"
1234
1218
  " end\n"
1235
1219
  " end\n"
1236
- " return queue_lock, next_result\n"
1220
+ " return queue_lock\n"
1237
1221
  "end\n"
1238
1222
  "local process_key_with_window = function(message, window)\n"
1239
1223
  " local index = directory[key]\n"
1240
- " local next_result = nil\n"
1241
1224
  " local queue_lock = false\n"
1242
1225
  " if index then\n"
1243
1226
  " local count = 0\n"
@@ -1264,18 +1247,6 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1264
1247
  " local new_count, prev_remain = math.modf(length / window)\n"
1265
1248
  " diff = new_count - prev_count\n"
1266
1249
  " if diff > 0 then\n"
1267
- " if redis.call(\"llen\", actions_key .. \"!\" .. sid) == 2 then\n"
1268
- " local frames = {}\n"
1269
- " for i = 0, window - 1, 1 do\n"
1270
- " table.insert(frames, unpacked_results[#unpacked_results - i])\n"
1271
- " end\n"
1272
- " local last_name = string.find(results_key, \"!\") - 1\n"
1273
- " if window == 1 then\n"
1274
- " next_result = {[string.sub(results_key, 1, last_name)] = frames[1]}\n"
1275
- " else\n"
1276
- " next_result = {[string.sub(results_key, 1, last_name)] = frames}\n"
1277
- " end\n"
1278
- " end\n"
1279
1250
  " for i = 0, diff - 1, 1 do\n"
1280
1251
  " redis.call(\"rpush\", actions_key .. \"!\" .. sid, results_key)\n"
1281
1252
  " if window == 1 then\n"
@@ -1288,7 +1259,7 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1288
1259
  " end\n"
1289
1260
  " end\n"
1290
1261
  " end\n"
1291
- " return queue_lock, next_result\n"
1262
+ " return queue_lock\n"
1292
1263
  "end\n"
1293
1264
  "local message = nil\n"
1294
1265
  "if #ARGV > (6 + keys_count) then\n"
@@ -1341,11 +1312,7 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1341
1312
  " expressions_count = context[\"expressions_count\"]\n"
1342
1313
  " local process_key = context[\"process_key\"]\n"
1343
1314
  " local process_key_count = context[\"process_key_count\"]\n"
1344
- " local new_candidate\n"
1345
- " queue_action, new_candidate = process_key(message, process_key_count)\n"
1346
- " if new_candidate then\n"
1347
- " candidate = new_candidate\n"
1348
- " end\n"
1315
+ " queue_action = process_key(message, process_key_count)\n"
1349
1316
  " if assert_fact == 0 and events_message_cache[tostring(message[\"id\"])] == false then\n"
1350
1317
  " break\n"
1351
1318
  " end\n"
@@ -1355,14 +1322,7 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1355
1322
  " redis.call(\"zadd\", actions_key , score, sid)\n"
1356
1323
  " end\n"
1357
1324
  "end\n"
1358
- "if not candidate then\n"
1359
- " if redis.call(\"llen\", actions_key .. \"!\" .. sid) > 2 then\n"
1360
- " end\n"
1361
- " return nil\n"
1362
- "else\n"
1363
- " redis.call(\"set\", \"skip\", \"yes\")\n"
1364
- " return {sid, cjson.encode(candidate)}\n"
1365
- "end\n",
1325
+ "return nil\n",
1366
1326
  name,
1367
1327
  name,
1368
1328
  name,
@@ -1388,10 +1348,6 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1388
1348
  free(lua);
1389
1349
 
1390
1350
  if (asprintf(&lua,
1391
- "if redis.call(\"get\", \"skip\") == \"yes\" then\n"
1392
- " redis.call(\"set\", \"skip\", \"no\")\n"
1393
- " return nil\n"
1394
- "end\n"
1395
1351
  "local facts_key = \"%s!f!\"\n"
1396
1352
  "local events_key = \"%s!e!\"\n"
1397
1353
  "local action_key = \"%s!a\"\n"
@@ -1567,7 +1523,7 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1567
1523
  "end\n"
1568
1524
  "local load_frame = function(max_score)\n"
1569
1525
  " local current_action = redis.call(\"zrange\", action_key, 0, 0, \"withscores\")\n"
1570
- " if #current_action == 0 or (tonumber(current_action[2]) > (max_score + 5)) then\n"
1526
+ " if (#current_action == 0) or (tonumber(current_action[2]) > (max_score + 5)) then\n"
1571
1527
  " return nil, nil, nil\n"
1572
1528
  " end\n"
1573
1529
  " local sid = current_action[1]\n"
@@ -1592,13 +1548,13 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1592
1548
  "local new_sid, action_name, frame\n"
1593
1549
  "if #ARGV == 3 then\n"
1594
1550
  " new_sid = ARGV[3]\n"
1595
- " action_name, frame = load_frame_from_sid(new_sid, ARGV[2])\n"
1551
+ " action_name, frame = load_frame_from_sid(new_sid, tonumber(ARGV[2]))\n"
1596
1552
  "else\n"
1597
1553
  " new_sid, action_name, frame = load_frame(tonumber(ARGV[2]))\n"
1598
1554
  "end\n"
1599
1555
  "if frame then\n"
1556
+ " redis.call(\"zadd\", action_key, tonumber(ARGV[1]), new_sid)\n"
1600
1557
  " if #ARGV == 2 then\n"
1601
- " redis.call(\"zincrby\", action_key, tonumber(ARGV[1]), new_sid)\n"
1602
1558
  " local state = redis.call(\"hget\", state_key, new_sid)\n"
1603
1559
  " return {new_sid, state, cjson.encode({[action_name] = frame})}\n"
1604
1560
  " else\n"
@@ -1706,7 +1662,7 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1706
1662
  free(lua);
1707
1663
 
1708
1664
  if (asprintf(&lua,
1709
- "local delete_frame = function(key)\n"
1665
+ "local delete_frame = function(key, action_key)\n"
1710
1666
  " local rule_action_key = redis.call(\"lpop\", key)\n"
1711
1667
  " local raw_count = redis.call(\"lpop\", key)\n"
1712
1668
  " local count = 1\n"
@@ -1720,7 +1676,7 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1720
1676
  " end\n"
1721
1677
  " else\n"
1722
1678
  " for i = 0, count - 1, 1 do\n"
1723
- " redis.call(\"lpop\", rule_action_key)\n"
1679
+ " local packed_frame = redis.call(\"rpop\", rule_action_key)\n"
1724
1680
  " end\n"
1725
1681
  " end\n"
1726
1682
  " return (redis.call(\"llen\", key) > 0)\n"
@@ -1728,14 +1684,10 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1728
1684
  "local sid = ARGV[1]\n"
1729
1685
  "local max_score = tonumber(ARGV[2])\n"
1730
1686
  "local action_key = \"%s!a\"\n"
1731
- "if delete_frame(action_key .. \"!\" .. sid) then\n"
1732
- //" if redis.call(\"get\", \"skip\") ~= \"yes\" then\n"
1733
- " redis.call(\"zadd\", action_key, max_score, sid)\n"
1734
- //" end\n"
1687
+ "if delete_frame(action_key .. \"!\" .. sid, action_key) then\n"
1688
+ " redis.call(\"zadd\", action_key , max_score, sid)\n"
1735
1689
  "else\n"
1736
- //" if redis.call(\"get\", \"skip\") ~= \"yes\" then\n"
1737
- " redis.call(\"zrem\", action_key, sid)\n"
1738
- //" end\n"
1690
+ " redis.call(\"zrem\", action_key, sid)\n"
1739
1691
  "end\n", name) == -1) {
1740
1692
  return ERR_OUT_OF_MEMORY;
1741
1693
  }
@@ -1806,6 +1758,29 @@ static unsigned int loadCommands(ruleset *tree, binding *rulesBinding) {
1806
1758
  freeReplyObject(reply);
1807
1759
  free(lua);
1808
1760
 
1761
+ if (asprintf(&lua,
1762
+ "local actions_key = \"%s!a\"\n"
1763
+ "local score = tonumber(ARGV[2])\n"
1764
+ "local sid = ARGV[1]\n"
1765
+ "if redis.call(\"zscore\", actions_key, sid) then\n"
1766
+ " redis.call(\"zadd\", actions_key , score, sid)\n"
1767
+ "end\n", name) == -1) {
1768
+ return ERR_OUT_OF_MEMORY;
1769
+ }
1770
+
1771
+ redisAppendCommand(reContext, "SCRIPT LOAD %s", lua);
1772
+ redisGetReply(reContext, (void**)&reply);
1773
+ if (reply->type == REDIS_REPLY_ERROR) {
1774
+ printf("%s\n", reply->str);
1775
+ freeReplyObject(reply);
1776
+ return ERR_REDIS_ERROR;
1777
+ }
1778
+
1779
+ strncpy(rulesBinding->updateActionHash, reply->str, 40);
1780
+ rulesBinding->updateActionHash[40] = '\0';
1781
+ freeReplyObject(reply);
1782
+ free(lua);
1783
+
1809
1784
  char *sessionHashset = malloc((nameLength + 3) * sizeof(char));
1810
1785
  if (!sessionHashset) {
1811
1786
  return ERR_OUT_OF_MEMORY;
@@ -1887,8 +1862,16 @@ unsigned int bindRuleset(void *handle,
1887
1862
  return ERR_CONNECT_REDIS;
1888
1863
  }
1889
1864
 
1865
+ struct timeval tv;
1866
+ tv.tv_sec = 10;
1867
+ tv.tv_usec = 0;
1868
+ int result = redisSetTimeout(reContext, tv);
1869
+ if (result != REDIS_OK) {
1870
+ return ERR_REDIS_ERROR;
1871
+ }
1872
+
1890
1873
  if (password != NULL) {
1891
- int result = redisAppendCommand(reContext, "auth %s", password);
1874
+ result = redisAppendCommand(reContext, "auth %s", password);
1892
1875
  if (result != REDIS_OK) {
1893
1876
  return ERR_REDIS_ERROR;
1894
1877
  }
@@ -2012,7 +1995,7 @@ unsigned int formatEvalMessage(void *rulesBinding,
2012
1995
  argv[4] = mid;
2013
1996
  argvl[4] = strlen(mid);
2014
1997
  argv[5] = score;
2015
- argvl[5] = 10;
1998
+ argvl[5] = strlen(score);
2016
1999
  argv[6] = (actionType == ACTION_ASSERT_FACT || actionType == ACTION_RETRACT_FACT) ? "1" : "0";
2017
2000
  argvl[6] = 1;
2018
2001
  argv[7] = keysLengthString;
@@ -2268,7 +2251,7 @@ unsigned int formatPeekAction(void *rulesBinding,
2268
2251
  int result = redisFormatCommand(command,
2269
2252
  "evalsha %s 0 %d %ld %s",
2270
2253
  currentBinding->peekActionHash,
2271
- 60,
2254
+ currentTime + 15,
2272
2255
  currentTime,
2273
2256
  sid);
2274
2257
  if (result == 0) {
@@ -2291,22 +2274,22 @@ unsigned int startNonBlockingBatch(void *rulesBinding,
2291
2274
  unsigned int result = RULES_OK;
2292
2275
  binding *currentBinding = (binding*)rulesBinding;
2293
2276
  redisContext *reContext = currentBinding->reContext;
2294
-
2277
+
2278
+ sds newbuf = sdsempty();
2295
2279
  for (unsigned int i = 0; i < commandCount; ++i) {
2296
- sds newbuf;
2297
- newbuf = sdscatlen(reContext->obuf, commands[i], strlen(commands[i]));
2280
+ newbuf = sdscatlen(newbuf, commands[i], strlen(commands[i]));
2298
2281
  if (newbuf == NULL) {
2299
2282
  return ERR_OUT_OF_MEMORY;
2300
2283
  }
2301
2284
 
2302
- reContext->obuf = newbuf;
2303
2285
  free(commands[i]);
2304
2286
  }
2305
2287
 
2288
+ reContext->obuf = newbuf;
2306
2289
  int wdone = 0;
2307
2290
  do {
2308
2291
  if (redisBufferWrite(reContext, &wdone) == REDIS_ERR) {
2309
- printf("error %u %s\n", reContext->err, reContext->errstr);
2292
+ printf("start non blocking batch error %u %s\n", reContext->err, reContext->errstr);
2310
2293
  return ERR_REDIS_ERROR;
2311
2294
  }
2312
2295
  } while (!wdone);
@@ -2314,6 +2297,22 @@ unsigned int startNonBlockingBatch(void *rulesBinding,
2314
2297
  return result;
2315
2298
  }
2316
2299
 
2300
+ static unsigned int tryGetReply(redisContext *reContext,
2301
+ redisReply **reply) {
2302
+
2303
+ if (redisGetReply(reContext, (void**)reply) != REDIS_OK) {
2304
+ printf("getReply err %d, %d, %s\n", reContext->err, errno, reContext->errstr);
2305
+ if (redisReconnect(reContext) != REDIS_OK) {
2306
+ printf("reconnect err %d, %d, %s\n", reContext->err, errno, reContext->errstr);
2307
+ return ERR_REDIS_ERROR;
2308
+ }
2309
+
2310
+ return ERR_TRY_AGAIN;
2311
+ }
2312
+
2313
+ return RULES_OK;
2314
+ }
2315
+
2317
2316
  unsigned int completeNonBlockingBatch(void *rulesBinding,
2318
2317
  unsigned int replyCount) {
2319
2318
  if (replyCount == 0) {
@@ -2325,12 +2324,12 @@ unsigned int completeNonBlockingBatch(void *rulesBinding,
2325
2324
  redisContext *reContext = currentBinding->reContext;
2326
2325
  redisReply *reply;
2327
2326
  for (unsigned int i = 0; i < replyCount; ++i) {
2328
- result = redisGetReply(reContext, (void**)&reply);
2329
- if (result != REDIS_OK) {
2330
- result = ERR_REDIS_ERROR;
2327
+ result = tryGetReply(reContext, &reply);
2328
+ if (result != RULES_OK) {
2329
+ return result;
2331
2330
  } else {
2332
2331
  if (reply->type == REDIS_REPLY_ERROR) {
2333
- printf("error %d %s\n", i, reply->str);
2332
+ printf("complete non blocking batch error %d %s\n", i, reply->str);
2334
2333
  result = ERR_REDIS_ERROR;
2335
2334
  }
2336
2335
 
@@ -2364,22 +2363,22 @@ unsigned int executeBatchWithReply(void *rulesBinding,
2364
2363
  *lastReply = NULL;
2365
2364
  }
2366
2365
 
2366
+ sds newbuf = sdsempty();
2367
2367
  for (unsigned int i = 0; i < commandCount; ++i) {
2368
- sds newbuf;
2369
- newbuf = sdscatlen(reContext->obuf, commands[i], strlen(commands[i]));
2368
+ newbuf = sdscatlen(newbuf, commands[i], strlen(commands[i]));
2370
2369
  if (newbuf == NULL) {
2371
2370
  return ERR_OUT_OF_MEMORY;
2372
2371
  }
2373
2372
 
2374
- reContext->obuf = newbuf;
2375
2373
  free(commands[i]);
2376
2374
  }
2377
2375
 
2376
+ reContext->obuf = newbuf;
2378
2377
  redisReply *reply;
2379
2378
  for (unsigned int i = 0; i < replyCount; ++i) {
2380
- result = redisGetReply(reContext, (void**)&reply);
2381
- if (result != REDIS_OK) {
2382
- result = ERR_REDIS_ERROR;
2379
+ result = tryGetReply(reContext, &reply);
2380
+ if (result != RULES_OK) {
2381
+ return result;
2383
2382
  } else {
2384
2383
  if (reply->type == REDIS_REPLY_ERROR) {
2385
2384
  printf("%s\n", reply->str);
@@ -2417,12 +2416,13 @@ unsigned int removeMessage(void *rulesBinding, char *sid, char *mid) {
2417
2416
  }
2418
2417
 
2419
2418
  redisReply *reply;
2420
- result = redisGetReply(reContext, (void**)&reply);
2421
- if (result != REDIS_OK) {
2422
- return ERR_REDIS_ERROR;
2419
+ result = tryGetReply(reContext, &reply);
2420
+ if (result != RULES_OK) {
2421
+ return result;
2423
2422
  }
2424
2423
 
2425
2424
  if (reply->type == REDIS_REPLY_ERROR) {
2425
+ printf("removeMessage err string %s\n", reply->str);
2426
2426
  freeReplyObject(reply);
2427
2427
  return ERR_REDIS_ERROR;
2428
2428
  }
@@ -2442,19 +2442,19 @@ unsigned int peekAction(ruleset *tree, void **bindingContext, redisReply **reply
2442
2442
  int result = redisAppendCommand(reContext,
2443
2443
  "evalsha %s 0 %d %ld",
2444
2444
  currentBinding->peekActionHash,
2445
- 60,
2445
+ currentTime + 15,
2446
2446
  currentTime);
2447
2447
  if (result != REDIS_OK) {
2448
2448
  continue;
2449
2449
  }
2450
2450
 
2451
- result = redisGetReply(reContext, (void**)reply);
2452
- if (result != REDIS_OK) {
2453
- return ERR_REDIS_ERROR;
2451
+ result = tryGetReply(reContext, reply);
2452
+ if (result != RULES_OK) {
2453
+ return result;
2454
2454
  }
2455
2455
 
2456
2456
  if ((*reply)->type == REDIS_REPLY_ERROR) {
2457
- printf("%s\n", (*reply)->str);
2457
+ printf("peekAction err string %s\n", (*reply)->str);
2458
2458
  freeReplyObject(*reply);
2459
2459
  return ERR_REDIS_ERROR;
2460
2460
  }
@@ -2486,12 +2486,13 @@ unsigned int peekTimers(ruleset *tree, void **bindingContext, redisReply **reply
2486
2486
  continue;
2487
2487
  }
2488
2488
 
2489
- result = redisGetReply(reContext, (void**)reply);
2490
- if (result != REDIS_OK) {
2491
- return ERR_REDIS_ERROR;
2489
+ result = tryGetReply(reContext, reply);
2490
+ if (result != RULES_OK) {
2491
+ return result;
2492
2492
  }
2493
2493
 
2494
2494
  if ((*reply)->type == REDIS_REPLY_ERROR) {
2495
+ printf("peekTimers err string %s\n", (*reply)->str);
2495
2496
  freeReplyObject(*reply);
2496
2497
  return ERR_REDIS_ERROR;
2497
2498
  }
@@ -2522,12 +2523,71 @@ unsigned int registerTimer(void *rulesBinding, unsigned int duration, char *time
2522
2523
  }
2523
2524
 
2524
2525
  redisReply *reply;
2525
- result = redisGetReply(reContext, (void**)&reply);
2526
+ result = tryGetReply(reContext, &reply);
2527
+ if (result != RULES_OK) {
2528
+ return result;
2529
+ }
2530
+
2531
+ if (reply->type == REDIS_REPLY_ERROR) {
2532
+ printf("registerTimer err string %s\n", reply->str);
2533
+ freeReplyObject(reply);
2534
+ return ERR_REDIS_ERROR;
2535
+ }
2536
+
2537
+ freeReplyObject(reply);
2538
+ return RULES_OK;
2539
+ }
2540
+
2541
+ unsigned int removeTimer(void *rulesBinding, char *timer) {
2542
+ binding *currentBinding = (binding*)rulesBinding;
2543
+ redisContext *reContext = currentBinding->reContext;
2544
+
2545
+ int result = redisAppendCommand(reContext,
2546
+ "zrem %s %s",
2547
+ currentBinding->timersSortedset,
2548
+ timer);
2526
2549
  if (result != REDIS_OK) {
2527
2550
  return ERR_REDIS_ERROR;
2528
2551
  }
2552
+
2553
+ redisReply *reply;
2554
+ result = tryGetReply(reContext, &reply);
2555
+ if (result != RULES_OK) {
2556
+ return result;
2557
+ }
2529
2558
 
2530
2559
  if (reply->type == REDIS_REPLY_ERROR) {
2560
+ printf("deleteTimer err string %s\n", reply->str);
2561
+ freeReplyObject(reply);
2562
+ return ERR_REDIS_ERROR;
2563
+ }
2564
+
2565
+ freeReplyObject(reply);
2566
+ return RULES_OK;
2567
+ }
2568
+
2569
+ unsigned int registerMessage(void *rulesBinding, char *destination, char *message) {
2570
+ binding *currentBinding = (binding*)rulesBinding;
2571
+ redisContext *reContext = currentBinding->reContext;
2572
+ time_t currentTime = time(NULL);
2573
+
2574
+ int result = redisAppendCommand(reContext,
2575
+ "zadd %s!t %ld %s",
2576
+ destination,
2577
+ currentTime,
2578
+ message);
2579
+ if (result != REDIS_OK) {
2580
+ return ERR_REDIS_ERROR;
2581
+ }
2582
+
2583
+ redisReply *reply;
2584
+ result = tryGetReply(reContext, &reply);
2585
+ if (result != RULES_OK) {
2586
+ return result;
2587
+ }
2588
+
2589
+ if (reply->type == REDIS_REPLY_ERROR) {
2590
+ printf("registerMessage err string %s\n", reply->str);
2531
2591
  freeReplyObject(reply);
2532
2592
  return ERR_REDIS_ERROR;
2533
2593
  }
@@ -2548,9 +2608,9 @@ unsigned int getSession(void *rulesBinding, char *sid, char **state) {
2548
2608
  }
2549
2609
 
2550
2610
  redisReply *reply;
2551
- result = redisGetReply(reContext, (void**)&reply);
2552
- if (result != REDIS_OK) {
2553
- return ERR_REDIS_ERROR;
2611
+ result = tryGetReply(reContext, &reply);
2612
+ if (result != RULES_OK) {
2613
+ return result;
2554
2614
  }
2555
2615
 
2556
2616
  if (reply->type == REDIS_REPLY_ERROR) {
@@ -2563,7 +2623,7 @@ unsigned int getSession(void *rulesBinding, char *sid, char **state) {
2563
2623
  return ERR_NEW_SESSION;
2564
2624
  }
2565
2625
 
2566
- *state = malloc(strlen(reply->str) * sizeof(char));
2626
+ *state = malloc((strlen(reply->str) + 1) * sizeof(char));
2567
2627
  if (!*state) {
2568
2628
  return ERR_OUT_OF_MEMORY;
2569
2629
  }
@@ -2572,4 +2632,32 @@ unsigned int getSession(void *rulesBinding, char *sid, char **state) {
2572
2632
  return REDIS_OK;
2573
2633
  }
2574
2634
 
2635
+ unsigned int updateAction(void *rulesBinding, char *sid) {
2636
+ binding *currentBinding = (binding*)rulesBinding;
2637
+ redisContext *reContext = currentBinding->reContext;
2638
+ time_t currentTime = time(NULL);
2575
2639
 
2640
+ int result = redisAppendCommand(reContext,
2641
+ "evalsha %s 0 %s %ld",
2642
+ currentBinding->updateActionHash,
2643
+ sid,
2644
+ currentTime + 15);
2645
+ if (result != REDIS_OK) {
2646
+ return ERR_REDIS_ERROR;
2647
+ }
2648
+
2649
+ redisReply *reply;
2650
+ result = tryGetReply(reContext, &reply);
2651
+ if (result != RULES_OK) {
2652
+ return result;
2653
+ }
2654
+
2655
+ if (reply->type == REDIS_REPLY_ERROR) {
2656
+ printf("updateAction err string %s\n", reply->str);
2657
+ freeReplyObject(reply);
2658
+ return ERR_REDIS_ERROR;
2659
+ }
2660
+
2661
+ freeReplyObject(reply);
2662
+ return RULES_OK;
2663
+ }