aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgrunfink <grunfink@comam.es>2025-09-12 21:48:34 +0200
committergrunfink <grunfink@comam.es>2025-09-12 21:48:34 +0200
commit08f99232e0854529bfd6f74d22d56fd4c8cc4cb5 (patch)
tree9f3fd3815f4642e34a5b79d9d3f85215919122b4
parent74e021cbb7c204c8141825a9e82065c45dba26e1 (diff)
New function instance_failure().
-rw-r--r--activitypub.c11
-rw-r--r--data.c53
-rw-r--r--snac.h2
3 files changed, 66 insertions, 0 deletions
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,