durable_rules 2.0.5 → 2.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f2783f44507366a2029205429dd94b99da4fdb8
4
- data.tar.gz: 15e4d147d321f18e701583d1cb0f1a77dac4a977
3
+ metadata.gz: c4dd49e4357fbd2d4df00d1055d3f28413f81631
4
+ data.tar.gz: 8f27a057991ac417017ad5127a2161a0be2accd8
5
5
  SHA512:
6
- metadata.gz: 73533cb05af0e9d0a5190187f5636e49fcbe000e7c2f374d3d142d20a998a94f22016a4570f1623e4809c8698d2d1a403afc1ca5aa2879a991998f2b93fa36d5
7
- data.tar.gz: 9ba5938a86bb9737246f6779a9d499f06eb116b2d079d5b2ac521769cbfde26b220c4dd68af14e12d1e5238927d155518e714aed5764d3b7a0e65dc8a06726a2
6
+ metadata.gz: a8c5ad57d5aa1cbdc2b798dfc2c91bab920d127b4ac05190c5a61a2eada58dc2261ee6bf062078ad1c7a4aa42e82e338b2580646ea5f3accefe8459f54063777
7
+ data.tar.gz: baa4b3ac0b646cf45cd427df314d015dc6a76d3d5d34b6126e2bc24cce39d971b43f540171422e7a874faa896d69573d8a6bba4f7baf5b1cf8e2861ead5d4473
data/src/rules/events.c CHANGED
@@ -13,13 +13,6 @@
13
13
  #include "regex.h"
14
14
  #include "rete.h"
15
15
 
16
- #define ACTION_ASSERT_FACT 1
17
- #define ACTION_ASSERT_EVENT 2
18
- #define ACTION_RETRACT_FACT 3
19
- #define ACTION_RETRACT_EVENT 4
20
- #define ACTION_UPDATE_STATE 5
21
-
22
-
23
16
  #define MAX_RESULT_NODES 32
24
17
  #define MAX_NODE_RESULTS 16
25
18
  #define MAX_STACK_SIZE 64
@@ -998,6 +991,7 @@ static unsigned int handleBetaFrame(ruleset *tree,
998
991
 
999
992
  static unsigned int handleDeleteMessage(ruleset *tree,
1000
993
  stateNode *state,
994
+ char *mid,
1001
995
  unsigned int messageOffset) {
1002
996
  unsigned int result;
1003
997
  unsigned int count = 0;
@@ -1139,7 +1133,10 @@ static unsigned int handleDeleteMessage(ruleset *tree,
1139
1133
  }
1140
1134
  }
1141
1135
 
1142
- result = deleteMessage(state, messageOffset);
1136
+ result = deleteMessage(tree,
1137
+ state,
1138
+ mid,
1139
+ messageOffset);
1143
1140
  if (result == ERR_NODE_DELETED) {
1144
1141
  return RULES_OK;
1145
1142
  } else if (result != RULES_OK) {
@@ -1590,14 +1587,17 @@ static unsigned int handleAlpha(ruleset *tree,
1590
1587
  stateNode *state,
1591
1588
  char *mid,
1592
1589
  jsonObject *jo,
1593
- unsigned int currentMessageOffset,
1594
- alpha *alphaNode) {
1590
+ unsigned char messageType,
1591
+ alpha *alphaNode,
1592
+ unsigned int *messageOffset) {
1595
1593
  unsigned short top = 1;
1596
1594
  unsigned int entry;
1595
+ unsigned char messageStored = 0;
1597
1596
  alpha *stack[MAX_STACK_SIZE];
1598
1597
  stack[0] = alphaNode;
1599
1598
  alpha *currentAlpha;
1600
1599
  unsigned int result = ERR_EVENT_NOT_HANDLED;
1600
+ *messageOffset = UNDEFINED_HASH_OFFSET;
1601
1601
 
1602
1602
  while (top) {
1603
1603
  --top;
@@ -1665,6 +1665,17 @@ static unsigned int handleAlpha(ruleset *tree,
1665
1665
  }
1666
1666
 
1667
1667
  if (currentAlpha->betaListOffset) {
1668
+ if (!messageStored) {
1669
+ CHECK_RESULT(storeMessage(tree,
1670
+ state,
1671
+ mid,
1672
+ jo,
1673
+ messageType,
1674
+ messageOffset));
1675
+
1676
+ messageStored = 1;
1677
+ }
1678
+
1668
1679
  result = RULES_OK;
1669
1680
  unsigned int *betaList = &tree->nextPool[currentAlpha->betaListOffset];
1670
1681
  for (unsigned int entry = 0; betaList[entry] != 0; ++entry) {
@@ -1672,7 +1683,7 @@ static unsigned int handleAlpha(ruleset *tree,
1672
1683
  state,
1673
1684
  &tree->nodePool[betaList[entry]],
1674
1685
  jo,
1675
- currentMessageOffset));
1686
+ *messageOffset));
1676
1687
  }
1677
1688
  }
1678
1689
  }
