topo: remember REQUEST_TABLE for not-yet-created groups, fulfill on create
При REQUEST_TABLE для ещё не созданной группы (CHAT-канал не загружен) пир дропал запрос, и проситель навсегда не узнавал таблицу — односторонняя видимость (звонок android→linux падал «peer offline»). Теперь запрос запоминается в pending_table_reqs[32] и выполняется при создании группы (topo_group_fulfill_table_reqs → handle_request_table). Попутно: test_chat_join_e2e — критерий успеха через CHAT_EVT_CONNECT_RESULT (JOIN_READY) вместо senders_list; doxygen-комментарии в etcp_api.h.
This commit is contained in:
1 parent
8bfb456161
commit
6d3ad965ee
5 files changed
+221
-19
No files matched your search
+19
-16
@@ -17,6 +17,7 @@
|
||||
#include "invite_link.h"
|
||||
#include "invite_build.h"
|
||||
#include "member_sync.h"
|
||||
#include "chat_event.h"
|
||||
#include "../routing_layer/topo_node_sqlite.h"
|
||||
#include "../routing_layer/topo_group.h"
|
||||
#include "../routing_layer/topo_node.h"
|
||||
@@ -235,21 +236,22 @@ static int wait_file(struct UTUN_INSTANCE* inst, const char* path, int max_iter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* J получил JOIN_READY: cs_handle_join_ready вызвал topo_group_new_conn → senders_list непуст */
|
||||
static int wait_group_started(struct UTUN_INSTANCE* inst, int max_iter) {
|
||||
uint64_t gid = strtoull(g_sh.ch_id, NULL, 10);
|
||||
for (int a = 0; a < max_iter; a++) {
|
||||
struct TOPO_GROUP* g = topo_groups_find(inst->topo_groups, gid);
|
||||
if (g && g->senders_list && g->senders_list->head) return 1;
|
||||
uasync_poll(inst->ua, POLL_MS);
|
||||
/* JOIN_READY (успех join) наблюдается через CHAT_EVT_CONNECT_RESULT(result=0):
|
||||
* сигнал точный (в отличие от senders_list, заполняемого и ncd-подключением)
|
||||
* и не зависит от того, успел ли connection-узел остаться в живых до синка мембера. */
|
||||
static int g_j_join_ok = 0;
|
||||
|
||||
static void join_event_handler(struct UTUN_INSTANCE* inst, int type, const uint8_t* data, int len) {
|
||||
(void)inst;
|
||||
if (type == CHAT_EVT_CONNECT_RESULT && len >= 12) {
|
||||
int r = 0; memcpy(&r, data + 8, 4);
|
||||
if (r == 0) g_j_join_ok = 1;
|
||||
}
|
||||
{
|
||||
struct TOPO_GROUP* g = topo_groups_find(inst->topo_groups, gid);
|
||||
fprintf(stderr, " [join-ready-fail] self=0x%016llx group=%p senders_head=%p\n",
|
||||
(unsigned long long)inst->node_id, (void*)g,
|
||||
(void*)(g && g->senders_list ? g->senders_list->head : NULL));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wait_join_result(struct UTUN_INSTANCE* inst, int max_iter) {
|
||||
for (int a = 0; a < max_iter && !g_j_join_ok; a++) uasync_poll(inst->ua, POLL_MS);
|
||||
return g_j_join_ok;
|
||||
}
|
||||
|
||||
/* ── настройка канала и мемберов ── */
|
||||
@@ -291,6 +293,7 @@ static int child_main(const char* role, const char* dir, int invalid_key) {
|
||||
struct UTUN_INSTANCE* inst = utun_instance_create(ua, cfg);
|
||||
if (!inst) { fprintf(stderr, "%s: create failed\n", role); uasync_destroy(ua, 0); return 1; }
|
||||
utun_instance_init(inst);
|
||||
chat_event_set_handler(inst, join_event_handler);
|
||||
|
||||
int rc = 1;
|
||||
uint64_t ch_num = strtoull(g_sh.ch_id, NULL, 10);
|
||||
@@ -397,8 +400,8 @@ static int child_main(const char* role, const char* dir, int invalid_key) {
|
||||
rc = wait_not_member(inst, g_sh.nid[IDX_J], 200) ? 0 : 1;
|
||||
if (rc) fprintf(stderr, "J: unexpectedly became member with wrong key\n");
|
||||
} else {
|
||||
/* критерий J по ТЗ: получил JOIN_READY (topo_group_new_conn → senders_list) */
|
||||
if (!wait_group_started(inst, 8000)) {
|
||||
/* критерий J по ТЗ: получил JOIN_READY (CHAT_EVT_CONNECT_RESULT result=0) */
|
||||
if (!wait_join_result(inst, 8000)) {
|
||||
fprintf(stderr, "J: no JOIN_READY\n"); goto out;
|
||||
}
|
||||
rc = 0;
|
||||
|
||||
Reference in new issue
Block a user