[asterisk-dev] Change in asterisk[master]: res_pjsip: Add global option to limit the maximum time for i...

George Joseph (Code Review) asteriskteam at digium.com
Sat Apr 11 20:08:28 CDT 2015


George Joseph has uploaded a new change for review.

  https://gerrit.asterisk.org/48

Change subject: res_pjsip: Add global option to limit the maximum time for initial qualifies
......................................................................

res_pjsip: Add global option to limit the maximum time for initial qualifies

Currently when Asterisk starts initial qualifies of contacts are spread out
randomly between 0 and qualify_timeout to prevent network and system overload.
If a contact's qualify_frequency is 5 minutes however, that contact may be
unavailable to accept calls for the entire 5 minutes after startup.  So while
staggering the initial qualifies is a good idea, basing the time on
qualify_timeout could leave contacts unavailable for too long.

This patch adds a new global parameter "max_initial_qualify_time" that sets the
maximum time for the initial qualifies.  This way you could make sure that all
your contacts are initialy, ransomly qualified within say 30 seconds but still
have the contact's ongoing qualifies at a 5 minute interval.

If max_initial_qualify_time is > 0, the formula is initial_interval =
min(max_initial_interval, qualify_timeout * random().  If not set,
qualify_timeout is used.

The default is "0" (disabled).

Testing Done:
Tested in my own pbx with 15 endpoints.
If max_initial_qualify_time is > 0 and < qualify_time, it's used, otherwise
qualify_timeout is used.

Testsuite test forthcoming.

Change-Id: Ib80498aa1ea9923277bef51d6a9015c9c79740f4
Tested-by: George Joseph <george.joseph at fairview5.com>
---
M CHANGES
A contrib/ast-db-manage/config/versions/45119a33fbbe_add_pjsip_max_initial_qualify_time.py
M include/asterisk/res_pjsip.h
M res/res_pjsip.c
M res/res_pjsip/config_global.c
M res/res_pjsip/pjsip_options.c
6 files changed, 66 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/48/48/1

diff --git a/CHANGES b/CHANGES
index 4237c82..0f70425 100644
--- a/CHANGES
+++ b/CHANGES
@@ -139,6 +139,11 @@
  * A new CLI command has been added: "pjsip show settings", which shows
    both the global and system configuration settings.
 
+ * A new global option has been added: "max_initial_qualify_time", which
+   sets the The maximum amount of time from startup that qualifies should be
+   attempted on all contacts.
+
+
 res_ari_channels
 ------------------
  * Two new events, 'ChannelHold' and 'ChannelUnhold', have been added to the
diff --git a/contrib/ast-db-manage/config/versions/45119a33fbbe_add_pjsip_max_initial_qualify_time.py b/contrib/ast-db-manage/config/versions/45119a33fbbe_add_pjsip_max_initial_qualify_time.py
new file mode 100644
index 0000000..3c5f243
--- /dev/null
+++ b/contrib/ast-db-manage/config/versions/45119a33fbbe_add_pjsip_max_initial_qualify_time.py
@@ -0,0 +1,21 @@
+"""add pjsip max_initial_qualify_time
+
+Revision ID: 45119a33fbbe
+Revises: 2256a84ca226
+Create Date: 2015-04-10 12:29:43.077598
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '45119a33fbbe'
+down_revision = '2256a84ca226'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+    op.add_column('ps_globals', sa.Column('max_initial_qualify_time', sa.Integer))
+
+def downgrade():
+    op.drop_column('ps_globals', 'max_initial_qualify_time')
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index 2358a72..df18238 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -1956,4 +1956,12 @@
  */
 unsigned int ast_sip_get_keep_alive_interval(void);
 
+/*!
+ * \brief Retrieve the system max initial qualify time.
+ *
+ * \retval the maximum initial qualify time.
+ */
+unsigned int ast_sip_get_max_initial_qualify_time(void);
+
+
 #endif /* _RES_PJSIP_H */
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index fcd8516..1a9afb2 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -1211,6 +1211,9 @@
 				<configOption name="keep_alive_interval" default="0">
 					<synopsis>The interval (in seconds) to send keepalives to active connection-oriented transports.</synopsis>
 				</configOption>
+				<configOption name="max_initial_qualify_time" default="0">
+					<synopsis>The maximum amount of time from startup that qualifies should be attempted on all contacts.</synopsis>
+				</configOption>
 				<configOption name="type">
 					<synopsis>Must be of type 'global'.</synopsis>
 				</configOption>
diff --git a/res/res_pjsip/config_global.c b/res/res_pjsip/config_global.c
index 2aa1583..42ba234 100644
--- a/res/res_pjsip/config_global.c
+++ b/res/res_pjsip/config_global.c
@@ -33,6 +33,7 @@
 #define DEFAULT_OUTBOUND_ENDPOINT "default_outbound_endpoint"
 #define DEFAULT_DEBUG "no"
 #define DEFAULT_ENDPOINT_IDENTIFIER_ORDER "ip,username,anonymous"
+#define DEFAULT_MAX_INITIAL_QUALIFY_TIME 0
 
 static char default_useragent[256];
 
@@ -50,6 +51,8 @@
 	unsigned int max_forwards;
 	/* The interval at which to send keep alive messages to active connection-oriented transports */
 	unsigned int keep_alive_interval;
+	/* The maximum time for all contacts to be qualified at startup */
+	unsigned int max_initial_qualify_time;
 };
 
 static void global_destructor(void *obj)
@@ -159,6 +162,21 @@
 	interval = cfg->keep_alive_interval;
 	ao2_ref(cfg, -1);
 	return interval;
+}
+
+unsigned int ast_sip_get_max_initial_qualify_time(void)
+{
+	unsigned int time;
+	struct global_config *cfg;
+
+	cfg = get_global_cfg();
+	if (!cfg) {
+		return DEFAULT_MAX_INITIAL_QUALIFY_TIME;
+	}
+
+	time = cfg->max_initial_qualify_time;
+	ao2_ref(cfg, -1);
+	return time;
 }
 
 /*!
@@ -271,6 +289,9 @@
 	ast_sorcery_object_field_register(sorcery, "global", "keep_alive_interval",
 		__stringify(DEFAULT_KEEPALIVE_INTERVAL),
 		OPT_UINT_T, 0, FLDSET(struct global_config, keep_alive_interval));
+	ast_sorcery_object_field_register(sorcery, "global", "max_initial_qualify_time",
+		__stringify(DEFAULT_MAX_INITIAL_QUALIFY_TIME),
+		OPT_UINT_T, 0, FLDSET(struct global_config, max_initial_qualify_time));
 
 	if (ast_sorcery_instance_observer_add(sorcery, &observer_callbacks_global)) {
 		return -1;
diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index 9794827..3b11cf0 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -949,13 +949,19 @@
 	struct ast_sip_contact *contact = obj;
 	struct ast_sip_aor *aor = arg;
 	int initial_interval;
+	int max_time = ast_sip_get_max_initial_qualify_time();
 
 	contact->qualify_frequency = aor->qualify_frequency;
 	contact->authenticate_qualify = aor->authenticate_qualify;
 
 	/* Delay initial qualification by a random fraction of the specified interval */
-	initial_interval = contact->qualify_frequency * 1000;
-	initial_interval = (int)(initial_interval * ast_random_double());
+	if (max_time && max_time < contact->qualify_frequency) {
+		initial_interval = max_time;
+	} else {
+		initial_interval = contact->qualify_frequency;
+	}
+
+	initial_interval = (int)((initial_interval * 1000) * ast_random_double());
 
 	if (contact->qualify_frequency) {
 		schedule_qualify(contact, initial_interval);

-- 
To view, visit https://gerrit.asterisk.org/48
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib80498aa1ea9923277bef51d6a9015c9c79740f4
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: George Joseph <george.joseph at fairview5.com>



More information about the asterisk-dev mailing list