From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 70CC92AE16 for ; Wed, 27 Mar 2019 15:28:42 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NXr_0JUhp_20 for ; Wed, 27 Mar 2019 15:28:42 -0400 (EDT) Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id B0EED2AE09 for ; Wed, 27 Mar 2019 15:28:41 -0400 (EDT) Subject: [tarantool-patches] [PATCH 7/6] swim: make swim_upsert_member returning two values From: Vladislav Shpilevoy References: Message-ID: <1a730742-0560-21da-d089-9d5b278532e4@tarantool.org> Date: Wed, 27 Mar 2019 22:28:38 +0300 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: tarantool-patches@freelists.org Cc: kostja@tarantool.org Here is one new patch. It appeared to be usefull both for the failure detection and for the dissemination. ================================================================ swim_upsert_member is a function to add new members or update existing ones using info received from other cluster participants. At this moment it is quite simple and straightforward: either create a new member and return it, or update an existing member and return it. But things are going to change in failure detection and dissemination components. A couple of examples showing that a member should be returned separately from success/error status: * To prevent undead members the failure detection forbids to add dead members. Otherwise a dead member would be added and removed back and forth by different components infinitely. Upsert for such members should return NULL, but it is not an error - it is a normal function of the protocol; * When the dissemination component receives a UUID update of an existing member, but with too old incarnation, it does not apply that update. And can not return that member from upsert because of UUID being different from the one in the 'request'. In such a case it should be ok to return NULL, but do not deem it an error. Part of #3234 --- diff --git a/src/lib/swim/swim.c b/src/lib/swim/swim.c index df34ce247..1b623fc27 100644 --- a/src/lib/swim/swim.c +++ b/src/lib/swim/swim.c @@ -657,22 +657,32 @@ swim_update_member_addr(struct swim *swim, struct swim_member *member, /** * Update or create a member by its definition, received from a * remote instance. - * @retval NULL Error. - * @retval New member, or updated old member. + * @param swim SWIM instance to upsert into. + * @param def Member definition to build a new member or update an + * existing one. + * @param[out] result A result member: a new, or an updated, or + * NULL in case of nothing has changed. For example, @a def + * was too old. + * + * @retval 0 Success. Member is added, or updated. Or nothing has + * changed but not always it is an error. + * @retval -1 Error. */ -static struct swim_member * -swim_upsert_member(struct swim *swim, const struct swim_member_def *def) +static int +swim_upsert_member(struct swim *swim, const struct swim_member_def *def, + struct swim_member **result) { struct swim_member *member = swim_find_member(swim, &def->uuid); if (member == NULL) { - member = swim_new_member(swim, &def->addr, &def->uuid, - def->status); - return member; + *result = swim_new_member(swim, &def->addr, &def->uuid, + def->status); + return *result != NULL ? 0 : -1; } struct swim_member *self = swim->self; if (member != self) swim_update_member_addr(swim, member, &def->addr); - return member; + *result = member; + return 0; } /** Decode an anti-entropy message, update member table. */ @@ -686,9 +696,10 @@ swim_process_anti_entropy(struct swim *swim, const char **pos, const char *end) return -1; for (uint64_t i = 0; i < size; ++i) { struct swim_member_def def; + struct swim_member *member; if (swim_member_def_decode(&def, pos, end, prefix) != 0) return -1; - if (swim_upsert_member(swim, &def) == NULL) { + if (swim_upsert_member(swim, &def, &member) != 0) { /* * Not a critical error. Other members * still can be updated.