MXS-1539: Make refresh rate limitations thread-specific

The refresh rate limitations are now also thread-specific. This is
required when the authentication data is partitioned on a per thread
basis.
This commit is contained in:
Markus Mäkelä
2017-11-23 14:07:47 +02:00
parent 4194c1c558
commit a2d275aca3
2 changed files with 41 additions and 50 deletions

View File

@ -49,6 +49,7 @@
#include <maxscale/version.h>
#include <maxscale/jansson.h>
#include <maxscale/json_api.h>
#include <maxscale/worker.h>
#include "internal/config.h"
#include "internal/filter.h"
@ -102,7 +103,8 @@ SERVICE* service_alloc(const char *name, const char *router)
char *my_name = MXS_STRDUP(name);
char *my_router = MXS_STRDUP(router);
SERVICE *service = (SERVICE *)MXS_CALLOC(1, sizeof(*service));
SERVICE_REFRESH_RATE* rate_limit = (SERVICE_REFRESH_RATE*)MXS_CALLOC(config_threadcount(),
sizeof(*rate_limit));
if (!my_name || !my_router || !service)
{
MXS_FREE(my_name);
@ -324,13 +326,6 @@ serviceStartPort(SERVICE *service, SERV_LISTENER *port)
}
}
/**
* At service start last update is set to USERS_REFRESH_TIME seconds earlier. This way MaxScale
* could try reloading users just after startup.
*/
service->rate_limit.last = time(NULL) - USERS_REFRESH_TIME;
service->rate_limit.nloads = 1;
if (port->listener->func.listen(port->listener, config_bind))
{
port->listener->session = session_alloc(service, port->listener);
@ -1612,60 +1607,56 @@ service_update(SERVICE *service, char *router, char *user, char *auth)
int service_refresh_users(SERVICE *service)
{
int ret = 1;
int self = mxs_worker_get_current_id();
ss_dassert(self);
time_t now = time(NULL);
if (spinlock_acquire_nowait(&service->spin))
/* Check if refresh rate limit has been exceeded */
if ((now < service->rate_limits[self].last + USERS_REFRESH_TIME) ||
(service->rate_limits[self].nloads >= USERS_REFRESH_MAX_PER_TIME))
{
time_t now = time(NULL);
MXS_ERROR("[%s] Refresh rate limit exceeded for load of users' table.", service->name);
}
else
{
service->rate_limits[self].nloads++;
/* Check if refresh rate limit has been exceeded */
if ((now < service->rate_limit.last + USERS_REFRESH_TIME) ||
(service->rate_limit.nloads > USERS_REFRESH_MAX_PER_TIME))
/** If we have reached the limit on users refreshes, reset refresh time and count */
if (service->rate_limits[self].nloads >= USERS_REFRESH_MAX_PER_TIME)
{
MXS_ERROR("[%s] Refresh rate limit exceeded for load of users' table.", service->name);
service->rate_limits[self].nloads = 0;
service->rate_limits[self].last = now;
}
else
ret = 0;
LISTENER_ITERATOR iter;
for (SERV_LISTENER *listener = listener_iterator_init(service, &iter);
listener; listener = listener_iterator_next(&iter))
{
service->rate_limit.nloads++;
/** If we have reached the limit on users refreshes, reset refresh time and count */
if (service->rate_limit.nloads > USERS_REFRESH_MAX_PER_TIME)
/** Load the authentication users before before starting the listener */
if (listener_is_active(listener) && listener->listener &&
listener->listener->authfunc.loadusers)
{
service->rate_limit.nloads = 1;
service->rate_limit.last = now;
}
ret = 0;
LISTENER_ITERATOR iter;
for (SERV_LISTENER *listener = listener_iterator_init(service, &iter);
listener; listener = listener_iterator_next(&iter))
{
/** Load the authentication users before before starting the listener */
if (listener_is_active(listener) && listener->listener &&
listener->listener->authfunc.loadusers)
switch (listener->listener->authfunc.loadusers(listener))
{
switch (listener->listener->authfunc.loadusers(listener))
{
case MXS_AUTH_LOADUSERS_FATAL:
MXS_ERROR("[%s] Fatal error when loading users for listener '%s',"
" authentication will not work.", service->name, listener->name);
ret = 1;
break;
case MXS_AUTH_LOADUSERS_FATAL:
MXS_ERROR("[%s] Fatal error when loading users for listener '%s',"
" authentication will not work.", service->name, listener->name);
ret = 1;
break;
case MXS_AUTH_LOADUSERS_ERROR:
MXS_WARNING("[%s] Failed to load users for listener '%s', authentication"
" might not work.", service->name, listener->name);
ret = 1;
break;
case MXS_AUTH_LOADUSERS_ERROR:
MXS_WARNING("[%s] Failed to load users for listener '%s', authentication"
" might not work.", service->name, listener->name);
ret = 1;
break;
default:
break;
}
default:
break;
}
}
}
spinlock_release(&service->spin);
}
return ret;