Allow query classifier to initialize itself

The process and thread initialization/finalization of the query
classifier plugins is handled using the process and thread
initialization/finalization functions in the module object.

However, the top-level query classifier will also need to perform
process and thread initialization when transaction boundaries are
detected using regular expressions.
This commit is contained in:
Johan Wikman
2017-03-10 14:01:36 +02:00
parent 669d6e95f4
commit a58f944f23
8 changed files with 68 additions and 25 deletions

View File

@ -19,6 +19,16 @@ MXS_BEGIN_DECLS
#define QUERY_CLASSIFIER_VERSION {1, 1, 0} #define QUERY_CLASSIFIER_VERSION {1, 1, 0}
/**
* qc_init_kind_t specifies what kind of initialization should be performed.
*/
typedef enum qc_init_kind
{
QC_INIT_SELF = 0x01, /*< Initialize/finalize the query classifier itself. */
QC_INIT_PLUGIN = 0x02, /*< Initialize/finalize the plugin. */
QC_INIT_BOTH = 0x03
} qc_init_kind_t;
/** /**
* qc_query_type_t defines bits that provide information about a * qc_query_type_t defines bits that provide information about a
* particular statement. * particular statement.
@ -377,11 +387,14 @@ bool qc_setup(const char* plugin_name, const char* plugin_args);
* *
* MaxScale calls this functions, so plugins should not do that. * MaxScale calls this functions, so plugins should not do that.
* *
* @param kind What kind of initialization should be performed.
* Combination of qc_init_kind_t.
*
* @return True, if the process wide initialization could be performed. * @return True, if the process wide initialization could be performed.
* *
* @see qc_process_end qc_thread_init * @see qc_process_end qc_thread_init
*/ */
bool qc_process_init(void); bool qc_process_init(uint32_t kind);
/** /**
* Finalizes the query classifier. * Finalizes the query classifier.
@ -390,9 +403,12 @@ bool qc_process_init(void);
* by a call to this function. MaxScale calls this function, so plugins * by a call to this function. MaxScale calls this function, so plugins
* should not do that. * should not do that.
* *
* @param kind What kind of finalization should be performed.
* Combination of qc_init_kind_t.
*
* @see qc_process_init qc_thread_end * @see qc_process_init qc_thread_end
*/ */
void qc_process_end(void); void qc_process_end(uint32_t kind);
/** /**
* Loads a particular query classifier. * Loads a particular query classifier.
@ -426,11 +442,14 @@ void qc_unload(QUERY_CLASSIFIER* classifier);
* *
* MaxScale calls this function, so plugins should not do that. * MaxScale calls this function, so plugins should not do that.
* *
* @param kind What kind of initialization should be performed.
* Combination of qc_init_kind_t.
*
* @return True if the initialization succeeded, false otherwise. * @return True if the initialization succeeded, false otherwise.
* *
* @see qc_thread_end * @see qc_thread_end
*/ */
bool qc_thread_init(void); bool qc_thread_init(uint32_t kind);
/** /**
* Performs thread finalization needed by the query classifier. * Performs thread finalization needed by the query classifier.
@ -439,9 +458,12 @@ bool qc_thread_init(void);
* *
* MaxScale calls this function, so plugins should not do that. * MaxScale calls this function, so plugins should not do that.
* *
* @param kind What kind of finalization should be performed.
* Combination of qc_init_kind_t.
*
* @see qc_thread_init * @see qc_thread_init
*/ */
void qc_thread_end(void); void qc_thread_end(uint32_t kind);
/** /**
* Parses the statement in the provided buffer and returns a value specifying * Parses the statement in the provided buffer and returns a value specifying

View File

@ -47,7 +47,7 @@ int main(int argc, char** argv)
set_process_datadir(strdup("/tmp")); set_process_datadir(strdup("/tmp"));
qc_setup("qc_sqlite", NULL); qc_setup("qc_sqlite", NULL);
qc_process_init(); qc_process_init(QC_INIT_BOTH);
infile = fopen(argv[1], "rb"); infile = fopen(argv[1], "rb");
outfile = fopen(argv[2], "wb"); outfile = fopen(argv[2], "wb");
@ -83,6 +83,6 @@ int main(int argc, char** argv)
} }
fclose(infile); fclose(infile);
fclose(outfile); fclose(outfile);
qc_process_end(); qc_process_end(QC_INIT_BOTH);
return 0; return 0;
} }

View File

@ -314,10 +314,10 @@ int main(int argc, char** argv)
if (mxs_log_init(NULL, ".", MXS_LOG_TARGET_DEFAULT)) if (mxs_log_init(NULL, ".", MXS_LOG_TARGET_DEFAULT))
{ {
if (qc_setup(lib, NULL) && qc_process_init()) if (qc_setup(lib, NULL) && qc_process_init(QC_INIT_BOTH))
{ {
rc = run(input_name, expected_name); rc = run(input_name, expected_name);
qc_process_end(); qc_process_end(QC_INIT_BOTH);
} }
else else
{ {

View File

@ -41,7 +41,7 @@ int main()
set_libdir(strdup("../qc_sqlite")); set_libdir(strdup("../qc_sqlite"));
if (qc_setup("qc_sqlite", NULL) && qc_process_init()) if (qc_setup("qc_sqlite", NULL) && qc_process_init(QC_INIT_BOTH))
{ {
const char s[] = "SELECT @@global.max_allowed_packet"; const char s[] = "SELECT @@global.max_allowed_packet";
@ -53,7 +53,7 @@ int main()
// code generator. // code generator.
qc_parse(stmt); qc_parse(stmt);
qc_process_end(); qc_process_end(QC_INIT_BOTH);
rv = EXIT_SUCCESS; rv = EXIT_SUCCESS;
} }

View File

@ -38,7 +38,6 @@ static const char default_qc_name[] = "qc_sqlite";
static QUERY_CLASSIFIER* classifier; static QUERY_CLASSIFIER* classifier;
bool qc_setup(const char* plugin_name, const char* plugin_args) bool qc_setup(const char* plugin_name, const char* plugin_args)
{ {
QC_TRACE(); QC_TRACE();
@ -67,22 +66,32 @@ bool qc_setup(const char* plugin_name, const char* plugin_args)
return (rv == QC_RESULT_OK) ? true : false; return (rv == QC_RESULT_OK) ? true : false;
} }
bool qc_process_init(void) bool qc_process_init(uint32_t kind)
{ {
QC_TRACE(); QC_TRACE();
ss_dassert(classifier); ss_dassert(classifier);
return classifier->qc_process_init() == 0; bool rc = true;
if (kind & QC_INIT_PLUGIN)
{
rc = classifier->qc_process_init() == 0;
} }
void qc_process_end(void) return rc;
}
void qc_process_end(uint32_t kind)
{ {
QC_TRACE(); QC_TRACE();
ss_dassert(classifier); ss_dassert(classifier);
if (kind & QC_INIT_PLUGIN)
{
classifier->qc_process_end(); classifier->qc_process_end();
classifier = NULL; classifier = NULL;
} }
}
QUERY_CLASSIFIER* qc_load(const char* plugin_name) QUERY_CLASSIFIER* qc_load(const char* plugin_name)
{ {
@ -106,20 +115,30 @@ void qc_unload(QUERY_CLASSIFIER* classifier)
// TODO: actually can unload something. // TODO: actually can unload something.
} }
bool qc_thread_init(void) bool qc_thread_init(uint32_t kind)
{ {
QC_TRACE(); QC_TRACE();
ss_dassert(classifier); ss_dassert(classifier);
return classifier->qc_thread_init() == 0; bool rc = true;
if (kind & QC_INIT_PLUGIN)
{
rc = classifier->qc_thread_init() == 0;
} }
void qc_thread_end(void) return rc;
}
void qc_thread_end(uint32_t kind)
{ {
QC_TRACE(); QC_TRACE();
ss_dassert(classifier); ss_dassert(classifier);
return classifier->qc_thread_end(); if (kind & QC_INIT_PLUGIN)
{
classifier->qc_thread_end();
}
} }
qc_parse_result_t qc_parse(GWBUF* query) qc_parse_result_t qc_parse(GWBUF* query)

View File

@ -127,7 +127,7 @@ int main(int argc, char* argv[])
{ {
if (mxs_log_init(NULL, ".", MXS_LOG_TARGET_DEFAULT)) if (mxs_log_init(NULL, ".", MXS_LOG_TARGET_DEFAULT))
{ {
if (qc_setup(NULL, NULL) && qc_process_init()) if (qc_setup(NULL, NULL) && qc_process_init(QC_INIT_BOTH))
{ {
const char* zModule = argv[1]; const char* zModule = argv[1];
@ -158,7 +158,7 @@ int main(int argc, char* argv[])
cerr << "error: Could not initialize factory." << endl; cerr << "error: Could not initialize factory." << endl;
} }
qc_process_end(); qc_process_end(QC_INIT_BOTH);
} }
else else
{ {

View File

@ -237,12 +237,12 @@ int main()
if (mxs_log_init(NULL, ".", MXS_LOG_TARGET_DEFAULT)) if (mxs_log_init(NULL, ".", MXS_LOG_TARGET_DEFAULT))
{ {
set_libdir(MXS_STRDUP_A("../../../../../query_classifier/qc_sqlite/")); set_libdir(MXS_STRDUP_A("../../../../../query_classifier/qc_sqlite/"));
if (qc_setup("qc_sqlite", "") && qc_process_init()) if (qc_setup("qc_sqlite", "") && qc_process_init(QC_INIT_BOTH))
{ {
set_libdir(MXS_STRDUP_A("../")); set_libdir(MXS_STRDUP_A("../"));
rc = test(); rc = test();
qc_process_end(); qc_process_end(QC_INIT_BOTH);
} }
else else
{ {

View File

@ -50,7 +50,7 @@ int TestStorage::run(int argc, char** argv)
{ {
if (mxs_log_init(NULL, ".", MXS_LOG_TARGET_DEFAULT)) if (mxs_log_init(NULL, ".", MXS_LOG_TARGET_DEFAULT))
{ {
if (qc_setup(NULL, NULL) && qc_process_init()) if (qc_setup(NULL, NULL) && qc_process_init(QC_INIT_BOTH))
{ {
const char* zModule = NULL; const char* zModule = NULL;
size_t threads = m_threads; size_t threads = m_threads;
@ -113,6 +113,8 @@ int TestStorage::run(int argc, char** argv)
{ {
cerr << "error: Could not initialize factory " << zModule << "." << endl; cerr << "error: Could not initialize factory " << zModule << "." << endl;
} }
qc_process_end(QC_INIT_BOTH);
} }
else else
{ {