#1456: Cleaned up and refactored exaudfclient cc#642
Conversation
| #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 |
There was a problem hiding this comment.
Can be moved into exaudfclient/exa_vm_factory.cc
| 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()); |
There was a problem hiding this comment.
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
|
|
||
| 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()); |
There was a problem hiding this comment.
We probably could move this also to cerr
|
|
||
| void setup_environment() { | ||
| if (::setenv("HOME", "/tmp", 1) == -1) { | ||
| fprintf(stderr, "Failed setting HOME env var: %s\n", std::strerror(errno)); |
There was a problem hiding this comment.
We probably move this also to cerr
| DBGVAR(std::cerr, libexaudflibPath); | ||
| void* handle = exa_load_libary(libexaudflibPath); | ||
| if (!handle) { | ||
| fprintf(stderr, "Failed to load library: %s\n", libexaudflibPath.c_str()); |
There was a problem hiding this comment.
We are already using cerr, so we probably can use it here, too
| #endif | ||
| } | ||
|
|
||
| int main(int argc, char **argv) { |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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() { |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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]); |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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>" |
There was a problem hiding this comment.
scriptOptionsParserVersion is actually only relevant for Java
| Benchmark | ||
| }; | ||
|
|
||
| class ExaUdfClientBase { |
There was a problem hiding this comment.
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"})...
?
There was a problem hiding this comment.
or there could be a pure virtual function which returns the list of expected CLI parameters, which each subclass implements.
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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.
tkilias
left a comment
There was a problem hiding this comment.
Accidentally approved, please see my comments
relates to #1456