[tarantool-patches] [PATCH 5/5] swim: speed-up empty payloads cluster bootstrap

Vladislav Shpilevoy v.shpilevoy at tarantool.org
Thu Jul 4 02:28:34 MSK 2019


One another place consuming most of the tests start up time is
useless dissemination of an empty payload, which can be skipped
in fact.

Consider a cluster of 300 nodes. Each one of them are
interconnected manually, and now a test wants to wait for a
stabilization, when there are no events. On such a cluster it
happens for ~200 round steps till there are no any single event.

This is not about big packets, or log() TTD. There may be a few
events, may be more, but when a test wants the cluster to be
clean, it needs to wait for all the events being done.

This patch abuses the fact, that empty payloads can be compared
for free, no any single memcmp. If both new and the old payload
are empty, then nothing to disseminate.

It could help in a real cluster too, if initially there are no
payloads.

Needed for #4253
---
 src/lib/swim/swim.c | 13 ++++++++++++-
 test/unit/swim.c    | 19 ++++++-------------
 2 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/src/lib/swim/swim.c b/src/lib/swim/swim.c
index e9f99015c..eda255e6f 100644
--- a/src/lib/swim/swim.c
+++ b/src/lib/swim/swim.c
@@ -728,9 +728,20 @@ swim_update_member_payload(struct swim *swim, struct swim_member *member,
 			return -1;
 		}
 		memcpy(new_payload, payload, payload_size);
-	} else {
+	} else if (member->payload_size > 0) {
 		free(member->payload);
 		new_payload = NULL;
+	} else {
+		/*
+		 * A special free-to-check case. Both new and old
+		 * payloads are empty usually at a cluster
+		 * startup. Skip of that useless event frees one
+		 * slot in UDP packets for something more
+		 * meaningful, and speeds up the tests.
+		 */
+		assert(member->payload_size == 0 && payload_size == 0);
+		member->is_payload_up_to_date = true;
+		return 0;
 	}
 	member->payload = new_payload;
 	member->payload_size = payload_size;
diff --git a/test/unit/swim.c b/test/unit/swim.c
index 263816c0c..1371e7d26 100644
--- a/test/unit/swim.c
+++ b/test/unit/swim.c
@@ -866,7 +866,7 @@ swim_cluster_delete_f(va_list ap)
 static void
 swim_test_triggers(void)
 {
-	swim_start_test(23);
+	swim_start_test(20);
 	struct swim_cluster *cluster = swim_cluster_new(2);
 	swim_cluster_set_ack_timeout(cluster, 1);
 	struct trigger_ctx tctx, tctx2;
@@ -891,16 +891,9 @@ swim_test_triggers(void)
 	   "ctx.member is set");
 	is(tctx.ctx.events, SWIM_EV_NEW, "ctx.events is set");
 
-	swim_run_for(1);
-	swim_cluster_run_triggers(cluster);
-	is(tctx.counter, 2, "payload is delivered, trigger caught that");
-	is(tctx.ctx.member, swim_cluster_member_view(cluster, 0, 1),
-	   "S1 got S2' payload");
-	is(tctx.ctx.events, SWIM_EV_NEW_PAYLOAD, "mask says that");
-
 	swim_cluster_member_set_payload(cluster, 0, "123", 3);
 	swim_cluster_run_triggers(cluster);
-	is(tctx.counter, 3, "self payload is updated");
+	is(tctx.counter, 2, "self payload is updated");
 	is(tctx.ctx.member, swim_self(s1), "self is set as a member");
 	is(tctx.ctx.events, SWIM_EV_NEW_PAYLOAD | SWIM_EV_NEW_VERSION,
 	   "both version and payload events are presented");
@@ -909,18 +902,18 @@ swim_test_triggers(void)
 	fail_if(swim_cluster_wait_status(cluster, 0, 1,
 					 MEMBER_SUSPECTED, 3) != 0);
 	swim_cluster_run_triggers(cluster);
-	is(tctx.counter, 4, "suspicion fired a trigger");
+	is(tctx.counter, 3, "suspicion fired a trigger");
 	is(tctx.ctx.events, SWIM_EV_NEW_STATUS, "status suspected");
 
 	fail_if(swim_cluster_wait_status(cluster, 0, 1, MEMBER_DEAD, 3) != 0);
 	swim_cluster_run_triggers(cluster);
-	is(tctx.counter, 5, "death fired a trigger");
+	is(tctx.counter, 4, "death fired a trigger");
 	is(tctx.ctx.events, SWIM_EV_NEW_STATUS, "status dead");
 
 	fail_if(swim_cluster_wait_status(cluster, 0, 1,
 					 swim_member_status_MAX, 2) != 0);
 	swim_cluster_run_triggers(cluster);
-	is(tctx.counter, 6, "drop fired a trigger");
+	is(tctx.counter, 5, "drop fired a trigger");
 	is(tctx.ctx.events, SWIM_EV_DROP, "status dropped");
 	is(swim_cluster_member_view(cluster, 0, 1), NULL,
 	   "dropped member is not presented in the member table");
@@ -940,7 +933,7 @@ swim_test_triggers(void)
 	swim_cluster_add_link(cluster, 0, 1);
 	swim_cluster_run_triggers(cluster);
 	is(tctx2.counter, 1, "yielding trigger is fired");
-	is(tctx.counter, 6, "non-yielding still is not");
+	is(tctx.counter, 5, "non-yielding still is not");
 
 	struct fiber *async_delete_fiber =
 		fiber_new("async delete", swim_cluster_delete_f);
-- 
2.20.1 (Apple Git-117)





More information about the Tarantool-patches mailing list