FSCORE-637 - limit - reset rate and release resource apis

Thanks Moy
This commit is contained in:
Rupa Schomaker 2010-07-20 22:21:32 -05:00
parent fca93f2910
commit a7c31e6fe9
8 changed files with 142 additions and 12 deletions

View File

@ -76,6 +76,14 @@ SWITCH_DECLARE(switch_status_t) switch_limit_release(const char *backend, switch
*/
SWITCH_DECLARE(int) switch_limit_usage(const char *backend, const char *realm, const char *resource, uint32_t *rcount);
/*!
\brief reset interval usage counter for a given resource
\param backend
\param realm
\param resource
*/
SWITCH_DECLARE(switch_status_t) switch_limit_interval_reset(const char *backend, const char *realm, const char *resource);
/*!
\brief reset all usage counters
\param backend to use
@ -106,6 +114,7 @@ SWITCH_DECLARE(char *) switch_limit_status(const char *backend);
#define SWITCH_LIMIT_RELEASE(name) static switch_status_t name (switch_core_session_t *session, const char *realm, const char *resource)
#define SWITCH_LIMIT_USAGE(name) static int name (const char *realm, const char *resource, uint32_t *rcount)
#define SWITCH_LIMIT_RESET(name) static switch_status_t name (void)
#define SWITCH_LIMIT_INTERVAL_RESET(name) static switch_status_t name (const char *realm, const char *resource)
#define SWITCH_LIMIT_STATUS(name) static char * name (void)
#define LIMIT_IGNORE_TRANSFER_VARIABLE "limit_ignore_transfer"

View File

@ -324,13 +324,14 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void);
break; \
}
#define SWITCH_ADD_LIMIT(limit_int, int_name, incrptr, releaseptr, usageptr, resetptr, statusptr) \
#define SWITCH_ADD_LIMIT(limit_int, int_name, incrptr, releaseptr, usageptr, resetptr, statusptr, interval_resetptr) \
for (;;) { \
limit_int = (switch_limit_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_LIMIT_INTERFACE); \
limit_int->incr = incrptr; \
limit_int->release = releaseptr; \
limit_int->usage = usageptr; \
limit_int->reset = resetptr; \
limit_int->interval_reset = interval_resetptr; \
limit_int->status = statusptr; \
limit_int->interface_name = int_name; \
break; \

View File

@ -526,6 +526,8 @@ struct switch_limit_interface {
switch_status_t (*reset) (void);
/*! freform status */
char * (*status) (void);
/*! reset interval counter */
switch_status_t (*interval_reset) (const char *realm, const char *resource);
/* internal */
switch_thread_rwlock_t *rwlock;
int refs;

View File

@ -4227,7 +4227,7 @@ SWITCH_STANDARD_API(sql_escape)
}
/* LIMIT Stuff */
#define LIMIT_USAGE_USAGE "<backend> <realm> <id> [rate]"
#define LIMIT_USAGE_SYNTAX "<backend> <realm> <id> [rate]"
SWITCH_STANDARD_API(limit_usage_function)
{
int argc = 0;
@ -4255,7 +4255,7 @@ SWITCH_STANDARD_API(limit_usage_function)
}
if (argc < 3) {
stream->write_function(stream, "USAGE: limit_usage %s\n", LIMIT_USAGE_USAGE);
stream->write_function(stream, "USAGE: limit_usage %s\n", LIMIT_USAGE_SYNTAX);
goto end;
}
@ -4279,7 +4279,7 @@ end:
return SWITCH_STATUS_SUCCESS;
}
#define LIMIT_HASH_USAGE_USAGE "<realm> <id> [rate] (Using deprecated limit api, check limit_usage with backend param)"
#define LIMIT_HASH_USAGE_SYNTAX "<realm> <id> [rate] (Using deprecated limit api, check limit_usage with backend param)"
SWITCH_STANDARD_API(limit_hash_usage_function)
{
char *mydata = NULL;
@ -4290,12 +4290,12 @@ SWITCH_STANDARD_API(limit_hash_usage_function)
switch_safe_free(mydata);
return ret;
} else {
stream->write_function(stream, "USAGE: limit_hash_usage %s\n", LIMIT_HASH_USAGE_USAGE);
stream->write_function(stream, "USAGE: limit_hash_usage %s\n", LIMIT_HASH_USAGE_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
}
#define LIMIT_STATUS_USAGE "<backend>"
#define LIMIT_STATUS_SYNTAX "<backend>"
SWITCH_STANDARD_API(limit_status_function)
{
int argc = 0;
@ -4310,7 +4310,7 @@ SWITCH_STANDARD_API(limit_status_function)
}
if (argc < 1) {
stream->write_function(stream, "USAGE: limit_status %s\n", LIMIT_STATUS_USAGE);
stream->write_function(stream, "USAGE: limit_status %s\n", LIMIT_STATUS_SYNTAX);
goto end;
}
@ -4325,7 +4325,7 @@ end:
return SWITCH_STATUS_SUCCESS;
}
#define LIMIT_RESET_USAGE "<backend>"
#define LIMIT_RESET_SYNTAX "<backend>"
SWITCH_STANDARD_API(limit_reset_function)
{
int argc = 0;
@ -4340,7 +4340,7 @@ SWITCH_STANDARD_API(limit_reset_function)
}
if (argc < 1) {
stream->write_function(stream, "USAGE: limit_reset %s\n", LIMIT_RESET_USAGE);
stream->write_function(stream, "USAGE: limit_reset %s\n", LIMIT_RESET_SYNTAX);
goto end;
}
@ -4354,6 +4354,81 @@ end:
return SWITCH_STATUS_SUCCESS;
}
#define LIMIT_RELEASE_SYNTAX "<uuid> <backend> [realm] [resource]"
SWITCH_STANDARD_API(uuid_limit_release_function)
{
int argc = 0;
char *argv[5] = { 0 };
char *mydata = NULL;
char *realm = NULL;
char *resource = NULL;
switch_core_session_t *sess = NULL;
if (!zstr(cmd)) {
mydata = strdup(cmd);
switch_assert(mydata);
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 2) {
stream->write_function(stream, "USAGE: uuid_limit_release %s\n", LIMIT_RELEASE_SYNTAX);
goto end;
}
if (argc > 2) {
realm = argv[2];
}
if (argc > 3) {
resource = argv[3];
}
sess = switch_core_session_locate(argv[0]);
if (!sess) {
stream->write_function(stream, "-ERR did not find a session with uuid %s\n", argv[0]);
goto end;
}
switch_limit_release(argv[1], sess, realm, resource);
switch_core_session_rwunlock(sess);
stream->write_function(stream, "+OK");
end:
switch_safe_free(mydata);
return SWITCH_STATUS_SUCCESS;
}
#define LIMIT_INTERVAL_RESET_SYNTAX "<backend> <realm> <resource>"
SWITCH_STANDARD_API(limit_interval_reset_function)
{
int argc = 0;
char *argv[5] = { 0 };
char *mydata = NULL;
if (!zstr(cmd)) {
mydata = strdup(cmd);
switch_assert(mydata);
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc < 3) {
stream->write_function(stream, "USAGE: limit_interval_reset %s\n", LIMIT_INTERVAL_RESET_SYNTAX);
goto end;
}
switch_limit_interval_reset(argv[0], argv[1], argv[2]);
stream->write_function(stream, "+OK");
end:
switch_safe_free(mydata);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_commands_shutdown)
{
int x;
@ -4446,6 +4521,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
SWITCH_ADD_API(commands_api_interface, "limit_hash_usage", "Deprecated: gets the usage count of a limited resource", limit_hash_usage_function, "<realm> <id>");
SWITCH_ADD_API(commands_api_interface, "limit_status", "Gets the status of a limit backend", limit_status_function, "<backend>");
SWITCH_ADD_API(commands_api_interface, "limit_reset", "Reset the counters of a limit backend", limit_reset_function, "<backend>");
SWITCH_ADD_API(commands_api_interface, "limit_interval_reset", "Reset the interval counter for a limited resource", limit_interval_reset_function, LIMIT_INTERVAL_RESET_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "load", "Load Module", load_function, LOAD_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "log", "Log", log_function, LOG_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "md5", "md5", md5_function, "<data>");
@ -4494,6 +4570,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
SWITCH_ADD_API(commands_api_interface, "uuid_getvar", "uuid_getvar", uuid_getvar_function, GETVAR_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_hold", "hold", uuid_hold_function, HOLD_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_kill", "Kill Channel", kill_function, KILL_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_limit_release", "Release limit resource", uuid_limit_release_function, LIMIT_RELEASE_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_loglevel", "set loglevel on session", uuid_loglevel, UUID_LOGLEVEL_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_media", "media", uuid_media_function, MEDIA_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_park", "Park Channel", park_function, PARK_SYNTAX);
@ -4600,6 +4677,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
switch_console_set_complete("add uuid_getvar ::console::list_uuid");
switch_console_set_complete("add uuid_hold ::console::list_uuid");
switch_console_set_complete("add uuid_kill ::console::list_uuid");
switch_console_set_complete("add uuid_limit_release ::console::list_uuid");
switch_console_set_complete("add uuid_loglevel ::console::list_uuid console");
switch_console_set_complete("add uuid_loglevel ::console::list_uuid alert");
switch_console_set_complete("add uuid_loglevel ::console::list_uuid crit");

View File

@ -620,7 +620,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_db_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
/* register limit interfaces */
SWITCH_ADD_LIMIT(limit_interface, "db", limit_incr_db, limit_release_db, limit_usage_db, limit_reset_db, limit_status_db);
SWITCH_ADD_LIMIT(limit_interface, "db", limit_incr_db, limit_release_db, limit_usage_db, limit_reset_db, limit_status_db, NULL);
SWITCH_ADD_APP(app_interface, "db", "Insert to the db", DB_DESC, db_function, DB_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "group", "Manage a group", GROUP_DESC, group_function, GROUP_USAGE, SAF_SUPPORT_NOMEDIA);

View File

@ -360,6 +360,24 @@ SWITCH_LIMIT_RESET(limit_reset_hash)
return SWITCH_STATUS_GENERR;
}
SWITCH_LIMIT_INTERVAL_RESET(limit_interval_reset_hash)
{
char *hash_key = NULL;
limit_hash_item_t *item = NULL;
switch_thread_rwlock_rdlock(globals.limit_hash_rwlock);
hash_key = switch_mprintf("%s_%s", realm, resource);
if ((item = switch_core_hash_find(globals.limit_hash, hash_key))) {
item->rate_usage = 0;
item->last_check = switch_epoch_time_now(NULL);
}
switch_safe_free(hash_key);
switch_thread_rwlock_unlock(globals.limit_hash_rwlock);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_LIMIT_STATUS(limit_status_hash)
{
/*
@ -892,7 +910,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_hash_load)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
/* register limit interfaces */
SWITCH_ADD_LIMIT(limit_interface, "hash", limit_incr_hash, limit_release_hash, limit_usage_hash, limit_reset_hash, limit_status_hash);
SWITCH_ADD_LIMIT(limit_interface, "hash", limit_incr_hash, limit_release_hash, limit_usage_hash, limit_reset_hash, limit_status_hash, limit_interval_reset_hash);
switch_scheduler_add_task(switch_epoch_time_now(NULL) + LIMIT_HASH_CLEANUP_INTERVAL, limit_hash_cleanup_callback, "limit_hash_cleanup", "mod_hash", 0, NULL,
SSHF_NONE);

View File

@ -300,7 +300,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_redis_load)
/* If FreeSWITCH was restarted and we still have active calls, decrement them so our global count stays valid */
limit_reset_redis();
SWITCH_ADD_LIMIT(limit_interface, "redis", limit_incr_redis, limit_release_redis, limit_usage_redis, limit_reset_redis, limit_status_redis);
SWITCH_ADD_LIMIT(limit_interface, "redis", limit_incr_redis, limit_release_redis, limit_usage_redis, limit_reset_redis, limit_status_redis, NULL);
return SWITCH_STATUS_SUCCESS;
}

View File

@ -196,6 +196,28 @@ end:
return status;
}
SWITCH_DECLARE(switch_status_t) switch_limit_interval_reset(const char *backend, const char *realm, const char *resource) {
switch_limit_interface_t *limit = NULL;
int status = SWITCH_STATUS_SUCCESS;
/* locate impl, call appropriate func */
if (!(limit = get_backend(backend))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Limit subsystem %s not found!\n", backend);
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
if (!limit->interval_reset) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Limit subsystem %s does not implement interval_reset!\n", backend);
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
status = limit->interval_reset(realm, resource);
end:
release_backend(limit);
return status;
}
SWITCH_DECLARE(char *) switch_limit_status(const char *backend) {
switch_limit_interface_t *limit = NULL;
char *status = NULL;