From 08f99232e0854529bfd6f74d22d56fd4c8cc4cb5 Mon Sep 17 00:00:00 2001 From: grunfink Date: Fri, 12 Sep 2025 21:48:34 +0200 Subject: New function instance_failure(). --- activitypub.c | 11 +++++++++++ data.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ snac.h | 2 ++ 3 files changed, 66 insertions(+) diff --git a/activitypub.c b/activitypub.c index 5fb60ba..ce3be35 100644 --- a/activitypub.c +++ b/activitypub.c @@ -2261,6 +2261,9 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) return -1; } + /* this instance is alive */ + instance_failure(actor, 2); + /* question votes may not have a type */ if (xs_is_null(type)) type = "Note"; @@ -3152,6 +3155,11 @@ void process_queue_item(xs_dict *q_item) return; } + if (instance_failure(inbox, 0)) { + srv_debug(1, xs_fmt("too many failures for instance %s", inbox)); + return; + } + /* deliver (if previous error status was a timeout, try now longer) */ if (p_status == 599) timeout = xs_number_get(xs_dict_get_def(srv_config, "queue_timeout_2", "8")); @@ -3163,6 +3171,9 @@ void process_queue_item(xs_dict *q_item) status = send_to_inbox_raw(keyid, seckey, inbox, msg, &payload, &p_size, timeout); + /* register or clear a value for this instance */ + instance_failure(inbox, valid_status(status) ? 2 : 1); + if (payload) { if (p_size > 64) { /* trim the message */ diff --git a/data.c b/data.c index 1533305..5c72184 100644 --- a/data.c +++ b/data.c @@ -112,6 +112,9 @@ int srv_open(const char *basedir, int auto_upgrade) xs *tmpdir = xs_fmt("%s/tmp", srv_basedir); mkdirx(tmpdir); + xs *faildir = xs_fmt("%s/failure", srv_basedir); + mkdirx(faildir); + #ifdef __APPLE__ /* Apple uses st_atimespec instead of st_atim etc */ #define st_atim st_atimespec @@ -3039,6 +3042,56 @@ xs_list *content_search(snac *user, const char *regex, } +int instance_failure(const char *url, int op) +/* do some checks and accounting on instance failures */ +{ + int ret = 0; + xs *l = xs_split(url, "/"); + const char *hostname = xs_list_get(l, 2); + double mt; + + if (!xs_is_string(hostname)) + return 0; + + xs *md5 = xs_md5_hex(hostname, strlen(hostname)); + xs *fn = xs_fmt("%s/%s", srv_basedir, md5); + + switch (op) { + case 0: /** check **/ + if ((mt = mtime(fn)) != 0.0) { + /* grace time */ + double seconds_failing = 30 * (24 * 60 * 60); + + if ((double)time(NULL) - mt > seconds_failing) + ret = -1; + } + + break; + + case 1: /** register a failure **/ + if (mtime(fn) == 0.0) { + FILE *f; + + /* only create once, as the date will be used */ + if ((f = fopen(fn, "w")) != NULL) { + fprintf(f, "%s\n", hostname); + fclose(f); + } + } + + break; + + case 2: /** clear a failure **/ + /* called whenever a message comes from this instance */ + unlink(fn); + + break; + } + + return ret; +} + + /** notifications **/ xs_str *notify_check_time(snac *snac, int reset) diff --git a/snac.h b/snac.h index e344f46..0027b59 100644 --- a/snac.h +++ b/snac.h @@ -278,6 +278,8 @@ int content_match(const char *file, const xs_dict *msg); xs_list *content_search(snac *user, const char *regex, int priv, int skip, int show, int max_secs, int *timeout); +int instance_failure(const char *url, int op); + void enqueue_input(snac *snac, const xs_dict *msg, const xs_dict *req, int retries); void enqueue_shared_input(const xs_dict *msg, const xs_dict *req, int retries); void enqueue_output_raw(const char *keyid, const char *seckey, -- cgit v1.2.3