From ad5704f80368dcd994c03e57a455c95dc48396b2 Mon Sep 17 00:00:00 2001
From: John Sully <john@csquare.ca>
Date: Thu, 27 Jun 2024 15:30:26 -0400
Subject: [PATCH] Upstream the availability zone info string from KeyDB (#700)

When Redis/Valkey/KeyDB is run in a cloud environment across multiple
AZ's it is preferable to keep traffic local to an AZ both for cost
reasons and for latency. This is typically done when you are enabling
reads on replicas with the READONLY command.

For this change we are creating a setting that is echo'd back in the
info command. We do not want to add the cloud SDKs as dependencies and
this is the easiest way around that. It is fairly trivial to grab the AZ
from the cloud and push that into your setting file.

Currently at Snapchat we have a custom client that after connecting
reads this from the server and will preferentially use that server if
the AZ string matches its internally configured AZ.

In the future it would be ideal if we used this information when
performing failover or even exposed it in cluster nodes.

Signed-off-by: John Sully <john@csquare.ca>
---
 src/config.c | 1 +
 src/server.c | 3 ++-
 src/server.h | 1 +
 valkey.conf  | 6 ++++++
 4 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/config.c b/src/config.c
index 2a692ac8f..108861325 100644
--- a/src/config.c
+++ b/src/config.c
@@ -3100,6 +3100,7 @@ standardConfig static_configs[] = {
     /* SDS Configs */
     createSDSConfig("primaryauth", "masterauth", MODIFIABLE_CONFIG | SENSITIVE_CONFIG, EMPTY_STRING_IS_NULL, server.primary_auth, NULL, NULL, NULL),
     createSDSConfig("requirepass", NULL, MODIFIABLE_CONFIG | SENSITIVE_CONFIG, EMPTY_STRING_IS_NULL, server.requirepass, NULL, NULL, updateRequirePass),
+    createSDSConfig("availability-zone", NULL, MODIFIABLE_CONFIG, 0, server.availability_zone, "", NULL, NULL),
 
     /* Enum Configs */
     createEnumConfig("supervised", NULL, IMMUTABLE_CONFIG, supervised_mode_enum, server.supervised_mode, SUPERVISED_NONE, NULL, NULL),
diff --git a/src/server.c b/src/server.c
index a8d44a080..ee1bcd088 100644
--- a/src/server.c
+++ b/src/server.c
@@ -5387,7 +5387,8 @@ sds genValkeyInfoString(dict *section_dict, int all_sections, int everything) {
             "lru_clock:%u\r\n", server.lruclock,
             "executable:%s\r\n", server.executable ? server.executable : "",
             "config_file:%s\r\n", server.configfile ? server.configfile : "",
-            "io_threads_active:%i\r\n", server.io_threads_active));
+            "io_threads_active:%i\r\n", server.io_threads_active,
+            "availability_zone:%s\r\n", server.availability_zone));
         /* clang-format on */
 
         /* Conditional properties */
diff --git a/src/server.h b/src/server.h
index bb432c896..90efc6aa9 100644
--- a/src/server.h
+++ b/src/server.h
@@ -2125,6 +2125,7 @@ struct valkeyServer {
                                                 is down, doesn't affect pubsub global. */
     long reply_buffer_peak_reset_time; /* The amount of time (in milliseconds) to wait between reply buffer peak resets */
     int reply_buffer_resizing_enabled; /* Is reply buffer resizing enabled (1 by default) */
+    sds availability_zone; /* When run in a cloud environment we can configure the availability zone it is running in */
     /* Local environment */
     char *locale_collate;
 };
diff --git a/valkey.conf b/valkey.conf
index 05301d1be..e4ffd0f8a 100644
--- a/valkey.conf
+++ b/valkey.conf
@@ -2319,3 +2319,9 @@ jemalloc-bg-thread yes
 # to suppress
 #
 # ignore-warnings ARM64-COW-BUG
+
+# Inform Valkey of the availability zone if running in a cloud environment.  Currently
+# this is only exposed via the info command for clients to use, but in the future we
+# we may also use this when making decisions for replication.
+#
+# availability-zone "zone-name"
\ No newline at end of file