From 08689d3bb200655c437ef6561450eece205ec89c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 28 Nov 2017 09:14:02 +0200 Subject: [PATCH] MXS-1539: Execute all REST API commands in a worker thread Executing the commands inside a worker thread allows further improvements to job queuing but mainly it fixes the problem of loading users when listeners are allocated at runtime. When a runtime listener was being created, it was allocated in the admin thread whereas the listeners created at startup were allocated in the "main" thread. This caused a minor difference in how administrative functions were handled by the REST API and MaxAdmin. The only real problem is that listener allocation depends on being done inside a worker thread as it lazily initializes some resources. --- server/core/resource.cc | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/server/core/resource.cc b/server/core/resource.cc index dbb92ac9b..5fdd0fb2a 100644 --- a/server/core/resource.cc +++ b/server/core/resource.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include "internal/httprequest.hh" #include "internal/httpresponse.hh" @@ -34,6 +35,7 @@ #include "internal/config_runtime.h" #include "internal/modules.h" #include "internal/worker.h" +#include "internal/worker.hh" using std::list; using std::map; @@ -1074,12 +1076,11 @@ bool request_precondition_met(const HttpRequest& request, HttpResponse& response return rval; } -HttpResponse resource_handle_request(const HttpRequest& request) +static HttpResponse handle_request(const HttpRequest& request) { MXS_DEBUG("%s %s %s", request.get_verb().c_str(), request.get_uri().c_str(), request.get_json_str().c_str()); - SpinLockGuard guard(resource_lock); HttpResponse rval; if (request_precondition_met(request, rval)) @@ -1115,3 +1116,38 @@ HttpResponse resource_handle_request(const HttpRequest& request) return rval; } + +class ResourceTask: public mxs::Worker::Task +{ +public: + ResourceTask(const HttpRequest& request): + m_request(request) + { + } + + void execute(mxs::Worker& worker) + { + m_response = handle_request(m_request); + } + + HttpResponse result() + { + return m_response; + } + +private: + const HttpRequest& m_request; + HttpResponse m_response; +}; + +HttpResponse resource_handle_request(const HttpRequest& request) +{ + mxs::Worker* worker = mxs::Worker::get(0); + mxs::Semaphore sem; + ResourceTask task(request); + + worker->post(&task, &sem); + sem.wait(); + + return task.result(); +}