Skip to content

#1456: Cleaned up and refactored exaudfclient cc#642

Open
sgn4sangar wants to merge 5 commits into
masterfrom
refactoring/1456_cleanup_exaudfclient_cc
Open

#1456: Cleaned up and refactored exaudfclient cc#642
sgn4sangar wants to merge 5 commits into
masterfrom
refactoring/1456_cleanup_exaudfclient_cc

Conversation

@sgn4sangar
Copy link
Copy Markdown
Contributor

relates to #1456

Comment thread exaudfclient/exa_vm_factory.h Outdated
Comment on lines +4 to +22
#ifdef ENABLE_JAVA_VM
#include "javacontainer/javacontainer_builder.h"
#endif //ENABLE_JAVA_VM

#ifdef ENABLE_PYTHON_VM
#include "python/pythoncontainer.h"
#endif //ENABLE_PYTHON_VM

#ifdef UDF_PLUGIN_CLIENT
#include "protegrityclient.h"
#endif //UDF_PLUGIN_CLIENT

#ifdef ENABLE_STREAMING_VM
#include "streaming_container/streamingcontainer.h"
#endif

#ifdef ENABLE_BENCHMARK_VM
#include "benchmark_container/benchmark_container.h"
#endif
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be moved into exaudfclient/exa_vm_factory.cc

Comment thread exaudfclient/exa_lib_loader.cc Outdated
if((error = dlerror()) != nullptr) {
std::stringstream sb;
sb << "Error when trying to load symbol '" << symbol_name << "': " << error;
fprintf(stderr, "dlsym error: %s loading symbol %s\n", error, sb.str().c_str());
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already using streams for constructing sb, so we probably can also use cerr directly and don't need the string stream and the fprintf

Comment thread exaudfclient/exa_lib_loader.cc Outdated

void* handle = dlmopen(LM_ID_NEWLM, stdLibPath.c_str(), RTLD_NOW);
if (!handle) {
fprintf(stderr, "dlmopen error: %s; while loading %s\n", dlerror(), stdLibPath.c_str());
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably could move this also to cerr

Comment thread exaudfclient/exa_set_env.cc Outdated

void setup_environment() {
if (::setenv("HOME", "/tmp", 1) == -1) {
fprintf(stderr, "Failed setting HOME env var: %s\n", std::strerror(errno));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably move this also to cerr

Comment thread exaudfclient/exa_udfclient.cc Outdated
DBGVAR(std::cerr, libexaudflibPath);
void* handle = exa_load_libary(libexaudflibPath);
if (!handle) {
fprintf(stderr, "Failed to load library: %s\n", libexaudflibPath.c_str());
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are already using cerr, so we probably can use it here, too

#endif
}

int main(int argc, char **argv) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good part of the main is also shared between the languages. The main difference will be in the argument and how the VM is created. Maybe we could also extract the remaining logic into a abstract class which provides abstract methods for usage, validate_arguments and create_vm. Validate arguments would store the parsed arguments in private attributes in the subclasses and create_vm would read the arguments from there again. This makes splitting the languages later easier.

#include "exa_lib_loader.h"
#include "utils/debug_message.h"

void* exa_load_libary(const std::string& stdLibPath) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good to have also for the new client later, because there we will need to load libraries into an extra namespace, too.

return handle;
}

void* exa_load_symbol(void *handle, const std::string& symbol_name) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good to have also for the new client later, because there we will need to load libraries into an extra namespace, too.


#include "exa_set_env.h"

void setup_environment() {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good to have also for the new client later, because it will also need to setup the environment. We might actually need to move later even more into this function.

exit(EXIT_FAILURE);
}
std::string libexaudflibPath;
#ifdef CUSTOM_LIBEXAUDFLIB_PATH
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should move the ifdef into its own function, this would make this function easier to read

#include <functional>
#include "exa_vm_factory.h"

std::function<SWIGVMContainers::SWIGVM*()> create_vm(const std::string& argv_lang, bool use_ctpg_options_parser) {
Copy link
Copy Markdown
Collaborator

@tkilias tkilias May 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For split of the languages we need a function for every language that returns the lambda. Maybe we extract a function for each language into a separate file and compose them here again, with the ifdef and argument check.


mb_useCtpgParser = false;
if(argc == 4) {
mb_useCtpgParser = is_use_ctpg_parser(argv[3]);
Copy link
Copy Markdown
Collaborator

@tomuben tomuben May 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This introduces a bug: If there is no fourth CLI parameter, the environment variable SCRIPT_OPTIONS_PARSER_VERSION is never eveluated!


// Parser option 2 means use ctpg parser.
// argv_parser_option is command line argument as it is
bool ExaUdfClientBase::is_use_ctpg_parser(const std::string& argv_parser_option) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_use_ctpg_parser is a strange name. Maybe just use_ctpg_parser?

#endif //ENABLE_PYTHON_VM

void ExaUdfClientPython::usage(const std::string& programName) {
std::cerr << "Usage: " << programName << " <socket> lang=python <scriptOptionsParserVersion=1|2>"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scriptOptionsParserVersion is actually only relevant for Java

Benchmark
};

class ExaUdfClientBase {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense that the base class knows the CLI parameters of each subclass?
Wouldn't it be better if the subclass pass the expected CLI parameters in the constructor to ExaUdfClientBase?
So for example

ExaUdfClientPython::ExaUdfClientPython() : ExaUdfClientBase({"lang=python"})...

?

Copy link
Copy Markdown
Collaborator

@tomuben tomuben May 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or there could be a pure virtual function which returns the list of expected CLI parameters, which each subclass implements.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, each subclas should implement it own validate_cli_argiments or maybe better parse_cli_args and store the result as attributes in the object


setup_environment();
std::function<SWIGVMContainers::SWIGVM*()> vmMaker;
switch(m_lang) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Base class should be an abstract class and call here create_vm, however don't implement it. You mixed implementation of the client that supports all languages with the implementation of the abstract class. For the moment, we need the ExaudfclientBase as abstract class, ExaudfclientAllLangs, and we can add for each language its Exaudfclient{Lang} if we want to, however I would wait with later until we do the split into repos.

Copy link
Copy Markdown
Collaborator

@tkilias tkilias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accidentally approved, please see my comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants