-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow running multiple isolated instances of gaia_db_server #661
Conversation
… all the relevant server settings
…into rondelli-db-server-sessions
…into rondelli-db-server-sessions
…xecutor and type_regoistry thread_local
…into rondelli-db-server-sessions
…into rondelli-db-server-sessions
std::vector<const char*> command = get_server_command(); | ||
|
||
// TODO this should be wrapped into a if_debug_enabled() | ||
std::string command_str; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like Hungarian, except str
is a suffix instead of a prefix.
This is very trivial code, functionally, but the naming makes it very mysterious. What exactly is being done here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this meant to be something like:
get_server_command
-> get_server_command_line_arguments
command
-> command_line_arguments
part
-> command_line_argument
command_str
-> command_line
or just command
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot call it get_server_command_line_arguments
because it is not just the arguments, but also the command itself. As mentioned in the comment above, I could change to: create_server_stratup_command
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could call it get_server_command_and_arguments
then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a big fan of the and
within method names, fine this time.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) | ||
if (-1 == ::execve(command[0], const_cast<char**>(command.data()), nullptr)) | ||
{ | ||
ASSERT_UNREACHABLE(fmt::format("Failed to execute '{}'", m_conf.server_exec_path.c_str())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Punctuation missing in the message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again I think this is an abuse of asserts. You should not just turn any fatal error into an assert. There could be any number of reasons why execve()
might fail, unrelated to any logical programming error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What you should be doing here is just using the existing facility throw_system_error()
to automatically extract errno
and its associated system description. There are many examples of this in the DB code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to system_error.
} | ||
} | ||
|
||
gaia_log::sys().debug("Server instance {} started with pid:{}", instance_name(), m_server_pid); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd punctuate log messages too, but if this hasn't been done yet, it's probably best left for a separate cleanup change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to come up with guidelines for logging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They were supposed to be the same as for messages as far as punctuation and capitalization was concerned.
Note that one value is preceded by a colon and the other not - the use of colons should be consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added punctuation and colon to each message
|
||
gaia::db::begin_session(session_opts); | ||
} | ||
catch (gaia::common::system_error& ex) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weren't we going with just e
for exceptions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
// I don't know if this is by design or a bug. | ||
// @chuan to review (if it is a bug I will file a JIRA) | ||
std::unique_lock lock(m_gaia_parser_lock); | ||
schema_loader_t::instance().load_schema("addr_book.ddl"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess @chuan didn't expect to have to load metadata multiple times. This is another reason not to allow clients to access different servers. Our assumption has always been that we deal with 1 server, 1 metadata, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The real problem here, I think, is that a layered design was rejected early on, so now everything (predictably) depends on everything else. Logically, the low-level client API shouldn't depend on anything but the corresponding low-level DB feature set ("dbcore"). In that case, there would be no issue with allowing different sessions in the same process to connect to different servers. The existence of process-global data here is the problem, not the introduction of multiple server instances. Any client state which depends on server state should have session scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The existence of process-global data here is the problem, not the introduction of multiple server instances.
The existence of the process-global data is due to the assumption that we only need to care about a single server instance. Obviously, changing that assumption now is a problem. We cannot come and say - "changing the assumption is not a problem, we should not have made it in the first place". We made it and nobody pushed back.
This also has nothing to do with the layered design issues. That is an orthogonal problem. Having a layered design is not incompatible with making the assumption that we work with a single server instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point I was trying to make is that a layered design would have avoided this because the session API would be oblivious to the higher-level features (e.g. the catalog) that are now entangled with the client's process-global state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"assumption that we only need to care about a single server instance" I think this assumption was a bad assumption to begin with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am confused. gaia parser which is just a wrapper around flex/bison generated parser is thread-safe. Executing DDLs in parallel is not multi-thread safe in the sense DDLs do not support txns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the comment to:
// TODO The gaia parser does not support running
// multiple DDL from different threads.
Note that this test is likely to be disabled after the meetings we will have tomorrow about DB sessions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you mean DDL executor. Parser is just a string parsing library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the parser itself that fails, not the DDL executor.
{ | ||
gaia_log::initialize({}); | ||
|
||
s_server_instance = server_instance_t{}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a difference between this line and this one:
s_server_instance = server_instance_t();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case (no arguments) there is no difference. I always use braces for consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see the value of braces at declaration time, but in code it seems confusing to use them when not necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Finally completed my pass through the entire PR.
My main concern is about introducing the ability for a client to connect to different server instances. I don't think we should support that.
Other than that, the comments I made are just fit&finish type of stuff.
@@ -146,6 +146,7 @@ endif() | |||
# Rocksdb. | |||
add_subdirectory(${ROCKSDB} rocksdb EXCLUDE_FROM_ALL) | |||
# Flatbuffers. | |||
set(FLATBUFFERS_BUILD_TESTS OFF) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So that we don't build flatbuffers tests, saving a little bit of build time.
@@ -13,6 +13,7 @@ | |||
#include <thread> | |||
|
|||
#include <flatbuffers/flatbuffers.h> | |||
#include <spdlog/fmt/fmt.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are going to use fmt, we should use an independent version instead of the embedded or bundled version in spdlog.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, this is a temporary work-around. Created a follow-up task: https://gaiaplatform.atlassian.net/browse/GAIAPLAT-938
…into rondelli-db-server-sessions
@senderista @LaurentiuCristofor @chuan It was not necessary to customize the reading of the configuration file.What we have is an internal APi that allows setting the default
When the user call:
That being said, I till intend to make the session_name configurable via Environment variable and also the configuration file modifiable at runtime, in a different PR though. |
Reverting change request after meeting.
// All rights reserved. | ||
///////////////////////////////////////////// | ||
|
||
#include "gaia_internal/db/db_server_instance.hpp" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this and db_server_instance.cpp be moved under test since they look like test helper utility?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you're right, there are other things that should be grouped under a "test" section. I created a jira task for it:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple trivial comments, I don't have time to do a proper review and I trust the general approach.
} | ||
server_instance_config_t server_conf = server_instance_config_t::get_default(); | ||
server_conf.instance_name = instance_name; | ||
server_conf.server_exec_path = string(path_to_db_server) + "/" + string(c_db_server_exec_name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you normalize this with std::filesystem::path
? I want to make this robust since this is user-supplied data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
if (!fs::exists(db_exec_path)) | ||
{ | ||
throw common::gaia_exception("Impossible to find the database server path"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Database server path does not exist."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
This change introduces the possibility of running multiple instances of gaia_db_server in complete isolation. Each instance has its own name which is used to create the socket and shm names. Whoever needs to connect to the gaia_db_server (client code, gaiac, gaiat, etc..) has to specify the instance name they want to connect to. If nothing is provided a default instance name is used.
The tests now run each into their own instance of gaia_db_server. The instance name is "randomly" generated at startup.
db
This is only exposed for testing ATM. It could be used beyond that.
catalog
common
gaiac
gaiat
Cmake
Tests