durable_rules 0.33.13 → 0.34.01

Sign up to get free protection for your applications and to get access to all the features.
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
+ }