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:
@ -148,7 +148,7 @@ typedef struct service
|
||||
bool strip_db_esc; /**< Remove the '\' characters from database names
|
||||
* when querying them from the server. MySQL Workbench seems
|
||||
* to escape at least the underscore character. */
|
||||
SERVICE_REFRESH_RATE rate_limit; /**< The refresh rate limit for users table */
|
||||
SERVICE_REFRESH_RATE *rate_limits; /**< The refresh rate limits for users of each thread */
|
||||
MXS_FILTER_DEF **filters; /**< Ordered list of filters */
|
||||
int n_filters; /**< Number of filters */
|
||||
int64_t conn_idle_timeout; /**< Session timeout in seconds */
|
||||
|
@ -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,26 +1607,25 @@ service_update(SERVICE *service, char *router, char *user, char *auth)
|
||||
int service_refresh_users(SERVICE *service)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (spinlock_acquire_nowait(&service->spin))
|
||||
{
|
||||
int self = mxs_worker_get_current_id();
|
||||
ss_dassert(self);
|
||||
time_t now = time(NULL);
|
||||
|
||||
/* 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 ((now < service->rate_limits[self].last + USERS_REFRESH_TIME) ||
|
||||
(service->rate_limits[self].nloads >= USERS_REFRESH_MAX_PER_TIME))
|
||||
{
|
||||
MXS_ERROR("[%s] Refresh rate limit exceeded for load of users' table.", service->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
service->rate_limit.nloads++;
|
||||
service->rate_limits[self].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)
|
||||
if (service->rate_limits[self].nloads >= USERS_REFRESH_MAX_PER_TIME)
|
||||
{
|
||||
service->rate_limit.nloads = 1;
|
||||
service->rate_limit.last = now;
|
||||
service->rate_limits[self].nloads = 0;
|
||||
service->rate_limits[self].last = now;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
@ -1665,9 +1659,6 @@ int service_refresh_users(SERVICE *service)
|
||||
}
|
||||
}
|
||||
|
||||
spinlock_release(&service->spin);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user