From ff893d64194d5d8e8cea386b28028927a89cbb02 Mon Sep 17 00:00:00 2001
From: Igor Kuznetsov <i.kuznetsov@picodata.io>
Date: Mon, 7 Nov 2022 07:22:54 +0000
Subject: [PATCH] feat: appended updating `sql_cache_size` parameter

---
 sbroad-cartridge/Makefile                     |  2 +-
 sbroad-cartridge/src/cartridge/storage.rs     | 19 ++++++
 sbroad-cartridge/test_app/test/helper.lua     | 64 +++++++++++++++---
 .../test/integration/broken_cache_test.lua    | 67 +++++++++++++++++++
 4 files changed, 142 insertions(+), 10 deletions(-)
 create mode 100644 sbroad-cartridge/test_app/test/integration/broken_cache_test.lua

diff --git a/sbroad-cartridge/Makefile b/sbroad-cartridge/Makefile
index be383e7375..347d7c567f 100644
--- a/sbroad-cartridge/Makefile
+++ b/sbroad-cartridge/Makefile
@@ -40,5 +40,5 @@ install_release:
 	cp -Rf $(CORE_MODULE)/src/*.lua $(LUADIR)/$(PROJECT_NAME)
 	cp -Rf $(CARTRIDGE_MODULE)/cartridge $(LUADIR)
 
-test_integration: 
+test_integration:
 	$(MAKE) build_integration && $(MAKE) run_integration
diff --git a/sbroad-cartridge/src/cartridge/storage.rs b/sbroad-cartridge/src/cartridge/storage.rs
index 841be62b40..1cd4a680fa 100644
--- a/sbroad-cartridge/src/cartridge/storage.rs
+++ b/sbroad-cartridge/src/cartridge/storage.rs
@@ -9,6 +9,7 @@ use sbroad::{debug, error, warn};
 use sbroad_proc::otm_child_span;
 use std::any::Any;
 use std::cell::RefCell;
+use std::fmt::Display;
 use tarantool::tlua::LuaFunction;
 use tarantool::tuple::Tuple;
 
@@ -141,6 +142,7 @@ impl Configuration for StorageRuntime {
 
     fn update_config(&mut self, metadata: Self::Configuration) {
         self.metadata = metadata;
+        update_box_param("sql_cache_size", self.metadata.storage_size_bytes);
     }
 }
 
@@ -335,3 +337,20 @@ fn write_unprepared(stmt: &str, params: &[Value]) -> Result<Box<dyn Any>, QueryP
         }
     }
 }
+
+fn update_box_param<T>(param: &str, val: T)
+where
+    T: Display,
+{
+    let lua = tarantool::lua_state();
+    match lua.exec(&format!("box.cfg{{{} = {}}}", param, val)) {
+        Ok(_) => debug!(
+            Option::from("update_box_param"),
+            &format!("box.cfg param {} was updated to {}", param, val)
+        ),
+        Err(e) => warn!(
+            Option::from("update_box_param"),
+            &format!("box.cfg update error: {}", e)
+        ),
+    }
+}
diff --git a/sbroad-cartridge/test_app/test/helper.lua b/sbroad-cartridge/test_app/test/helper.lua
index 14725904ab..aa826c6bc9 100644
--- a/sbroad-cartridge/test_app/test/helper.lua
+++ b/sbroad-cartridge/test_app/test/helper.lua
@@ -87,6 +87,55 @@ local config = {
   ["storage_cache_size_bytes"] = 204800,
   ["schema"] = {
     spaces = {
+        space_for_breake_cache = {
+          format = {
+              { name = "id", type = "integer", is_nullable = false },
+              { name = "field1", type = "number", is_nullable = false },
+              { name = "field2", type = "number", is_nullable = false },
+              { name = "field3", type = "string", is_nullable = false },
+              { name = "field4", type = "boolean", is_nullable = false },
+              { name = "field5", type = "integer", is_nullable = false },
+              { name = "field6", type = "integer", is_nullable = false },
+              { name = "field7", type = "integer", is_nullable = false },
+              { name = "field8", type = "integer", is_nullable = false },
+              { name = "field9", type = "integer", is_nullable = false },
+              { name = "field10", type = "string", is_nullable = false },
+              { name = "field11", type = "string", is_nullable = false },
+              { name = "field12", type = "integer", is_nullable = false },
+              { name = "field13", type = "number", is_nullable = false },
+              { name = "bucket_id", type = "unsigned", is_nullable = true },
+          },
+          temporary = false,
+          engine = "vinyl",
+          indexes = {
+              {
+                  unique = true,
+                  parts = {
+                      {
+                          path = "id",
+                          type = "integer",
+                          is_nullable = false,
+                      },
+                  },
+                  type = "TREE",
+                  name = "id",
+              },
+              {
+                  unique = false,
+                  parts = {
+                      {
+                          path = "bucket_id",
+                          type = "unsigned",
+                          is_nullable = true,
+                      },
+                  },
+                  type = "TREE",
+                  name = "bucket_id",
+              },
+          },
+          is_local = false,
+          sharding_key = { "id" },
+      },
       t = {
         format = {
             {
@@ -1397,30 +1446,27 @@ helper.start_test_cluster = function (cfg)
             server_command = helper.server_command,
             datadir = helper.datadir,
             use_vshard = true,
+            cookie='123',
             replicasets = {
                 {
                     alias = "api",
                     uuid = cartridge_helpers.uuid('a'),
                     roles = {'app.roles.api'},
-                    servers = {
-                        { instance_uuid = cartridge_helpers.uuid('a', 1) }
-                    },
+                    servers = 1,
                 },
                 {
                     alias = "storage-1",
                     uuid = cartridge_helpers.uuid("b"),
                     roles = { "app.roles.storage" },
-                    servers = {
-                        { instance_uuid = cartridge_helpers.uuid("b", 1) }
-                    },
+                    all_rw = false,
+                    servers = 2,
+                    weight = 1
                 },
                 {
                     alias = "storage-2",
                     uuid = cartridge_helpers.uuid("c"),
                     roles = { "app.roles.storage" },
-                    servers = {
-                        { instance_uuid = cartridge_helpers.uuid("c", 1) }
-                    },
+                    servers = 1,
                 }
             }
     })
diff --git a/sbroad-cartridge/test_app/test/integration/broken_cache_test.lua b/sbroad-cartridge/test_app/test/integration/broken_cache_test.lua
new file mode 100644
index 0000000000..63101d347e
--- /dev/null
+++ b/sbroad-cartridge/test_app/test/integration/broken_cache_test.lua
@@ -0,0 +1,67 @@
+local t = require('luatest')
+local g = t.group('broken_cache')
+
+local helper = require('test.helper')
+local cluster = nil
+
+g.before_all(
+        function()
+            cluster = helper.cluster
+
+            local storage1 = cluster:server("storage-1-1").net_box
+            storage1:call("box.execute", { [[truncate table "space_for_breake_cache"]] })
+
+            local storage2 = cluster:server("storage-2-1").net_box
+            storage2:call("box.execute", { [[truncate table "space_for_breake_cache"]] })
+        end
+)
+
+g.after_all(
+        function()
+            local storage1 = cluster:server("storage-1-1").net_box
+            storage1:call("box.execute", { [[truncate table "space_for_breake_cache"]] })
+
+            local storage2 = cluster:server("storage-2-1").net_box
+            storage2:call("box.execute", { [[truncate table "space_for_breake_cache"]] })
+        end
+)
+
+g.test_change_cache_by_config_replica = function()
+    local api = cluster:server("api-1").net_box
+    local storage11 = cluster:server("storage-1-1").net_box
+    local storage12 = cluster:server("storage-1-2").net_box
+    local storage2 = cluster:server("storage-2-1").net_box
+
+    -- config will be applied by sbroad after the first query is executed
+    local _, err = api:call("sbroad.execute", { [[SELECT * FROM "space_for_breake_cache"]], {} })
+    t.assert_equals(err, nil)
+
+    local c = cluster:download_config()
+    local cache_before_config = c["storage_cache_size_bytes"]
+    t.assert_equals(204800, cache_before_config)
+
+    -- here we check that storage-1-1 is master and that its config isn't updated
+    t.assert_equals(false, storage11:eval("return box.info.ro"))
+
+    -- config was not applied on the master because the first query was 'select' and it was run on the replica
+    t.assert_not_equals(cache_before_config, storage11:eval("return box.cfg.sql_cache_size"))
+    -- but on the replica cache params must be updated
+    t.assert_equals(cache_before_config, storage12:eval("return box.cfg.sql_cache_size"))
+    t.assert_equals(cache_before_config, storage2:eval("return box.cfg.sql_cache_size"))
+
+    local cache_after_config = 4239361
+    c["storage_cache_size_bytes"] = cache_after_config
+    cluster:upload_config(c)
+
+    -- config will be applied by sbroad on the replica after the first query is executed
+    _, err = api:call("sbroad.execute", { [[SELECT * FROM "space_for_breake_cache"]], {} })
+    t.assert_equals(err, nil)
+
+    t.assert_equals(false, storage11:eval("return box.info.ro"))
+
+    -- on the master config was not applied, because select query was ran on the replica
+    t.assert_not_equals(cache_after_config, storage11:eval("return box.cfg.sql_cache_size"))
+    -- but on the replica cache params must be updated
+    t.assert_equals(cache_after_config, storage12:eval("return box.cfg.sql_cache_size"))
+    t.assert_equals(cache_after_config, storage2:eval("return box.cfg.sql_cache_size"))
+end
-- 
GitLab