You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pegasus.apache.org by la...@apache.org on 2022/06/08 08:29:45 UTC

[incubator-pegasus] branch master updated: feat(update_replication_factor#10): support to get/set the replication factor of each table by shell (#914)

This is an automated email from the ASF dual-hosted git repository.

laiyingchun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pegasus.git


The following commit(s) were added to refs/heads/master by this push:
     new 8d09f485 feat(update_replication_factor#10): support to get/set the replication factor of each table by shell (#914)
8d09f485 is described below

commit 8d09f4855f65ed047b1165a6f7c7183bff6303f3
Author: Dan Wang <em...@126.com>
AuthorDate: Wed Jun 8 16:29:40 2022 +0800

    feat(update_replication_factor#10): support to get/set the replication factor of each table by shell (#914)
---
 rdsn                                    |   2 +-
 src/shell/command_utils.cpp             |  31 ++++++++++
 src/shell/command_utils.h               |   2 +
 src/shell/commands.h                    |   4 ++
 src/shell/commands/table_management.cpp | 105 ++++++++++++++++++++++++++++++++
 src/shell/main.cpp                      |  12 ++++
 6 files changed, 155 insertions(+), 1 deletion(-)

diff --git a/rdsn b/rdsn
index 608c3cef..61e3890b 160000
--- a/rdsn
+++ b/rdsn
@@ -1 +1 @@
-Subproject commit 608c3cef86b8789ef728781470bff45b9bad3a09
+Subproject commit 61e3890ba1e1f37b6a326daaa7fa4ea3f383d9a8
diff --git a/src/shell/command_utils.cpp b/src/shell/command_utils.cpp
index 733d01fd..39d19768 100644
--- a/src/shell/command_utils.cpp
+++ b/src/shell/command_utils.cpp
@@ -45,3 +45,34 @@ bool validate_ip(shell_context *sc,
     err_info = fmt::format("invalid ip:port={}, can't find it in the cluster", ip_str);
     return false;
 }
+
+bool confirm_unsafe_command(const std::string &action)
+{
+    const int max_attempts = 5;
+    for (int attempts = 0; attempts < max_attempts; ++attempts) {
+        fmt::print(stdout,
+                   "PLEASE be CAUTIOUS with this operation ! "
+                   "Are you sure to {} ? [y/n]: ",
+                   action);
+
+        int choice = fgetc(stdin);
+        int len = 0;
+        for (int c = choice; c != '\n' && c != EOF; ++len) {
+            c = fgetc(stdin);
+        }
+        if (len != 1) {
+            continue;
+        }
+
+        if (choice == 'y') {
+            fmt::print(stdout, "you've chosen YES, we will continue ...\n");
+            return true;
+        } else if (choice == 'n') {
+            fmt::print(stdout, "you've chosen NO, we will stop !\n");
+            return false;
+        }
+    }
+
+    fmt::print(stdout, "too many failed attempts, we will stop !\n");
+    return false;
+}
diff --git a/src/shell/command_utils.h b/src/shell/command_utils.h
index 3393de0a..92482f4d 100644
--- a/src/shell/command_utils.h
+++ b/src/shell/command_utils.h
@@ -105,3 +105,5 @@ EnumType type_from_string(const std::map<int, const char *> &type_maps,
     }
     return default_type;
 }
+
+bool confirm_unsafe_command(const std::string &action);
diff --git a/src/shell/commands.h b/src/shell/commands.h
index f1bb9ee8..09ea4898 100644
--- a/src/shell/commands.h
+++ b/src/shell/commands.h
@@ -153,6 +153,10 @@ bool del_app_envs(command_executor *e, shell_context *sc, arguments args);
 
 bool clear_app_envs(command_executor *e, shell_context *sc, arguments args);
 
+bool get_max_replica_count(command_executor *e, shell_context *sc, arguments args);
+
+bool set_max_replica_count(command_executor *e, shell_context *sc, arguments args);
+
 // == data operations (see 'commands/data_operations.cpp') == //
 
 bool data_operations(command_executor *e, shell_context *sc, arguments args);
diff --git a/src/shell/commands/table_management.cpp b/src/shell/commands/table_management.cpp
index 299e29ff..8ee84393 100644
--- a/src/shell/commands/table_management.cpp
+++ b/src/shell/commands/table_management.cpp
@@ -19,6 +19,8 @@
 
 #include "shell/commands.h"
 
+#include <dsn/utility/ports.h>
+
 double convert_to_ratio(double hit, double total)
 {
     return std::abs(total) < 1e-6 ? 0 : hit / total;
@@ -886,3 +888,106 @@ bool clear_app_envs(command_executor *e, shell_context *sc, arguments args)
     }
     return true;
 }
+
+bool get_max_replica_count(command_executor *e, shell_context *sc, arguments args)
+{
+    static struct option long_options[] = {{"json", no_argument, 0, 'j'}, {0, 0, 0, 0}};
+
+    if (args.argc < 2) {
+        return false;
+    }
+
+    std::string app_name(args.argv[1]);
+
+    bool json = false;
+    optind = 0;
+    while (true) {
+        int option_index = 0;
+        int c = getopt_long(args.argc, args.argv, "j", long_options, &option_index);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+        case 'j':
+            json = true;
+            break;
+        default:
+            return false;
+        }
+    }
+
+    auto err_resp = sc->ddl_client->get_max_replica_count(app_name);
+    auto err = err_resp.get_error();
+    const auto &resp = err_resp.get_value();
+
+    if (err.is_ok()) {
+        err = dsn::error_s::make(resp.err);
+    }
+
+    std::string escaped_app_name(pegasus::utils::c_escape_string(app_name));
+    if (!err.is_ok()) {
+        fmt::print(stderr, "get replica count of app({}) failed: {}\n", escaped_app_name, err);
+        return true;
+    }
+
+    dsn::utils::table_printer tp("max_replica_count");
+    tp.add_row_name_and_data("max_replica_count", resp.max_replica_count);
+    tp.output(std::cout, json ? tp_output_format::kJsonPretty : tp_output_format::kTabular);
+
+    return true;
+}
+
+bool set_max_replica_count(command_executor *e, shell_context *sc, arguments args)
+{
+    if (args.argc < 3) {
+        return false;
+    }
+
+    int new_max_replica_count;
+    if (!dsn::buf2int32(args.argv[2], new_max_replica_count)) {
+        fmt::print(stderr, "parse '{}' as replica count failed\n", args.argv[2]);
+        return false;
+    }
+
+    if (new_max_replica_count < 1) {
+        fmt::print(stderr, "replica count should be >= 1\n");
+        return false;
+    }
+
+    std::string app_name(args.argv[1]);
+    std::string escaped_app_name(pegasus::utils::c_escape_string(app_name));
+    std::string action(fmt::format(
+        "set the replica count of app({}) to {}", escaped_app_name, new_max_replica_count));
+    if (!confirm_unsafe_command(action)) {
+        return true;
+    }
+
+    auto err_resp = sc->ddl_client->set_max_replica_count(app_name, new_max_replica_count);
+    auto err = err_resp.get_error();
+    const auto &resp = err_resp.get_value();
+
+    if (dsn_likely(err.is_ok())) {
+        err = dsn::error_s::make(resp.err);
+    }
+
+    if (err.is_ok()) {
+        fmt::print(stdout,
+                   "set replica count of app({}) from {} to {}: {}\n",
+                   escaped_app_name,
+                   resp.old_max_replica_count,
+                   new_max_replica_count,
+                   resp.hint_message.empty() ? "success" : resp.hint_message);
+    } else {
+        std::string error_message(resp.err.to_string());
+        if (!resp.hint_message.empty()) {
+            error_message += ", ";
+            error_message += resp.hint_message;
+        }
+
+        fmt::print(
+            stderr, "set replica count of app({}) failed: {}\n", escaped_app_name, error_message);
+    }
+
+    return true;
+}
diff --git a/src/shell/main.cpp b/src/shell/main.cpp
index 0f152675..0f2a3bd4 100644
--- a/src/shell/main.cpp
+++ b/src/shell/main.cpp
@@ -496,6 +496,18 @@ static command_executor commands[] = {
         "<-d|--address str>",
         detect_hotkey,
     },
+    {
+        "get_replica_count",
+        "get the max replica count of an app",
+        "<app_name> [-j|--json]",
+        get_max_replica_count,
+    },
+    {
+        "set_replica_count",
+        "set the max replica count of an app",
+        "<app_name> <replica_count>",
+        set_max_replica_count,
+    },
     {
         "exit", "exit shell", "", exit_shell,
     },


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pegasus.apache.org
For additional commands, e-mail: commits-help@pegasus.apache.org