@@ -1702,7 +1713,7 @@ static unsigned int handleMessageCore(ruleset *tree,
1702
1713
 
1703
1714
  sid[sidProperty->valueLength] = '\0';
1704
1715
 
1705
- #ifdef _WIN32
1716
+ #ifdef _WIN32
1706
1717
  char *mid = (char *)_alloca(sizeof(char)*(midProperty->valueLength + 1));
1707
1718
  #else
1708
1719
  char mid[midProperty->valueLength + 1];
@@ -1713,38 +1724,59 @@ static unsigned int handleMessageCore(ruleset *tree,
1713
1724
  strncpy(mid, jo->idBuffer, midProperty->valueLength);
1714
1725
  }
1715
1726
 
1727
+ *stateOffset = UNDEFINED_HASH_OFFSET;
1716
1728
  mid[midProperty->valueLength] = '\0';
1717
- unsigned char isNewState;
1718
- CHECK_RESULT(ensureStateNode(tree,
1719
- sid,
1720
- &isNewState,
1721
- &sidState));
1729
+ unsigned int result = getStateNode(tree,
1730
+ sid,
1731
+ &sidState);
1732
+ if (result != RULES_OK && result != ERR_SID_NOT_FOUND) {
1733
+ return result;
1734
+ } else if (result == ERR_SID_NOT_FOUND) {
1735
+ if (!tree->queueMessageCallback) {
1736
+ CHECK_RESULT(createStateNode(tree,
1737
+ sid,
1738
+ &sidState));
1739
+ } else {
1740
+ CHECK_RESULT(tree->queueMessageCallback(tree->queueMessageCallbackContext,
1741
+ &tree->stringPool[tree->nameOffset],
1742
+ sid,
1743
+ actionType,
1744
+ jo->content));
1745
+
1746
+ return ERR_EVENT_DEFERRED;
1747
+ }
1748
+ }
1722
1749
 
1723
1750
  *stateOffset = sidState->offset;
1724
1751
  if (actionType == ACTION_UPDATE_STATE) {
1725
1752
  if (sidState->factOffset != UNDEFINED_HASH_OFFSET) {
1726
1753
  CHECK_RESULT(handleDeleteMessage(tree,
1727
1754
  sidState,
1755
+ mid,
1728
1756
  sidState->factOffset));
1729
1757
 
1730
1758
  }
1731
1759
 
1732
- CHECK_RESULT(storeMessage(sidState,
1760
+ result = handleAlpha(tree,
1761
+ sidState,
1762
+ mid,
1763
+ jo,
1764
+ MESSAGE_TYPE_FACT,
1765
+ &tree->nodePool[NODE_M_OFFSET].value.a,
1766
+ messageOffset);
1767
+ if (result != RULES_OK && result != ERR_EVENT_NOT_HANDLED) {
1768
+ return result;
1769
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
1770
+ CHECK_RESULT(storeMessage(tree,
1771
+ sidState,
1733
1772
  mid,
1734
1773
  jo,
1735
1774
  MESSAGE_TYPE_FACT,
1736
1775
  messageOffset));
1737
-
1776
+ }
1738
1777
 
1739
1778
  sidState->factOffset = *messageOffset;
1740
- CHECK_RESULT(handleAlpha(tree,
1741
- sidState,
1742
- mid,
1743
- jo,
1744
- sidState->factOffset,
1745
- &tree->nodePool[NODE_M_OFFSET].value.a));
1746
-
1747
- } else if (actionType == ACTION_RETRACT_FACT || actionType == ACTION_RETRACT_EVENT) {
1779
+ } else if (actionType == ACTION_RETRACT_FACT) {
1748
1780
  CHECK_RESULT(getMessage(sidState,
1749
1781
  mid,
1750
1782
  messageOffset));
@@ -1752,24 +1784,20 @@ static unsigned int handleMessageCore(ruleset *tree,
1752
1784
  if (*messageOffset != UNDEFINED_HASH_OFFSET) {
1753
1785
  CHECK_RESULT(handleDeleteMessage(tree,
1754
1786
  sidState,
1787
+ mid,
1755
1788
  *messageOffset));
1756
1789
  }
1757
1790
  } else {
1758
- CHECK_RESULT(storeMessage(sidState,
1759
- mid,
1760
- jo,
1761
- (actionType == ACTION_ASSERT_FACT ? MESSAGE_TYPE_FACT : MESSAGE_TYPE_EVENT),
1762
- messageOffset));
1763
-
1764
1791
  unsigned int result = handleAlpha(tree,
1765
1792
  sidState,
1766
1793
  mid,
1767
1794
  jo,
1768
- *messageOffset,
1769
- &tree->nodePool[NODE_M_OFFSET].value.a);
1795
+ (actionType == ACTION_ASSERT_FACT ? MESSAGE_TYPE_FACT : MESSAGE_TYPE_EVENT),
1796
+ &tree->nodePool[NODE_M_OFFSET].value.a,
1797
+ messageOffset);
1770
1798
 
1771
1799
  if (result == RULES_OK || result == ERR_EVENT_NOT_HANDLED) {
1772
- if (isNewState) {
1800
+ if (sidState->factOffset == UNDEFINED_HASH_OFFSET) {
1773
1801
  #ifdef _WIN32
1774
1802
  char *stateMessage = (char *)_alloca(sizeof(char)*(50 + sidProperty->valueLength * 2));
1775
1803
  sprintf_s(stateMessage, sizeof(char)*(50 + sidProperty->valueLength * 2), "{ \"sid\":\"%s\", \"id\":\"sid-%s\", \"$s\":1}", sid, sid);
@@ -1781,7 +1809,7 @@ static unsigned int handleMessageCore(ruleset *tree,
1781
1809
  unsigned int stateMessageOffset;
1782
1810
  unsigned int stateResult = handleMessage(tree,
1783
1811
  stateMessage,
1784
- ACTION_ASSERT_FACT,
1812
+ ACTION_UPDATE_STATE,
1785
1813
  &stateMessageOffset,
1786
1814
  stateOffset);
1787
1815
  if (stateResult != RULES_OK && stateResult != ERR_EVENT_NOT_HANDLED) {
@@ -1861,12 +1889,12 @@ static unsigned int handleMessages(ruleset *tree,
1861
1889
  stateOffset);
1862
1890
 
1863
1891
  *last = lastTemp;
1864
- if (result != RULES_OK && result != ERR_EVENT_NOT_HANDLED) {
1892
+ if (result != RULES_OK && result != ERR_EVENT_NOT_HANDLED && result != ERR_EVENT_OBSERVED) {
1865
1893
  return result;
1866
1894
  }
1867
1895
 
1868
- if (result == ERR_EVENT_NOT_HANDLED) {
1869
- returnResult = ERR_EVENT_NOT_HANDLED;
1896
+ if (result == ERR_EVENT_NOT_HANDLED || result == ERR_EVENT_OBSERVED) {
1897
+ returnResult = result;
1870
1898
  }
1871
1899
 
1872
1900
  first = last;
@@ -1949,6 +1977,149 @@ unsigned int updateState(unsigned int handle,
1949
1977
  return result;
1950
1978
  }
1951
1979
 
1980
+ static unsigned int replayMessages(ruleset *tree,
1981
+ char *messages,
1982
+ unsigned int *stateOffset) {
1983
+ unsigned int result;
1984
+ unsigned int messageOffset;
1985
+ jsonObject jo;
1986
+ unsigned char type;
1987
+ unsigned char actionType;
1988
+ char *first = messages;
1989
+ char *last = NULL;
1990
+ char lastTemp;
1991
+
1992
+ while (readNextArrayValue(first,
1993
+ &first,
1994
+ &last,
1995
+ &type) == PARSE_OK) {
1996
+
1997
+ if (type != JSON_INT) {
1998
+ return ERR_UNEXPECTED_TYPE;
1999
+ }
2000
+
2001
+ char temp = last[1];
2002
+ last[1] = '\0';
2003
+ actionType = atol(first);
2004
+ last[1] = temp;
2005
+ first = last;
2006
+
2007
+ CHECK_PARSE_RESULT(readNextArrayValue(first,
2008
+ &first,
2009
+ &last,
2010
+ &type));
2011
+
2012
+ if (type != JSON_OBJECT) {
2013
+ return ERR_UNEXPECTED_TYPE;
2014
+ }
2015
+
2016
+ CHECK_RESULT(constructObject(first,
2017
+ NULL,
2018
+ NULL,
2019
+ 1,
2020
+ &jo,
2021
+ &last));
2022
+
2023
+ while (*last != ',' && *last != '\0' ) {
2024
+ ++last;
2025
+ }
2026
+
2027
+ if (*last == '\0') {
2028
+ --last;
2029
+ }
2030
+
2031
+ lastTemp = *last;
2032
+ *last = '\0';
2033
+ result = handleMessageCore(tree,
2034
+ &jo,
2035
+ actionType,
2036
+ &messageOffset,
2037
+ stateOffset);
2038
+
2039
+ *last = lastTemp;
2040
+ if (result != RULES_OK && result != ERR_EVENT_NOT_HANDLED && result != ERR_EVENT_OBSERVED) {
2041
+ return result;
2042
+ }
2043
+
2044
+ first = last;
2045
+ }
2046
+
2047
+ return RULES_OK;
2048
+ }
2049
+
2050
+
2051
+ static unsigned int flushQueuedActions(ruleset *tree) {
2052
+ if (tree->getIdleStateCallback) {
2053
+ char *sid;
2054
+ CHECK_RESULT(tree->getIdleStateCallback(tree->getIdleStateCallbackContext,
2055
+ &tree->stringPool[tree->nameOffset],
2056
+ &sid));
2057
+ if (sid) {
2058
+ stateNode *state;
2059
+ unsigned int result = getStateNode(tree,
2060
+ sid,
2061
+ &state);
2062
+ if (result != RULES_OK && result != ERR_SID_NOT_FOUND) {
2063
+ return result;
2064
+ } else if (result == RULES_OK) {
2065
+ CHECK_RESULT(deleteStateNode(tree,
2066
+ state));
2067
+ }
2068
+
2069
+ CHECK_RESULT(createStateNode(tree,
2070
+ sid,
2071
+ &state));
2072
+
2073
+ free(sid);
2074
+ if (tree->getStoredMessagesCallback) {
2075
+ char *messages;
2076
+ unsigned int stateOffset;
2077
+ CHECK_RESULT(tree->getStoredMessagesCallback(tree->getStoredMessagesCallbackContext,
2078
+ &tree->stringPool[tree->nameOffset],
2079
+ state->sid,
2080
+ &messages));
2081
+ if (messages) {
2082
+ result = replayMessages(tree,
2083
+ messages,
2084
+ &stateOffset);
2085
+
2086
+ free(messages);
2087
+ if (result != RULES_OK) {
2088
+ return result;
2089
+ }
2090
+
2091
+ }
2092
+ }
2093
+ }
2094
+ }
2095
+
2096
+
2097
+ if (tree->getQueuedMessagesCallback) {
2098
+ for (unsigned int index = 0; index < tree->statePool.count; ++index) {
2099
+ unsigned int nodeOffset = tree->reverseStateIndex[index];
2100
+ stateNode *currentState = STATE_NODE(tree, nodeOffset);
2101
+
2102
+ char *messages;
2103
+ unsigned int stateOffset;
2104
+ CHECK_RESULT(tree->getQueuedMessagesCallback(tree->getQueuedMessagesCallbackContext,
2105
+ &tree->stringPool[tree->nameOffset],
2106
+ currentState->sid,
2107
+ &messages));
2108
+ if (messages) {
2109
+ unsigned int result = replayMessages(tree,
2110
+ messages,
2111
+ &stateOffset);
2112
+ free(messages);
2113
+ if (result != RULES_OK) {
2114
+ return result;
2115
+ }
2116
+ }
2117
+ }
2118
+ }
2119
+
2120
+ return RULES_OK;
2121
+ }
2122
+
1952
2123
  unsigned int startAction(unsigned int handle,
1953
2124
  char **stateFact,
1954
2125
  char **messages,
@@ -1962,6 +2133,8 @@ unsigned int startAction(unsigned int handle,
1962
2133
  unsigned int resultFrameOffset;
1963
2134
  time_t currentTime = time(NULL);
1964
2135
 
2136
+ CHECK_RESULT(flushQueuedActions(tree));
2137
+
1965
2138
  CHECK_RESULT(getNextResult(tree,
1966
2139
  currentTime,
1967
2140
  &resultState,
@@ -1995,6 +2168,11 @@ unsigned int startActionForState(unsigned int handle,
1995
2168
  unsigned int stateOffset,
1996
2169
  char **stateFact,
1997
2170
  char **messages) {
2171
+
2172
+ if (stateOffset == UNDEFINED_HASH_OFFSET) {
2173
+ return ERR_NO_ACTION_AVAILABLE;
2174
+ }
2175
+
1998
2176
  ruleset *tree;
1999
2177
  RESOLVE_HANDLE(handle, &tree);
2000
2178
  stateNode *resultState = STATE_NODE(tree, stateOffset);
@@ -2052,10 +2230,26 @@ static unsigned int deleteCurrentAction(ruleset *tree,
2052
2230
  messageNode *currentMessageNode = MESSAGE_NODE(state,
2053
2231
  currentMessageFrame->messageNodeOffset);
2054
2232
 
2055
-
2056
2233
  if (currentMessageNode->messageType == MESSAGE_TYPE_EVENT) {
2234
+ jsonObject *jo = &currentMessageNode->jo;
2235
+ jsonProperty *midProperty = &jo->properties[jo->idIndex];
2236
+
2237
+ #ifdef _WIN32
2238
+ char *mid = (char *)_alloca(sizeof(char)*(midProperty->valueLength + 1));
2239
+ #else
2240
+ char mid[midProperty->valueLength + 1];
2241
+ #endif
2242
+ if (midProperty->valueOffset) {
2243
+ strncpy(mid, jo->content + midProperty->valueOffset, midProperty->valueLength);
2244
+ } else {
2245
+ strncpy(mid, jo->idBuffer, midProperty->valueLength);
2246
+ }
2247
+
2248
+ mid[midProperty->valueLength] = '\0';
2249
+
2057
2250
  CHECK_RESULT(handleDeleteMessage(tree,
2058
- state,
2251
+ state,
2252
+ mid,
2059
2253
  currentMessageFrame->messageNodeOffset));
2060
2254
  }
2061
2255
  }
@@ -2091,7 +2285,6 @@ unsigned int completeAndStartAction(unsigned int handle,
2091
2285
  ruleset *tree;
2092
2286
  RESOLVE_HANDLE(handle, &tree);
2093
2287
  stateNode *resultState = STATE_NODE(tree, stateOffset);
2094
-
2095
2288
  CHECK_RESULT(deleteCurrentAction(tree,
2096
2289
  resultState,
2097
2290
  resultState->context.actionStateIndex,
@@ -2138,7 +2331,6 @@ unsigned int abandonAction(unsigned int handle, unsigned int stateOffset) {
2138
2331
 
2139
2332
  unsigned int renewActionLease(unsigned int handle, char *sid) {
2140
2333
  ruleset *tree;
2141
- unsigned char isNewState;
2142
2334
  stateNode *state = NULL;
2143
2335
 
2144
2336
  RESOLVE_HANDLE(handle, &tree);
@@ -2146,10 +2338,9 @@ unsigned int renewActionLease(unsigned int handle, char *sid) {
2146
2338
  sid = "0";
2147
2339
  }
2148
2340
 
2149
- CHECK_RESULT(ensureStateNode(tree,
2150
- sid,
2151
- &isNewState,
2152
- &state));
2341
+ CHECK_RESULT(getStateNode(tree,
2342
+ sid,
2343
+ &state));
2153
2344
 
2154
2345
  state->lockExpireTime = time(NULL) + STATE_LEASE_TIME;
2155
2346
  return RULES_OK;
@@ -2209,7 +2400,6 @@ unsigned int assertTimers(unsigned int handle) {
2209
2400
 
2210
2401
  unsigned int cancelTimer(unsigned int handle, char *sid, char *timerName) {
2211
2402
  ruleset *tree;
2212
- unsigned char isNewState;
2213
2403
  unsigned int messageOffset;
2214
2404
  unsigned int stateOffset;
2215
2405
  stateNode *state = NULL;
@@ -2219,10 +2409,9 @@ unsigned int cancelTimer(unsigned int handle, char *sid, char *timerName) {
2219
2409
  sid = "0";
2220
2410
  }
2221
2411
 
2222
- CHECK_RESULT(ensureStateNode(tree,
2223
- sid,
2224
- &isNewState,
2225
- &state));
2412
+ CHECK_RESULT(getStateNode(tree,
2413
+ sid,
2414
+ &state));
2226
2415
 
2227
2416
  CHECK_RESULT(getMessage(state,
2228
2417
  timerName,
data/src/rules/rete.c CHANGED
@@ -1852,6 +1852,19 @@ unsigned int createRuleset(unsigned int *handle, char *name, char *rules) {
1852
1852
  tree->actionCount = 0;
1853
1853
  tree->bindingsList = NULL;
1854
1854
  tree->currentStateIndex = 0;
1855
+ tree->storeMessageCallback = NULL;
1856
+ tree->storeMessageCallbackContext = NULL;
1857
+ tree->deleteMessageCallback = NULL;
1858
+ tree->deleteMessageCallbackContext = NULL;
1859
+ tree->queueMessageCallback = NULL;
1860
+ tree->queueMessageCallbackContext = NULL;
1861
+ tree->getQueuedMessagesCallback = NULL;
1862
+ tree->getQueuedMessagesCallbackContext = NULL;
1863
+ tree->getStoredMessagesCallback = NULL;
1864
+ tree->getStoredMessagesCallbackContext = NULL;
1865
+ tree->getIdleStateCallback = NULL;
1866
+ tree->getIdleStateCallbackContext = NULL;
1867
+
1855
1868
  memset(tree->stateIndex, 0, MAX_STATE_INDEX_LENGTH * sizeof(unsigned int) * 2);
1856
1869
  memset(tree->reverseStateIndex, 0, MAX_STATE_INDEX_LENGTH * sizeof(unsigned int));
1857
1870
  initStatePool(tree);
@@ -1894,4 +1907,66 @@ unsigned int deleteRuleset(unsigned int handle) {
1894
1907
  return RULES_OK;
1895
1908
  }
1896
1909
 
1910
+ unsigned int setStoreMessageCallback(unsigned int handle,
1911
+ void *context,
1912
+ unsigned int (*callback)(void *, char *, char *, char *, unsigned char, char *)) {
1913
+ ruleset *tree;
1914
+ RESOLVE_HANDLE(handle, &tree);
1915
+ tree->storeMessageCallbackContext = context;
1916
+ tree->storeMessageCallback = callback;
1917
+ return RULES_OK;
1918
+ }
1919
+
1920
+ unsigned int setDeleteMessageCallback(unsigned int handle,
1921
+ void *context,
1922
+ unsigned int (*callback)(void *, char *, char *, char *)) {
1923
+ ruleset *tree;
1924
+ RESOLVE_HANDLE(handle, &tree);
1925
+ tree->deleteMessageCallbackContext = context;
1926
+ tree->deleteMessageCallback = callback;
1927
+ return RULES_OK;
1928
+ }
1929
+
1930
+ unsigned int setQueueMessageCallback(unsigned int handle,
1931
+ void *context,
1932
+ unsigned int (*callback)(void *, char *, char *, unsigned char, char *)) {
1933
+ ruleset *tree;
1934
+ RESOLVE_HANDLE(handle, &tree);
1935
+ tree->queueMessageCallbackContext = context;
1936
+ tree->queueMessageCallback = callback;
1937
+ return RULES_OK;
1938
+ }
1939
+
1940
+ unsigned int setGetQueuedMessagesCallback(unsigned int handle,
1941
+ void *context,
1942
+ unsigned int (*callback)(void *, char *, char *, char **)) {
1943
+ ruleset *tree;
1944
+ RESOLVE_HANDLE(handle, &tree);
1945
+
1946
+ tree->getQueuedMessagesCallbackContext = context;
1947
+ tree->getQueuedMessagesCallback = callback;
1948
+ return RULES_OK;
1949
+ }
1950
+
1951
+ unsigned int setGetStoredMessagesCallback(unsigned int handle,
1952
+ void *context,
1953
+ unsigned int (*callback)(void *, char *, char *, char **)) {
1954
+ ruleset *tree;
1955
+ RESOLVE_HANDLE(handle, &tree);
1956
+
1957
+ tree->getStoredMessagesCallbackContext = context;
1958
+ tree->getStoredMessagesCallback = callback;
1959
+ return RULES_OK;
1960
+ }
1961
+
1962
+ unsigned int setGetIdleStateCallback(unsigned int handle,
1963
+ void *context,
1964
+ unsigned int (*callback)(void *, char *, char **)) {
1965
+ ruleset *tree;
1966
+ RESOLVE_HANDLE(handle, &tree);
1967
+
1968
+ tree->getIdleStateCallbackContext = context;
1969
+ tree->getIdleStateCallback = callback;
1970
+ return RULES_OK;
1971
+ }
1897
1972
 
data/src/rules/rete.h CHANGED
@@ -146,6 +146,27 @@ typedef struct ruleset {
146
146
  unsigned int stateIndex[MAX_STATE_INDEX_LENGTH];
147
147
  unsigned int reverseStateIndex[MAX_STATE_INDEX_LENGTH];
148
148
  unsigned int currentStateIndex;
149
+
150
+
151
+ unsigned int (*storeMessageCallback)(void *, char *, char *, char *, unsigned char, char *);
152
+ void *storeMessageCallbackContext;
153
+
154
+ unsigned int (*deleteMessageCallback)(void *, char *, char *, char *);
155
+ void *deleteMessageCallbackContext;
156
+
157
+ unsigned int (*queueMessageCallback)(void *, char *, char *, unsigned char, char *);
158
+ void *queueMessageCallbackContext;
159
+
160
+ unsigned int (*getQueuedMessagesCallback)(void *, char *, char *, char **);
161
+ void *getQueuedMessagesCallbackContext;
162
+
163
+ unsigned int (*getStoredMessagesCallback)(void *, char *, char *, char **);
164
+ void *getStoredMessagesCallbackContext;
165
+
166
+ unsigned int (*getIdleStateCallback)(void *, char *, char **);
167
+ void *getIdleStateCallbackContext;
168
+
169
+
149
170
  } ruleset;
150
171
 
151
172
  #ifdef _PRINT
data/src/rules/rules.h CHANGED
@@ -2,6 +2,7 @@
2
2
  #define RULES_OK 0
3
3
  #define ERR_EVENT_NOT_HANDLED 1
4
4
  #define ERR_EVENT_OBSERVED 2
5
+ #define ERR_EVENT_DEFERRED 3
5
6
 
6
7
  #define ERR_OUT_OF_MEMORY 101
7
8
  #define ERR_UNEXPECTED_TYPE 102
@@ -108,10 +109,37 @@ extern char entriesInitialized;
108
109
  if (!firstEmptyEntry) firstEmptyEntry = lastEmptyEntry; \
109
110
  } while(0)
110
111
 
112
+
113
+ unsigned int cloneString(char **target, char *source);
114
+
111
115
  unsigned int createRuleset(unsigned int *handle,
112
116
  char *name,
113
117
  char *rules);
114
118
 
119
+ unsigned int setStoreMessageCallback(unsigned int handle,
120
+ void *context,
121
+ unsigned int (*callback)(void *, char *, char *, char *, unsigned char, char *));
122
+
123
+ unsigned int setDeleteMessageCallback(unsigned int handle,
124
+ void *context,
125
+ unsigned int (*callback)(void *, char *, char *, char *));
126
+
127
+ unsigned int setQueueMessageCallback(unsigned int handle,
128
+ void *context,
129
+ unsigned int (*callback)(void *, char *, char *, unsigned char, char *));
130
+
131
+ unsigned int setGetQueuedMessagesCallback(unsigned int handle,
132
+ void *context,
133
+ unsigned int (*callback)(void *, char *, char *, char **));
134
+
135
+ unsigned int setGetStoredMessagesCallback(unsigned int handle,
136
+ void *context,
137
+ unsigned int (*callback)(void *, char *, char *, char **));
138
+
139
+ unsigned int setGetIdleStateCallback(unsigned int handle,
140
+ void *context,
141
+ unsigned int (*callback)(void *, char *, char **));
142
+
115
143
  unsigned int deleteRuleset(unsigned int handle);
116
144
 
117
145
  unsigned int createClient(unsigned int *handle,
data/src/rules/state.c CHANGED
@@ -154,6 +154,17 @@ int asprintf(char** ret, char* format, ...){
154
154
  --pool.count; \
155
155
  } while (0)
156
156
 
157
+ unsigned int cloneString(char **target, char *source) {
158
+ unsigned int length = (strlen(source) + 1) * sizeof(char);
159
+ *target = malloc(length);
160
+ if (!*target) {
161
+ return ERR_OUT_OF_MEMORY;
162
+ }
163
+ memcpy(*target, source, length);
164
+
165
+ return RULES_OK;
166
+ }
167
+
157
168
  unsigned int fnv1Hash32(char *str, unsigned int length) {
158
169
  unsigned int hash = FNV_32_OFFSET_BASIS;
159
170
  for(unsigned int i = 0; i < length; str++, i++) {
@@ -670,10 +681,19 @@ unsigned int createRightFrame(stateNode *state,
670
681
  return RULES_OK;
671
682
  }
672
683
 
673
- unsigned int deleteMessage(stateNode *state,
684
+ unsigned int deleteMessage(void *tree,
685
+ stateNode *state,
686
+ char *mid,
674
687
  unsigned int messageNodeOffset) {
675
-
676
688
  messageNode *node = MESSAGE_NODE(state, messageNodeOffset);
689
+ ruleset *rulesetTree = (ruleset*)tree;
690
+ if (rulesetTree->deleteMessageCallback) {
691
+ CHECK_RESULT(rulesetTree->deleteMessageCallback(rulesetTree->deleteMessageCallbackContext,
692
+ &rulesetTree->stringPool[rulesetTree->nameOffset],
693
+ state->sid,
694
+ mid));
695
+ }
696
+
677
697
  if (node->jo.content) {
678
698
  free(node->jo.content);
679
699
  free(node->locationPool.content);
@@ -686,6 +706,7 @@ unsigned int deleteMessage(stateNode *state,
686
706
  MAX_MESSAGE_INDEX_LENGTH,
687
707
  state->messagePool,
688
708
  messageNodeOffset);
709
+
689
710
  return RULES_OK;
690
711
  }
691
712
 
@@ -724,7 +745,8 @@ static unsigned int copyMessage(jsonObject *targetMessage,
724
745
  return RULES_OK;
725
746
  }
726
747
 
727
- unsigned int storeMessage(stateNode *state,
748
+ unsigned int storeMessage(void *tree,
749
+ stateNode *state,
728
750
  char *mid,
729
751
  jsonObject *message,
730
752
  unsigned char messageType,
@@ -762,13 +784,29 @@ unsigned int storeMessage(stateNode *state,
762
784
  memset(node->locationIndex, 0, MAX_LOCATION_INDEX_LENGTH * sizeof(unsigned int) * 2);
763
785
 
764
786
  node->messageType = messageType;
765
- return copyMessage(&node->jo, message);
787
+ CHECK_RESULT(copyMessage(&node->jo, message));
788
+
789
+ ruleset *rulesetTree = (ruleset*)tree;
790
+ if (rulesetTree->storeMessageCallback) {
791
+ unsigned char actionType = ACTION_ASSERT_FACT;
792
+ if (messageType == MESSAGE_TYPE_EVENT) {
793
+ actionType = ACTION_ASSERT_EVENT;
794
+ }
795
+
796
+ return rulesetTree->storeMessageCallback(rulesetTree->storeMessageCallbackContext,
797
+ &rulesetTree->stringPool[rulesetTree->nameOffset],
798
+ state->sid,
799
+ mid,
800
+ actionType,
801
+ message->content);
802
+ }
803
+
804
+ return RULES_OK;
766
805
  }
767
806
 
768
- unsigned int ensureStateNode(void *tree,
769
- char *sid,
770
- unsigned char *isNew,
771
- stateNode **state) {
807
+ unsigned int getStateNode(void *tree,
808
+ char *sid,
809
+ stateNode **state) {
772
810
  unsigned int sidHash = fnv1Hash32(sid, strlen(sid));
773
811
  unsigned int nodeOffset;
774
812
  ruleset *rulesetTree = (ruleset*)tree;
@@ -779,102 +817,144 @@ unsigned int ensureStateNode(void *tree,
779
817
  ((ruleset*)tree)->statePool,
780
818
  sidHash,
781
819
  nodeOffset);
820
+ if (nodeOffset == UNDEFINED_HASH_OFFSET) {
821
+ return ERR_SID_NOT_FOUND;
822
+ }
782
823
 
783
- if (nodeOffset != UNDEFINED_HASH_OFFSET) {
784
- *isNew = 0;
785
- *state = STATE_NODE(tree, nodeOffset);
786
- } else {
787
- *isNew = 1;
788
- NEW(stateNode,
789
- rulesetTree->statePool,
790
- nodeOffset);
791
-
792
- SET(stateNode,
793
- rulesetTree->stateIndex,
794
- MAX_STATE_INDEX_LENGTH,
795
- rulesetTree->statePool,
796
- sidHash,
797
- nodeOffset);
798
-
799
- if (rulesetTree->statePool.count > MAX_STATE_INDEX_LENGTH) {
800
- return ERR_OUT_OF_MEMORY;
801
- }
802
- rulesetTree->reverseStateIndex[rulesetTree->statePool.count - 1] = nodeOffset;
803
- stateNode *node = STATE_NODE(tree, nodeOffset);
804
- node->offset = nodeOffset;
824
+ *state = STATE_NODE(tree, nodeOffset);
825
+ return RULES_OK;
826
+ }
805
827
 
806
- int sidLength = sizeof(char) * (strlen(sid) + 1);
807
- node->sid = malloc(sidLength);
808
- if (!node->sid) {
809
- return ERR_OUT_OF_MEMORY;
810
- }
811
- memcpy(node->sid, sid, sidLength);
828
+ unsigned int createStateNode(void *tree,
829
+ char *sid,
830
+ stateNode **state) {
831
+ unsigned int sidHash = fnv1Hash32(sid, strlen(sid));
832
+ unsigned int nodeOffset;
833
+ ruleset *rulesetTree = (ruleset*)tree;
834
+
835
+ NEW(stateNode,
836
+ rulesetTree->statePool,
837
+ nodeOffset);
812
838
 
813
- INIT(messageNode,
814
- node->messagePool,
815
- MAX_MESSAGE_NODES);
839
+ SET(stateNode,
840
+ rulesetTree->stateIndex,
841
+ MAX_STATE_INDEX_LENGTH,
842
+ rulesetTree->statePool,
843
+ sidHash,
844
+ nodeOffset);
816
845
 
817
- memset(node->messageIndex, 0, MAX_MESSAGE_INDEX_LENGTH * sizeof(unsigned int) * 2);
846
+ if (rulesetTree->statePool.count > MAX_STATE_INDEX_LENGTH) {
847
+ return ERR_OUT_OF_MEMORY;
848
+ }
849
+ rulesetTree->reverseStateIndex[rulesetTree->statePool.count - 1] = nodeOffset;
850
+ stateNode *node = STATE_NODE(tree, nodeOffset);
851
+ node->offset = nodeOffset;
852
+
853
+ int sidLength = sizeof(char) * (strlen(sid) + 1);
854
+ node->sid = malloc(sidLength);
855
+ if (!node->sid) {
856
+ return ERR_OUT_OF_MEMORY;
857
+ }
858
+ memcpy(node->sid, sid, sidLength);
859
+
860
+ INIT(messageNode,
861
+ node->messagePool,
862
+ MAX_MESSAGE_NODES);
863
+
864
+ memset(node->messageIndex, 0, MAX_MESSAGE_INDEX_LENGTH * sizeof(unsigned int) * 2);
865
+
866
+ node->betaState = malloc(((ruleset*)tree)->betaCount * sizeof(betaStateNode));
867
+ for (unsigned int i = 0; i < ((ruleset*)tree)->betaCount; ++i) {
868
+ betaStateNode *betaNode = &node->betaState[i];
869
+ betaNode->reteNode = NULL;
870
+
871
+ INIT(leftFrameNode,
872
+ betaNode->leftFramePool,
873
+ MAX_LEFT_FRAME_NODES);
874
+
875
+ memset(betaNode->leftFrameIndex, 0, MAX_LEFT_FRAME_INDEX_LENGTH * sizeof(unsigned int) * 2);
818
876
 
819
- node->betaState = malloc(((ruleset*)tree)->betaCount * sizeof(betaStateNode));
820
- for (unsigned int i = 0; i < ((ruleset*)tree)->betaCount; ++i) {
821
- betaStateNode *betaNode = &node->betaState[i];
822
- betaNode->reteNode = NULL;
823
-
824
- INIT(leftFrameNode,
825
- betaNode->leftFramePool,
826
- MAX_LEFT_FRAME_NODES);
827
-
828
- memset(betaNode->leftFrameIndex, 0, MAX_LEFT_FRAME_INDEX_LENGTH * sizeof(unsigned int) * 2);
829
-
830
- INIT(rightFrameNode,
831
- betaNode->rightFramePool,
832
- MAX_RIGHT_FRAME_NODES);
833
-
834
- memset(betaNode->rightFrameIndex, 0, MAX_RIGHT_FRAME_INDEX_LENGTH * sizeof(unsigned int) * 2);
835
- }
877
+ INIT(rightFrameNode,
878
+ betaNode->rightFramePool,
879
+ MAX_RIGHT_FRAME_NODES);
836
880
 
837
- node->connectorState = malloc(((ruleset*)tree)->connectorCount * sizeof(connectorStateNode));
838
- for (unsigned int i = 0; i < ((ruleset*)tree)->connectorCount; ++i) {
839
- connectorStateNode *connectorNode = &node->connectorState[i];
840
- connectorNode->reteNode = NULL;
881
+ memset(betaNode->rightFrameIndex, 0, MAX_RIGHT_FRAME_INDEX_LENGTH * sizeof(unsigned int) * 2);
882
+ }
841
883
 
842
- INIT(leftFrameNode,
843
- connectorNode->aFramePool,
844
- MAX_LEFT_FRAME_NODES);
845
-
846
- connectorNode->aFrameIndex[0] = UNDEFINED_HASH_OFFSET;
847
- connectorNode->aFrameIndex[1] = UNDEFINED_HASH_OFFSET;
884
+ node->connectorState = malloc(((ruleset*)tree)->connectorCount * sizeof(connectorStateNode));
885
+ for (unsigned int i = 0; i < ((ruleset*)tree)->connectorCount; ++i) {
886
+ connectorStateNode *connectorNode = &node->connectorState[i];
887
+ connectorNode->reteNode = NULL;
848
888
 
849
- INIT(leftFrameNode,
850
- connectorNode->bFramePool,
851
- MAX_LEFT_FRAME_NODES);
889
+ INIT(leftFrameNode,
890
+ connectorNode->aFramePool,
891
+ MAX_LEFT_FRAME_NODES);
852
892
 
853
- connectorNode->bFrameIndex[0] = UNDEFINED_HASH_OFFSET;
854
- connectorNode->bFrameIndex[1] = UNDEFINED_HASH_OFFSET;
855
- }
893
+ connectorNode->aFrameIndex[0] = UNDEFINED_HASH_OFFSET;
894
+ connectorNode->aFrameIndex[1] = UNDEFINED_HASH_OFFSET;
895
+
896
+ INIT(leftFrameNode,
897
+ connectorNode->bFramePool,
898
+ MAX_LEFT_FRAME_NODES);
856
899
 
857
- node->actionState = malloc(((ruleset*)tree)->actionCount * sizeof(actionStateNode));
858
- for (unsigned int i = 0; i < ((ruleset*)tree)->actionCount; ++i) {
859
- actionStateNode *actionNode = &node->actionState[i];
860
- actionNode->reteNode = NULL;
861
-
862
- actionNode->resultIndex[0] = UNDEFINED_HASH_OFFSET;
863
- actionNode->resultIndex[1] = UNDEFINED_HASH_OFFSET;
864
-
865
- INIT(leftFrameNode,
866
- actionNode->resultPool,
867
- MAX_LEFT_FRAME_NODES);
868
- }
869
-
870
- node->factOffset = UNDEFINED_HASH_OFFSET;
871
- node->lockExpireTime = 0;
872
- *state = node;
900
+ connectorNode->bFrameIndex[0] = UNDEFINED_HASH_OFFSET;
901
+ connectorNode->bFrameIndex[1] = UNDEFINED_HASH_OFFSET;
873
902
  }
903
+
904
+ node->actionState = malloc(((ruleset*)tree)->actionCount * sizeof(actionStateNode));
905
+ for (unsigned int i = 0; i < ((ruleset*)tree)->actionCount; ++i) {
906
+ actionStateNode *actionNode = &node->actionState[i];
907
+ actionNode->reteNode = NULL;
908
+
909
+ actionNode->resultIndex[0] = UNDEFINED_HASH_OFFSET;
910
+ actionNode->resultIndex[1] = UNDEFINED_HASH_OFFSET;
911
+
912
+ INIT(leftFrameNode,
913
+ actionNode->resultPool,
914
+ MAX_LEFT_FRAME_NODES);
915
+ }
916
+
917
+ node->factOffset = UNDEFINED_HASH_OFFSET;
918
+ node->lockExpireTime = 0;
919
+ *state = node;
874
920
 
875
921
  return RULES_OK;
876
922
  }
877
923
 
924
+ unsigned int deleteStateNode(void *tree,
925
+ stateNode *node) {
926
+ ruleset *rulesetTree = (ruleset*)tree;
927
+ free(node->sid);
928
+
929
+ for (unsigned int i = 0; i < rulesetTree->betaCount; ++i) {
930
+ betaStateNode *betaNode = &node->betaState[i];
931
+ free(betaNode->leftFramePool.content);
932
+ free(betaNode->rightFramePool.content);
933
+ }
934
+ free(node->betaState);
935
+
936
+ for (unsigned int i = 0; i < rulesetTree->connectorCount; ++i) {
937
+ connectorStateNode *connectorNode = &node->connectorState[i];
938
+ free(connectorNode->aFramePool.content);
939
+ free(connectorNode->bFramePool.content);
940
+ }
941
+ free(node->connectorState);
942
+
943
+ for (unsigned int i = 0; i < rulesetTree->actionCount; ++i) {
944
+ actionStateNode *actionNode = &node->actionState[i];
945
+ free(actionNode->resultPool.content);
946
+ }
947
+ free(node->actionState);
948
+
949
+ DELETE(stateNode,
950
+ rulesetTree->stateIndex,
951
+ MAX_STATE_INDEX_LENGTH,
952
+ rulesetTree->statePool,
953
+ node->offset);
954
+
955
+ return RULES_OK;
956
+ }
957
+
878
958
  static unsigned int getResultFrameLength(ruleset *tree,
879
959
  stateNode *state,
880
960
  leftFrameNode *frame) {
@@ -1466,6 +1546,8 @@ unsigned int getState(unsigned int handle, char *sid, char **state) {
1466
1546
  return serializeState(node, state);
1467
1547
  }
1468
1548
 
1549
+
1550
+
1469
1551
  unsigned int deleteState(unsigned int handle, char *sid) {
1470
1552
  ruleset *tree;
1471
1553
  RESOLVE_HANDLE(handle, &tree);
@@ -1488,33 +1570,5 @@ unsigned int deleteState(unsigned int handle, char *sid) {
1488
1570
  }
1489
1571
 
1490
1572
  stateNode *node = STATE_NODE(tree, nodeOffset);
1491
- free(node->sid);
1492
-
1493
- for (unsigned int i = 0; i < ((ruleset*)tree)->betaCount; ++i) {
1494
- betaStateNode *betaNode = &node->betaState[i];
1495
- free(betaNode->leftFramePool.content);
1496
- free(betaNode->rightFramePool.content);
1497
- }
1498
- free(node->betaState);
1499
-
1500
- for (unsigned int i = 0; i < ((ruleset*)tree)->connectorCount; ++i) {
1501
- connectorStateNode *connectorNode = &node->connectorState[i];
1502
- free(connectorNode->aFramePool.content);
1503
- free(connectorNode->bFramePool.content);
1504
- }
1505
- free(node->connectorState);
1506
-
1507
- for (unsigned int i = 0; i < ((ruleset*)tree)->actionCount; ++i) {
1508
- actionStateNode *actionNode = &node->actionState[i];
1509
- free(actionNode->resultPool.content);
1510
- }
1511
- free(node->actionState);
1512
-
1513
- DELETE(stateNode,
1514
- tree->stateIndex,
1515
- MAX_STATE_INDEX_LENGTH,
1516
- tree->statePool,
1517
- nodeOffset);
1518
-
1519
- return RULES_OK;
1573
+ return deleteStateNode(tree, node);
1520
1574
  }
data/src/rules/state.h CHANGED
@@ -10,6 +10,11 @@
10
10
  #define MESSAGE_TYPE_EVENT 0
11
11
  #define MESSAGE_TYPE_FACT 1
12
12
 
13
+ #define ACTION_ASSERT_FACT 1
14
+ #define ACTION_ASSERT_EVENT 2
15
+ #define ACTION_RETRACT_FACT 3
16
+ #define ACTION_UPDATE_STATE 4
17
+
13
18
  #define UNDEFINED_HASH_OFFSET 0
14
19
  #define MAX_OBJECT_PROPERTIES 32
15
20
  #define MAX_MESSAGE_FRAMES 16
@@ -307,24 +312,33 @@ unsigned int createActionFrame(stateNode *state,
307
312
  leftFrameNode **newNode,
308
313
  frameLocation *newLocation);
309
314
 
310
- unsigned int deleteMessage(stateNode *state,
315
+ unsigned int deleteMessage(void *tree,
316
+ stateNode *state,
317
+ char *mid,
311
318
  unsigned int messageNodeOffset);
312
319
 
313
320
  unsigned int getMessage(stateNode *state,
314
321
  char *mid,
315
322
  unsigned int *valueOffset);
316
323
 
317
- unsigned int storeMessage(stateNode *state,
324
+ unsigned int storeMessage(void *tree,
325
+ stateNode *state,
318
326
  char *mid,
319
327
  jsonObject *message,
320
328
  unsigned char messageType,
321
329
  unsigned int *valueOffset);
322
330
 
323
- unsigned int ensureStateNode(void *tree,
331
+ unsigned int getStateNode(void *tree,
332
+ char *sid,
333
+ stateNode **state);
334
+
335
+ unsigned int createStateNode(void *tree,
324
336
  char *sid,
325
- unsigned char *isNew,
326
337
  stateNode **state);
327
338
 
339
+ unsigned int deleteStateNode(void *tree,
340
+ stateNode *state);
341
+
328
342
  unsigned int serializeResult(void *tree,
329
343
  stateNode *state,
330
344
  actionStateNode *actionNode,
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: 2.0.5
4
+ version: 2.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jesus Ruiz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-21 00:00:00.000000000 Z
11
+ date: 2019-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake