[MOD] Move temporary stanza/event mappings

This should increase reliability, as a bad write shouldn't affect the
MUC mappings directoy (which I've _seen_ happen.)
This commit is contained in:
LDA 2024-08-02 14:11:23 +02:00
commit 3c5b9aac82
3 changed files with 60 additions and 120 deletions

View file

@ -370,15 +370,17 @@ ParseeEventHandler(ParseeData *data, HashMap *event)
{
char *event_type, *event_id, *room_id, *sender;
char *parsee = ParseeMXID(data);
if (!data || !event)
event_id = GrabString(event, 1, "event_id");
event_type = GrabString(event, 1, "type");
room_id = GrabString(event, 1, "room_id");
sender = GrabString(event, 1, "sender");
if (!data || !event || ParseeIsPuppet(data->config, sender))
{
Free(parsee);
return;
}
event_type = GrabString(event, 1, "type");
event_id = GrabString(event, 1, "event_id");
room_id = GrabString(event, 1, "room_id");
sender = GrabString(event, 1, "sender");
ParseePushHeadTable(room_id, event_id);
if (StrEquals(event_type, "m.room.member"))

View file

@ -68,45 +68,46 @@ ParseeCleanup(void *datp)
uint64_t ts = UtilTsMillis();
Log(LOG_NOTICE, "Cleaning up...");
chats = DbList(data->db, 1, "chats");
for (i = 0; i < ArraySize(chats); i++)
{
DbRef *ref;
HashMap *json, *stanzas, *events, *ids;
char *stanza, *event, *id;
JsonValue *val;
Array *to_delete;
size_t j;
chat = ArrayGet(chats, i);
ref = DbLock(data->db, 2, "chats", chat);
json = DbJson(ref);
#define CleanupField(field, timeout, threshold) do \
{ \
Array *field##_list = DbList(data->db, 3, "chats", chat, #field"s"); \
size_t cleaned = 0; \
field##s = JsonValueAsObject(HashMapGet(json, #field"s")); \
to_delete = ArrayCreate(); \
while (HashMapIterate(field##s, &field, (void **) &val)) \
for (j = 0; j < ArraySize(field##_list); j++) \
{ \
HashMap *obj = JsonValueAsObject(val); \
char *f = ArrayGet(field##_list, j); \
ref = DbLock(data->db, 4, "chats", chat, #field"s", f); \
HashMap *obj = DbJson(ref); \
uint64_t age = JsonValueAsInteger(HashMapGet(obj, "age")); \
uint64_t dur = ts - age; \
\
if ((dur > (timeout))) \
{ \
ArrayAdd(to_delete, StrDuplicate(field)); \
ArrayAdd(to_delete, StrDuplicate(f)); \
cleaned++; \
} \
DbUnlock(data->db, ref); \
} \
DbListFree(field##_list); \
\
for (j = 0; j < ArraySize(to_delete); j++) \
{ \
field = ArrayGet(to_delete, j); \
if (cleaned > threshold) \
{ \
JsonValueFree(HashMapDelete(field##s, field)); \
DbDelete(data->db, 4, "chats", chat, #field"s", field); \
} \
Free(field); \
} \
@ -117,8 +118,7 @@ ParseeCleanup(void *datp)
CleanupField(stanza, 30 MINUTES, 50);
CleanupField(event, 30 MINUTES, 50);
CleanupField(id, 30 MINUTES, 50);
DbUnlock(data->db, ref);
#undef CleanupField
}
DbListFree(chats);
/* TODO */
@ -499,76 +499,56 @@ ParseePushStanza(ParseeData *data, char *chat_id, char *stanza_id, char *id, cha
{
DbRef *ref;
HashMap *j;
HashMap *stanzas, *obj, *events, *ids;
bool new_stanzas = false, new_events = false;
bool new_ids = false;
uint64_t age = UtilTsMillis();
if (!data || !chat_id || !stanza_id || !ev || !sender)
{
return;
}
ref = DbLock(data->db, 2, "chats", chat_id);
j = DbJson(ref);
if (!ref)
/* TODO */
{
return;
ref = DbCreate(data->db, 4, "chats", chat_id, "stanzas", stanza_id);
j = DbJson(ref);
if (!ref)
{
return;
}
HashMapSet(j, "age", JsonValueInteger(age));
HashMapSet(j, "event", JsonValueString(ev));
DbUnlock(data->db, ref);
}
stanzas = JsonValueAsObject(HashMapGet(j, "stanzas"));
if (!stanzas)
{
stanzas = HashMapCreate();
new_stanzas = true;
}
ref = DbCreate(data->db, 4, "chats", chat_id, "events", ev);
j = DbJson(ref);
if (!ref)
{
return;
}
obj = HashMapCreate();
HashMapSet(obj, "age", JsonValueInteger(age));
HashMapSet(obj, "event", JsonValueString(ev));
JsonValueFree(HashMapSet(stanzas, stanza_id, JsonValueObject(obj)));
if (new_stanzas)
{
HashMapSet(j, "stanzas", JsonValueObject(stanzas));
}
events = JsonValueAsObject(HashMapGet(j, "events"));
if (!events)
{
events = HashMapCreate();
new_events = true;
}
obj = HashMapCreate();
HashMapSet(obj, "stanza", JsonValueString(stanza_id));
HashMapSet(obj, "origin", JsonValueString(id));
HashMapSet(obj, "sender", JsonValueString(sender));
HashMapSet(obj, "age", JsonValueInteger(age));
JsonValueFree(HashMapSet(events, ev, JsonValueObject(obj)));
if (new_events)
{
HashMapSet(j, "events", JsonValueObject(events));
HashMapSet(j, "event", JsonValueString(ev));
HashMapSet(j, "stanza", JsonValueString(stanza_id));
HashMapSet(j, "origin", JsonValueString(id));
HashMapSet(j, "sender", JsonValueString(sender));
HashMapSet(j, "age", JsonValueInteger(age));
DbUnlock(data->db, ref);
}
if (id)
{
ids = JsonValueAsObject(HashMapGet(j, "ids"));
if (!ids)
ref = DbCreate(data->db, 4, "chats", chat_id, "ids", id);
j = DbJson(ref);
if (!ref)
{
ids = HashMapCreate();
new_ids = true;
}
obj = HashMapCreate();
HashMapSet(obj, "stanza", JsonValueString(stanza_id));
HashMapSet(obj, "event", JsonValueString(ev));
HashMapSet(obj, "sender", JsonValueString(sender));
HashMapSet(obj, "age", JsonValueInteger(age));
JsonValueFree(HashMapSet(ids, id, JsonValueObject(obj)));
if (new_ids)
{
HashMapSet(j, "ids", JsonValueObject(ids));
return;
}
HashMapSet(j, "stanza", JsonValueString(stanza_id));
HashMapSet(j, "event", JsonValueString(ev));
HashMapSet(j, "sender", JsonValueString(sender));
HashMapSet(j, "age", JsonValueInteger(age));
DbUnlock(data->db, ref);
}
DbUnlock(data->db, ref);
}
bool
@ -605,29 +585,15 @@ bool
ParseeVerifyStanza(ParseeData *data, char *chat_id, char *stanza_id)
{
DbRef *ref = NULL;
HashMap *j = NULL;
HashMap *stanzas = NULL;
bool ret = true;
if (!data || !chat_id || !stanza_id)
{
return true;
}
ref = DbLock(data->db, 2, "chats", chat_id);
j = DbJson(ref);
if (!ref)
{
goto end;
}
ref = DbLock(data->db, 4, "chats", chat_id, "stanzas", stanza_id);
ret = !ref;
stanzas = JsonValueAsObject(HashMapGet(j, "stanzas"));
if (!stanzas)
{
goto end;
}
ret = !HashMapGet(stanzas, stanza_id);
end:
DbUnlock(data->db, ref);
return ret;
}
@ -636,27 +602,20 @@ ParseeEventFromID(ParseeData *data, char *chat_id, char *id)
{
DbRef *ref = NULL;
HashMap *j = NULL;
HashMap *ids = NULL;
char *ret = NULL;
if (!data || !chat_id || !id)
{
return NULL;
}
ref = DbLock(data->db, 2, "chats", chat_id);
ref = DbLock(data->db, 4, "chats", chat_id, "ids", id);
j = DbJson(ref);
if (!ref)
{
goto end;
}
ids = JsonValueAsObject(HashMapGet(j, "ids"));
if (!ids)
{
goto end;
}
ret = JsonValueAsString(JsonGet(ids, 2, id, "event"));
ret = JsonValueAsString(JsonGet(j, 1, "event"));
ret = StrDuplicate(ret);
end:
DbUnlock(data->db, ref);
@ -699,27 +658,20 @@ ParseeEventFromSID(ParseeData *data, char *chat_id, char *id)
{
DbRef *ref = NULL;
HashMap *j = NULL;
HashMap *ids = NULL;
char *ret = NULL;
if (!data || !chat_id || !id)
{
return NULL;
}
ref = DbLock(data->db, 2, "chats", chat_id);
ref = DbLock(data->db, 4, "chats", chat_id, "stanzas", id);
j = DbJson(ref);
if (!ref)
{
goto end;
}
ids = JsonValueAsObject(HashMapGet(j, "stanzas"));
if (!ids)
{
goto end;
}
ret = JsonValueAsString(JsonGet(ids, 2, id, "event"));
ret = JsonValueAsString(JsonGet(j, 1, "event"));
ret = StrDuplicate(ret);
end:
DbUnlock(data->db, ref);

View file

@ -583,28 +583,21 @@ ParseeGetStanzaInfo(ParseeData *data, char *chat_id, char *ev, char **st, char *
{
DbRef *ref = NULL;
HashMap *j = NULL;
HashMap *event = NULL;
bool ret = false;
if (!data || !chat_id || !ev || !st || !se)
{
return false;
}
ref = DbLock(data->db, 2, "chats", chat_id);
ref = DbLock(data->db, 4, "chats", chat_id, "events", ev);
j = DbJson(ref);
if (!ref)
{
goto end;
}
event = JsonValueAsObject(JsonGet(j, 2, "events", ev));
if (!event)
{
goto end;
}
*st = StrDuplicate(JsonValueAsString(HashMapGet(event, "stanza")));
*se = StrDuplicate(JsonValueAsString(HashMapGet(event, "sender")));
*st = StrDuplicate(JsonValueAsString(HashMapGet(j, "stanza")));
*se = StrDuplicate(JsonValueAsString(HashMapGet(j, "sender")));
ret = true;
end:
DbUnlock(data->db, ref);
@ -647,27 +640,20 @@ ParseeGetOrigin(ParseeData *data, char *chat_id, char *ev, char **o)
{
DbRef *ref = NULL;
HashMap *j = NULL;
HashMap *event = NULL;
bool ret = false;
if (!data || !chat_id || !ev || !o)
{
return false;
}
ref = DbLock(data->db, 2, "chats", chat_id);
ref = DbLock(data->db, 4, "chats", chat_id, "events", ev);
j = DbJson(ref);
if (!ref)
{
goto end;
}
event = JsonValueAsObject(JsonGet(j, 2, "events", ev));
if (!event)
{
goto end;
}
*o = StrDuplicate(JsonValueAsString(HashMapGet(event, "origin")));
*o = StrDuplicate(JsonValueAsString(HashMapGet(j, "origin")));
ret = true;
end:
DbUnlock(data->db, ref);