add fsctl min_idle_cpu and min-idle-cpu feature to refuse calls after the system fallse below a certian percentage of idle cpu

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16962 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2010-03-10 20:21:34 +00:00
parent 869c221f3a
commit b1ddb70cf1
8 changed files with 94 additions and 26 deletions

View File

@ -228,6 +228,7 @@ libfreeswitch_la_SOURCES = \
src/switch_odbc.c \
src/g711.c \
src/switch_pcm.c \
src/switch_profile.c\
libs/stfu/stfu.c \
libs/libteletone/src/libteletone_detect.c \
libs/libteletone/src/libteletone_generate.c \

View File

@ -31,6 +31,9 @@
* this file does not exist!!!!
*
*/
#include "switch_profile.h"
#ifndef WIN32
#include <switch_private.h>
#endif
@ -220,6 +223,9 @@ struct switch_runtime {
uint32_t runlevel;
uint32_t tipping_point;
int32_t timer_affinity;
switch_profile_timer_t *profile_timer;
double profile_time;
double min_idle_time;
};
extern struct switch_runtime runtime;

View File

@ -1901,7 +1901,7 @@ SWITCH_DECLARE(switch_time_t) switch_core_uptime(void);
\param val the command arguement (if needed)
\return 0 on success nonzero on error
*/
SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_t *val);
SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *val);
/*!
\brief Get the output console
@ -1970,6 +1970,8 @@ SWITCH_DECLARE(void) switch_time_set_matrix(switch_bool_t enable);
SWITCH_DECLARE(void) switch_time_set_cond_yield(switch_bool_t enable);
SWITCH_DECLARE(uint32_t) switch_core_min_dtmf_duration(uint32_t duration);
SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration);
SWITCH_DECLARE(double) switch_core_min_idle_cpu(double new_limit);
SWITCH_DECLARE(double) switch_core_idle_cpu(void);
SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration);
SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string);
SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string);

View File

@ -1458,7 +1458,8 @@ typedef enum {
SCSC_SHUTDOWN_NOW,
SCSC_CALIBRATE_CLOCK,
SCSC_SAVE_HISTORY,
SCSC_CRASH
SCSC_CRASH,
SCSC_MIN_IDLE_CPU
} switch_session_ctl_t;
typedef enum {

View File

@ -1439,6 +1439,7 @@ SWITCH_STANDARD_API(status_function)
switch_core_session_ctl(SCSC_SPS, &sps);
stream->write_function(stream, "%d session(s) %d/%d\n", switch_core_session_count(), last_sps, sps);
stream->write_function(stream, "%d session(s) max\n", switch_core_session_limit(0));
stream->write_function(stream, "min idle cpu %0.2f/%0.2f\n", switch_core_min_idle_cpu(-1.0), switch_core_idle_cpu());
if (html) {
stream->write_function(stream, "</b>\n");
@ -1535,7 +1536,23 @@ SWITCH_STANDARD_API(ctl_function)
arg = atoi(argv[1]);
}
switch_core_session_ctl(SCSC_MAX_SESSIONS, &arg);
stream->write_function(stream, "+OK max sessions: %d\n", arg);
stream->write_function(stream, "+OK max sessions: %f\n", arg);
} else if (!strcasecmp(argv[0], "min_idle_cpu")) {
double d = -1;
if (argc > 1) {
d = atof(argv[1]);
}
switch_core_session_ctl(SCSC_MIN_IDLE_CPU, &d);
if (d) {
stream->write_function(stream, "+OK min idle cpu: %0.2f%\n", d);
} else {
stream->write_function(stream, "+OK min idle cpu: DISABLED\n", d);
}
} else if (!strcasecmp(argv[0], "max_dtmf_duration")) {
if (argc > 1) {
arg = atoi(argv[1]);

View File

@ -82,6 +82,7 @@ static void send_heartbeat(void)
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count());
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Idle-CPU", "%f", switch_core_idle_cpu());
switch_event_fire(&event);
}
}
@ -1442,6 +1443,8 @@ static void switch_load_core_config(const char *file)
switch_time_set_matrix(switch_true(var));
} else if (!strcasecmp(var, "max-sessions") && !zstr(val)) {
switch_core_session_limit(atoi(val));
} else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)) {
switch_core_min_idle_cpu(atof(val));
} else if (!strcasecmp(var, "tipping-point") && !zstr(val)) {
runtime.tipping_point = atoi(val);
} else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) {
@ -1628,8 +1631,10 @@ SWITCH_DECLARE(uint32_t) switch_core_debug_level(void)
}
SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_t *val)
SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *val)
{
int *intval = (int *) val;
if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) {
return -1;
}
@ -1646,10 +1651,10 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_
break;
case SCSC_SYNC_CLOCK:
switch_time_sync();
*val = 0;
*intval = 0;
break;
case SCSC_PAUSE_INBOUND:
if (*val) {
if (*intval) {
switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
} else {
switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);
@ -1700,7 +1705,7 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_
win_shutdown();
#endif
if (*val) {
if (*intval) {
switch_set_flag((&runtime), SCF_RESTART);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");
} else {
@ -1722,7 +1727,7 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_
win_shutdown();
#endif
if (*val) {
if (*intval) {
switch_set_flag((&runtime), SCF_RESTART);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");
} else {
@ -1734,53 +1739,59 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_
runtime.running = 0;
break;
case SCSC_CHECK_RUNNING:
*val = runtime.running;
*intval = runtime.running;
break;
case SCSC_LOGLEVEL:
if (*val > -1) {
runtime.hard_log_level = *val;
if (*intval > -1) {
runtime.hard_log_level = *intval;
}
if (runtime.hard_log_level > SWITCH_LOG_DEBUG) {
runtime.hard_log_level = SWITCH_LOG_DEBUG;
}
*val = runtime.hard_log_level;
*intval = runtime.hard_log_level;
break;
case SCSC_DEBUG_LEVEL:
if (*val > -1) {
if (*val > 10)
*val = 10;
runtime.debug_level = *val;
if (*intval > -1) {
if (*intval > 10)
*intval = 10;
runtime.debug_level = *intval;
}
*intval = runtime.debug_level;
break;
case SCSC_MIN_IDLE_CPU:
{
double *dval = (double *) val;
*dval = switch_core_min_idle_cpu(*dval);
}
*val = runtime.debug_level;
break;
case SCSC_MAX_SESSIONS:
*val = switch_core_session_limit(*val);
*intval = switch_core_session_limit(*intval);
break;
case SCSC_LAST_SPS:
*val = runtime.sps_last;
*intval = runtime.sps_last;
break;
case SCSC_MAX_DTMF_DURATION:
*val = switch_core_max_dtmf_duration(*val);
*intval = switch_core_max_dtmf_duration(*intval);
break;
case SCSC_MIN_DTMF_DURATION:
*val = switch_core_min_dtmf_duration(*val);
*intval = switch_core_min_dtmf_duration(*intval);
break;
case SCSC_DEFAULT_DTMF_DURATION:
*val = switch_core_default_dtmf_duration(*val);
*intval = switch_core_default_dtmf_duration(*intval);
break;
case SCSC_SPS:
switch_mutex_lock(runtime.throttle_mutex);
if (*val > 0) {
runtime.sps_total = *val;
if (*intval > 0) {
runtime.sps_total = *intval;
}
*val = runtime.sps_total;
*intval = runtime.sps_total;
switch_mutex_unlock(runtime.throttle_mutex);
break;
case SCSC_RECLAIM:
switch_core_memory_reclaim_all();
*val = 0;
*intval = 0;
break;
}

View File

@ -1485,6 +1485,10 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_
return NULL;
}
if (runtime.min_idle_time > 0 && runtime.profile_time < runtime.min_idle_time) {
return NULL;
}
PROTECT_INTERFACE(endpoint_interface);
switch_mutex_lock(runtime.throttle_mutex);
@ -1640,6 +1644,21 @@ SWITCH_DECLARE(uint32_t) switch_core_session_limit(uint32_t new_limit)
return session_manager.session_limit;
}
SWITCH_DECLARE(double) switch_core_min_idle_cpu(double new_limit)
{
if (new_limit >= 0) {
runtime.min_idle_time = new_limit;
}
return runtime.min_idle_time;
}
SWITCH_DECLARE(double) switch_core_idle_cpu(void)
{
return runtime.profile_time;
}
SWITCH_DECLARE(uint32_t) switch_core_sessions_per_second(uint32_t new_limit)
{
if (new_limit) {

View File

@ -630,6 +630,10 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
uint32_t x, tick = 0;
switch_time_t ts = 0, last = 0;
int fwd_errs = 0, rev_errs = 0;
int profile_tick = 0;
runtime.profile_timer = switch_new_profile_timer();
switch_get_system_idle_time(runtime.profile_timer, &runtime.profile_time);
#ifdef HAVE_CPU_SET_MACROS
if (runtime.timer_affinity > -1) {
@ -741,6 +745,11 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
tick += STEP_MS;
if (tick >= TICK_PER_SEC) {
if (++profile_tick == 1) {
switch_get_system_idle_time(runtime.profile_timer, &runtime.profile_time);
profile_tick = 0;
}
if (runtime.sps <= 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Rate of %d!\n", runtime.sps_total);
}
@ -803,6 +812,8 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
globals.RUNNING = 0;
switch_mutex_unlock(globals.mutex);
switch_delete_profile_timer(&runtime.profile_timer);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Soft timer thread exiting.\n");
return SWITCH_STATUS_TERM;