Skip to content

Commit 96868ed

Browse files
authored
refactor: remove the unnecessary zookeeper_session_mgr class (apache#2356)
The `zookeeper_session_mgr::get_session(...)` can be made static, so it can be extracted and implemented as a separate global function. Setting the ZooKeeper C client’s log file handle can be done together with the log level, ensuring it is executed only once globally and before any `zhandle_t` object is created. Thus entire `zookeeper_session_mgr` class could be removed. In addition, error info would be printed if the the ZooKeeper C client's log file failed to be opened. Also introduce mutex to support concurrent operations to obtain ZooKeeper sessions by multiple threads.
1 parent 58b8326 commit 96868ed

File tree

7 files changed

+56
-128
lines changed

7 files changed

+56
-128
lines changed

.licenserc.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,8 +668,6 @@ header:
668668
- 'src/zookeeper/zookeeper_error.h'
669669
- 'src/zookeeper/zookeeper_session.cpp'
670670
- 'src/zookeeper/zookeeper_session.h'
671-
- 'src/zookeeper/zookeeper_session_mgr.cpp'
672-
- 'src/zookeeper/zookeeper_session_mgr.h'
673671
# Apache License, Version 2.0, Copyright 2018 Google LLC
674672
- 'src/gutil/test/map_traits_test.cpp'
675673
- 'src/gutil/test/map_util_test.h'

src/meta/meta_state_service_zookeeper.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
#include "utils/utils.h"
4242
#include "zookeeper/zookeeper_error.h"
4343
#include "zookeeper/zookeeper_session.h"
44-
#include "zookeeper/zookeeper_session_mgr.h"
4544

4645
DSN_DECLARE_int32(timeout_ms);
4746

@@ -160,8 +159,7 @@ meta_state_service_zookeeper::~meta_state_service_zookeeper()
160159

161160
error_code meta_state_service_zookeeper::initialize(const std::vector<std::string> &)
162161
{
163-
_session =
164-
zookeeper_session_mgr::instance().get_session(service_app::current_service_app_info());
162+
_session = get_zookeeper_session(service_app::current_service_app_info());
165163
_zoo_state = _session->attach(this,
166164
std::bind(&meta_state_service_zookeeper::on_zoo_session_evt,
167165
ref_this(this),

src/zookeeper/distributed_lock_service_zookeeper.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
#include "utils/strings.h"
4040
#include "zookeeper/lock_struct.h"
4141
#include "zookeeper/lock_types.h"
42-
#include "zookeeper/zookeeper_session_mgr.h"
4342
#include "zookeeper_error.h"
4443
#include "zookeeper_session.h"
4544

@@ -94,8 +93,7 @@ error_code distributed_lock_service_zookeeper::initialize(const std::vector<std:
9493
}
9594
const char *lock_root = args[0].c_str();
9695

97-
_session =
98-
zookeeper_session_mgr::instance().get_session(service_app::current_service_app_info());
96+
_session = get_zookeeper_session(service_app::current_service_app_info());
9997
_zoo_state = _session->attach(this,
10098
std::bind(&distributed_lock_service_zookeeper::on_zoo_session_evt,
10199
lock_srv_ptr(this),

src/zookeeper/zookeeper_session.cpp

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
#include <zookeeper/zookeeper.h>
3232
#include <algorithm>
3333
#include <cerrno>
34+
#include <cstdio>
3435
#include <cstdlib>
36+
#include <mutex>
3537
#include <utility>
3638

3739
#include "rpc/rpc_address.h"
@@ -42,6 +44,7 @@
4244
#include "utils/flags.h"
4345
#include "utils/fmt_logging.h"
4446
#include "utils/safe_strerror_posix.h"
47+
#include "utils/singleton_store.h"
4548
#include "utils/strings.h"
4649
#include "zookeeper/proto.h"
4750
#include "zookeeper/zookeeper.jute.h"
@@ -70,6 +73,7 @@ DSN_DEFINE_int32(zookeeper,
7073
timeout_ms,
7174
30000,
7275
"The timeout of accessing ZooKeeper, in milliseconds");
76+
DSN_DEFINE_string(zookeeper, logfile, "zoo.log", "The path of the log file for ZooKeeper C client");
7377
DSN_DEFINE_string(zookeeper, zoo_log_level, "ZOO_LOG_LEVEL_INFO", "ZooKeeper log level");
7478
DSN_DEFINE_string(zookeeper, hosts_list, "", "ZooKeeper hosts list");
7579
DSN_DEFINE_string(zookeeper, sasl_service_name, "zookeeper", "");
@@ -119,8 +123,7 @@ DSN_DEFINE_group_validator(consistency_between_configurations, [](std::string &m
119123
return true;
120124
});
121125

122-
namespace dsn {
123-
namespace dist {
126+
namespace dsn::dist {
124127

125128
zookeeper_session::zoo_atomic_packet::zoo_atomic_packet(unsigned int size)
126129
{
@@ -274,9 +277,32 @@ bool is_password_file_plaintext()
274277

275278
zhandle_t *create_zookeeper_handle(watcher_fn watcher, void *context)
276279
{
277-
const auto zoo_log_level = enum_from_string(FLAGS_zoo_log_level, INVALID_ZOO_LOG_LEVEL);
278-
CHECK(zoo_log_level != INVALID_ZOO_LOG_LEVEL, "Invalid zoo log level: {}", FLAGS_zoo_log_level);
279-
zoo_set_debug_level(zoo_log_level);
280+
static std::once_flag flag;
281+
std::call_once(flag, []() {
282+
FILE *zoo_log_file = std::fopen(FLAGS_logfile, "a");
283+
if (zoo_log_file == nullptr) {
284+
LOG_ERROR("failed to open the log file for ZooKeeper C Client, use stderr instead: "
285+
"path = {}, error = {}",
286+
FLAGS_logfile,
287+
utils::safe_strerror(errno));
288+
zoo_set_log_stream(stderr);
289+
} else {
290+
// The file handle pointed to by `zoo_log_file` will never be released because:
291+
// 1. Each meta server process holds only one log file handle.
292+
// 2. It cannot be guaranteed that the handle will no longer be used in some
293+
// background thread of ZooKeeper C Client after being released even by atexit(),
294+
// since zhandle_t objects are not closed in the end. Once `fclose` is called on
295+
// the log file handle, any subsequent write operations on it would result in
296+
// undefined behavior.
297+
zoo_set_log_stream(zoo_log_file);
298+
}
299+
300+
const auto zoo_log_level = enum_from_string(FLAGS_zoo_log_level, INVALID_ZOO_LOG_LEVEL);
301+
CHECK(zoo_log_level != INVALID_ZOO_LOG_LEVEL,
302+
"Invalid zoo log level: {}",
303+
FLAGS_zoo_log_level);
304+
zoo_set_debug_level(zoo_log_level);
305+
});
280306

281307
// SASL auth is enabled iff FLAGS_sasl_mechanisms_type is non-empty.
282308
if (dsn::utils::is_empty(FLAGS_sasl_mechanisms_type)) {
@@ -565,5 +591,21 @@ void zookeeper_session::global_void_completion(int rc, const void *data)
565591
release_ref(op_ctx);
566592
}
567593

568-
} // namespace dist
569-
} // namespace dsn
594+
zookeeper_session *get_zookeeper_session(const service_app_info &info)
595+
{
596+
static std::mutex mtx;
597+
auto &store = utils::singleton_store<int, zookeeper_session *>::instance();
598+
599+
zookeeper_session *session{nullptr};
600+
{
601+
std::lock_guard<std::mutex> lock(mtx);
602+
if (!store.get(info.entity_id, session)) {
603+
session = new zookeeper_session(info);
604+
store.put(info.entity_id, session);
605+
}
606+
}
607+
608+
return session;
609+
}
610+
611+
} // namespace dsn::dist

src/zookeeper/zookeeper_session.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,11 @@ class zookeeper_session
205205
DISALLOW_MOVE_AND_ASSIGN(zookeeper_session);
206206
};
207207

208+
// Obtain a ZooKeeper session. Each service node has at most one ZooKeeper session; if none
209+
// exists for the service app, one will be created. The obtained ZooKeeper session can be
210+
// shared across multiple threads in one service node. This function is thread-safe.
211+
zookeeper_session *get_zookeeper_session(const service_app_info &info);
212+
208213
} // namespace dsn::dist
209214

210215
USER_DEFINED_STRUCTURE_FORMATTER(::dsn::dist::zookeeper_session);

src/zookeeper/zookeeper_session_mgr.cpp

Lines changed: 0 additions & 61 deletions
This file was deleted.

src/zookeeper/zookeeper_session_mgr.h

Lines changed: 0 additions & 52 deletions
This file was deleted.

0 commit comments

Comments
 (0)