diff --git a/core/legion.c b/core/legion.c index 877c9368..436981de 100644 --- a/core/legion.c +++ b/core/legion.c @@ -79,6 +79,9 @@ void uwsgi_parse_legion(char *key, uint16_t keylen, char *value, uint16_t vallen ul->scroll = value; ul->scroll_len = vallen; } + else if (!uwsgi_strncmp(key, keylen, "dead", 4)) { + ul->dead = 1; + } } // this function is called when a node is added or removed (heavy locking is needed) @@ -611,6 +614,14 @@ static void *legion_loop(void *foobar) { usl = usl->next; } } + // remove node announcing death + else if (ul->dead) { + uwsgi_log("[uwsgi-legion] %s: %.*s valor: %llu uuid: %.*s announced its death to Legion %s\n", node->valor > 0 ? "node" : "arbiter", node->name_len, node->name, node->valor, 36, node->uuid, ul->legion); + uwsgi_wlock(ul->lock); + uwsgi_legion_remove_node(ul, node); + uwsgi_rwunlock(ul->lock); + continue; + } node->last_seen = uwsgi_now(); node->lord_valor = legion_msg.lord_valor; @@ -752,8 +763,11 @@ int uwsgi_legion_announce(struct uwsgi_legion *ul) { if (uwsgi_buffer_append_keyval(ub, "scroll", 6, ul->scroll, ul->scroll_len)) goto err; } -#ifdef UWSGI_UUID -#endif + + if (ul->dead) { + if (uwsgi_buffer_append_keyval(ub, "dead", 1, "1", 1)) + goto err; + } unsigned char *encrypted = uwsgi_malloc(ub->pos + 4 + EVP_MAX_BLOCK_LENGTH); if (EVP_EncryptInit_ex(ul->encrypt_ctx, NULL, NULL, NULL, NULL) <= 0) { @@ -1140,6 +1154,13 @@ next: legion = legion->next; } + legion = uwsgi.legions; + while (legion) { + legion->dead = 1; + uwsgi_legion_announce(legion); + legion = legion->next; + } + } int uwsgi_legion_i_am_the_lord(char *name) { diff --git a/uwsgi.h b/uwsgi.h index a0e0abde..f17a46dc 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -609,6 +609,8 @@ struct uwsgi_legion { int quorum; int changed; + // if set the next packet will be a death-announce + int dead; // set to 1 first time when quorum is reached int joined;