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.
This commit is contained in:
Markus Mäkelä 2017-11-28 09:14:02 +02:00
parent 74ae3d9ff3
commit 08689d3bb2

View File

@ -24,6 +24,7 @@
#include <maxscale/http.hh>
#include <maxscale/adminusers.h>
#include <maxscale/modulecmd.h>
#include <maxscale/semaphore.hh>
#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();
}