commit b3c45b010e65a1ba08b6cc64d12bf5e720f2df30
parent 410b228231d29974ddf90329708731a7b50762f6
Author: Jacki <jacki@thejackimonster.de>
Date: Sat, 24 Feb 2024 00:41:09 +0100
Delay automatic requests for messages
Signed-off-by: Jacki <jacki@thejackimonster.de>
Diffstat:
5 files changed, 97 insertions(+), 6 deletions(-)
diff --git a/src/gnunet_chat_context.c b/src/gnunet_chat_context.c
@@ -29,8 +29,10 @@
#include "gnunet_chat_util.h"
#include "gnunet_chat_context_intern.c"
+#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_messenger_service.h>
#include <gnunet/gnunet_namestore_service.h>
+#include <gnunet/gnunet_scheduler_lib.h>
static const unsigned int initial_map_size_of_room = 8;
static const unsigned int initial_map_size_of_contact = 4;
@@ -45,12 +47,16 @@ init_new_context (struct GNUNET_CHAT_Context *context,
context->topic = NULL;
context->deleted = GNUNET_NO;
+ context->request_task = NULL;
+
context->timestamps = GNUNET_CONTAINER_multishortmap_create(
initial_map_size, GNUNET_NO);
context->dependencies = GNUNET_CONTAINER_multihashmap_create(
initial_map_size, GNUNET_NO);
context->messages = GNUNET_CONTAINER_multihashmap_create(
initial_map_size, GNUNET_NO);
+ context->requests = GNUNET_CONTAINER_multihashmap_create(
+ initial_map_size, GNUNET_NO);
context->taggings = GNUNET_CONTAINER_multihashmap_create(
initial_map_size, GNUNET_NO);
context->invites = GNUNET_CONTAINER_multihashmap_create(
@@ -117,6 +123,9 @@ context_destroy (struct GNUNET_CHAT_Context *context)
(context->files)
);
+ if (context->request_task)
+ GNUNET_SCHEDULER_cancel(context->request_task);
+
if (context->query)
GNUNET_NAMESTORE_cancel(context->query);
@@ -142,6 +151,7 @@ context_destroy (struct GNUNET_CHAT_Context *context)
GNUNET_CONTAINER_multishortmap_destroy(context->timestamps);
GNUNET_CONTAINER_multihashmap_destroy(context->dependencies);
GNUNET_CONTAINER_multihashmap_destroy(context->messages);
+ GNUNET_CONTAINER_multihashmap_destroy(context->requests);
GNUNET_CONTAINER_multihashmap_destroy(context->taggings);
GNUNET_CONTAINER_multihashmap_destroy(context->invites);
GNUNET_CONTAINER_multihashmap_destroy(context->files);
@@ -153,6 +163,26 @@ context_destroy (struct GNUNET_CHAT_Context *context)
}
void
+context_request_message (struct GNUNET_CHAT_Context* context,
+ const struct GNUNET_HashCode *hash)
+{
+ GNUNET_assert((context) && (hash));
+
+ if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(context->requests,
+ hash, NULL, GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE))
+ return;
+
+ if (context->request_task)
+ return;
+
+ context->request_task = GNUNET_SCHEDULER_add_with_priority(
+ GNUNET_SCHEDULER_PRIORITY_IDLE,
+ cb_context_request_messages,
+ context
+ );
+}
+
+void
context_update_room (struct GNUNET_CHAT_Context *context,
struct GNUNET_MESSENGER_Room *room)
{
@@ -178,6 +208,7 @@ context_update_room (struct GNUNET_CHAT_Context *context,
initial_map_size_of_room, GNUNET_NO);
GNUNET_CONTAINER_multihashmap_clear(context->messages);
+ GNUNET_CONTAINER_multihashmap_clear(context->requests);
GNUNET_CONTAINER_multihashmap_clear(context->invites);
GNUNET_CONTAINER_multihashmap_clear(context->files);
diff --git a/src/gnunet_chat_context.h b/src/gnunet_chat_context.h
@@ -25,6 +25,7 @@
#ifndef GNUNET_CHAT_CONTEXT_H_
#define GNUNET_CHAT_CONTEXT_H_
+#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_gnsrecord_lib.h>
#include <gnunet/gnunet_messenger_service.h>
#include <gnunet/gnunet_util_lib.h>
@@ -43,9 +44,12 @@ struct GNUNET_CHAT_Context
char *topic;
int deleted;
+ struct GNUNET_SCHEDULER_Task *request_task;
+
struct GNUNET_CONTAINER_MultiShortmap *timestamps;
struct GNUNET_CONTAINER_MultiHashMap *dependencies;
struct GNUNET_CONTAINER_MultiHashMap *messages;
+ struct GNUNET_CONTAINER_MultiHashMap *requests;
struct GNUNET_CONTAINER_MultiHashMap *taggings;
struct GNUNET_CONTAINER_MultiHashMap *invites;
struct GNUNET_CONTAINER_MultiHashMap *files;
@@ -93,6 +97,17 @@ void
context_destroy (struct GNUNET_CHAT_Context* context);
/**
+ * Request a message from a chat <i>context</i> with a
+ * given <i>hash</i>.
+ *
+ * @param[in,out] context Chat context
+ * @param[in] hash Message hash
+ */
+void
+context_request_message (struct GNUNET_CHAT_Context* context,
+ const struct GNUNET_HashCode *hash);
+
+/**
* Updates the connected messenger <i>room</i> of a
* selected chat <i>context</i>.
*
diff --git a/src/gnunet_chat_context_intern.c b/src/gnunet_chat_context_intern.c
@@ -28,6 +28,7 @@
#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_error_codes.h>
+#include <gnunet/gnunet_messenger_service.h>
#define GNUNET_UNUSED __attribute__ ((unused))
@@ -79,6 +80,49 @@ it_destroy_context_invites (GNUNET_UNUSED void *cls,
return GNUNET_YES;
}
+enum GNUNET_GenericReturnValue
+it_iterate_context_requests (void *cls,
+ const struct GNUNET_HashCode *key,
+ GNUNET_UNUSED void *value)
+{
+ struct GNUNET_CHAT_Context *context = cls;
+
+ GNUNET_assert((context) && (context->room) && (key));
+
+ GNUNET_MESSENGER_get_message(context->room, key);
+
+ return GNUNET_YES;
+}
+
+void
+cb_context_request_messages (void *cls)
+{
+ struct GNUNET_CHAT_Context *context = cls;
+
+ GNUNET_assert(context);
+
+ context->request_task = NULL;
+
+ if (!(context->room))
+ {
+ context->request_task = GNUNET_SCHEDULER_add_with_priority(
+ GNUNET_SCHEDULER_PRIORITY_IDLE,
+ cb_context_request_messages,
+ context
+ );
+
+ return;
+ }
+
+ GNUNET_CONTAINER_multihashmap_iterate(
+ context->requests,
+ it_iterate_context_requests,
+ context
+ );
+
+ GNUNET_CONTAINER_multihashmap_clear(context->requests);
+}
+
void
cont_context_write_records (void *cls,
enum GNUNET_ErrorCode ec)
diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h
@@ -25,6 +25,7 @@
#ifndef GNUNET_CHAT_HANDLE_H_
#define GNUNET_CHAT_HANDLE_H_
+#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_arm_service.h>
#include <gnunet/gnunet_fs_service.h>
#include <gnunet/gnunet_gns_service.h>
diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c
@@ -1017,20 +1017,20 @@ on_handle_message (void *cls,
if ((handle->destruction) ||
(GNUNET_OK != handle_request_context_by_room(handle, room)))
return;
+
+ struct GNUNET_CHAT_Context *context = GNUNET_CONTAINER_multihashmap_get(
+ handle->contexts, GNUNET_MESSENGER_room_get_key(room)
+ );
- GNUNET_MESSENGER_get_message(room, &(msg->header.previous));
+ context_request_message(context, &(msg->header.previous));
if (GNUNET_MESSENGER_KIND_MERGE == msg->header.kind)
- GNUNET_MESSENGER_get_message(room, &(msg->body.merge.previous));
+ context_request_message(context, &(msg->body.merge.previous));
if ((GNUNET_CHAT_KIND_UNKNOWN == util_message_kind_from_kind(msg->header.kind)) ||
(GNUNET_OK != intern_provide_contact_for_member(handle, sender, NULL)))
return;
- struct GNUNET_CHAT_Context *context = GNUNET_CONTAINER_multihashmap_get(
- handle->contexts, GNUNET_MESSENGER_room_get_key(room)
- );
-
const struct GNUNET_TIME_Absolute timestamp = GNUNET_TIME_absolute_ntoh(
msg->header.timestamp
);