From 605752e5c646a8094b52ffe93770dafc4344c197 Mon Sep 17 00:00:00 2001
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Date: Tue, 28 May 2024 23:01:22 +0200
Subject: [PATCH] relay: move gc subscriber creation out of it

GC consumer creation and destroy seemed to only happen in box.cc
with one exception in relay_subscribe(). Lets move it out for
consistency. Now relay can only notify GC consumers, but can't
manage them.

That also makes it harder to misuse the GC by passing some wrong
vclock to it, similar to what was happening in #10047.

In scope of #10047

NO_TEST=refactoring
NO_CHANGELOG=refactoring
NO_DOC=refactoring

(cherry picked from commit 4dc0c1ea06c485d5f0b14358d90e0d90e8d45711)
---
 src/box/box.cc   | 20 ++++++++++++++++++++
 src/box/relay.cc | 21 ---------------------
 2 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/src/box/box.cc b/src/box/box.cc
index 67dd4d6c3a..dd66285a45 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -4268,6 +4268,26 @@ box_process_subscribe(struct iostream *io, const struct xrow_header *header)
 	}
 	struct vclock start_vclock;
 	box_localize_vclock(&req.vclock, &start_vclock);
+	/*
+	 * Register the replica with the garbage collector.
+	 * In case some of the replica's WAL files were deleted, it might
+	 * subscribe with a smaller vclock than the master remembers, so
+	 * recreate the gc consumer unconditionally to make sure it holds
+	 * the correct vclock.
+	 */
+	if (!replica->anon) {
+		bool had_gc = false;
+		if (replica->gc != NULL) {
+			gc_consumer_unregister(replica->gc);
+			had_gc = true;
+		}
+		replica->gc = gc_consumer_register(&start_vclock, "replica %s",
+						   tt_uuid_str(&replica->uuid));
+		if (replica->gc == NULL)
+			diag_raise();
+		if (!had_gc)
+			gc_delay_unref();
+	}
 	/*
 	 * Send a response to SUBSCRIBE request, tell
 	 * the replica how many rows we have in stock for it,
diff --git a/src/box/relay.cc b/src/box/relay.cc
index 21a84d537e..d25e4ce439 100644
--- a/src/box/relay.cc
+++ b/src/box/relay.cc
@@ -1115,27 +1115,6 @@ relay_subscribe(struct replica *replica, struct iostream *io, uint64_t sync,
 	assert(replica->anon || replica->id != REPLICA_ID_NIL);
 	struct relay *relay = replica->relay;
 	assert(relay->state != RELAY_FOLLOW);
-	/*
-	 * Register the replica with the garbage collector.
-	 * In case some of the replica's WAL files were deleted, it might
-	 * subscribe with a smaller vclock than the master remembers, so
-	 * recreate the gc consumer unconditionally to make sure it holds
-	 * the correct vclock.
-	 */
-	if (!replica->anon) {
-		bool had_gc = false;
-		if (replica->gc != NULL) {
-			gc_consumer_unregister(replica->gc);
-			had_gc = true;
-		}
-		replica->gc = gc_consumer_register(replica_clock, "replica %s",
-						   tt_uuid_str(&replica->uuid));
-		if (replica->gc == NULL)
-			diag_raise();
-		if (!had_gc)
-			gc_delay_unref();
-	}
-
 	if (replica_version_id < version_id(2, 6, 0) || replica->anon)
 		sent_raft_term = UINT64_MAX;
 	relay_start(relay, io, sync, relay_process_row,
-- 
GitLab