[asterisk-commits] murf: branch murf/bug11210 r97207 - /team/murf/bug11210/channels/chan_sip.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jan 8 15:25:12 CST 2008


Author: murf
Date: Tue Jan  8 15:25:12 2008
New Revision: 97207

URL: http://svn.digium.com/view/asterisk?view=rev&rev=97207
Log:
added some code to keep tight track of peer and user load times; I see a terrific slowdown in reading peers if DNS resolution is broken. I'm thinking it might be cool to output a warning if peer build times are significantly higher than user build times. Begin phase II of speeding up the reloads: take the same sort of approach that the extensions.conf reader takes: an incremental sort of merge operation to reduce the downtime of reloading. Begin with code to compare peers.

Modified:
    team/murf/bug11210/channels/chan_sip.c

Modified: team/murf/bug11210/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/channels/chan_sip.c?view=diff&rev=97207&r1=97206&r2=97207
==============================================================================
--- team/murf/bug11210/channels/chan_sip.c (original)
+++ team/murf/bug11210/channels/chan_sip.c Tue Jan  8 15:25:12 2008
@@ -18662,7 +18662,7 @@
 		} else
 			speerobjs++;
 	}
-	/* Note that our peer HAS had its reference count incrased */
+	/* Note that our peer HAS had its reference count increased */
 	if (firstpass) {
 		peer->lastmsgssent = -1;
 		oldha = peer->ha;
@@ -18907,7 +18907,6 @@
 		 * way, then we will get events when app_voicemail gets loaded. */
 		sip_send_mwi_to_peer(peer, NULL, 1);
 	}
-
 	peer->theMark = 0;
 
 	ast_free_ha(oldha);
@@ -18922,6 +18921,76 @@
 	}
 	return peer;
 }
+
+/* Theory: It is quicker to construct a peer from the config file,
+   and to compare it with the (possibly existing) current peer at reload
+   time, and do nothing if the peer has not changed at all, than to 
+   automatically destroy the peer and re-create it every time.
+   With really large lists of peers, most reload situations will
+   involve fairly small sets of peer changes  */
+
+
+int ast_peercmp(struct sip_peer *peer1, struct sip_peer *peer2);
+
+int ast_peercmp(struct sip_peer *peer1, struct sip_peer *peer2)
+{
+	/* rule 1: only compare those fields that are actually set
+	   when the config file is read in. */
+	/* fields to compare:
+	   name
+	   stuff in handle_common_options
+	   secret
+	   md5secret
+	   auth (stuff from add_realm_authentification)
+	   callerid
+	   cid_name
+	   cid_num
+	   context
+	   subscribecontext
+	   fromdomain
+	   fromuser
+	   flags[0] <- SIP_USEREQPHONE
+	   outboundproxy (proxyname, port, forceopt)
+	   addr.sin_addr
+	   addr.sin_port
+	   defaddr
+	   host_dynamic
+	   tohost
+	   ha (permit/deny info)
+	   callingpres
+	   username
+	   language
+	   regexten
+	   callback (a sep field) (used to register, but not stored in peer, perse)
+	   call_limit
+	   busy_level
+	   amaflags
+	   accountcode
+	   mohinterpret
+	   mohsuggest
+	   stuff done by add_peer_mailboxes()
+	   flags[1] <- SIP_PAGE2_SUBSCRIBEMWIONLY
+	   flags[1] <- SIP_PAGE2_REGISTERTRYING
+	   vmexten
+	   callgroup
+	   allowtransfer
+	   pickupgroup
+	   prefs ------\
+	   capability --+---- set by ast_parse_allow_disallow
+	   autoframing
+	   rtptimeout
+	   rtpholdtimeout
+	   rtpkeepalive
+	   timer_t1
+	   timer_b
+	   chanvars (is a list!)
+	   maxms (qualify)
+	   maxcallbitrate
+
+	   NOTE: this is a big list, with lots of datatypes...! */
+	return 1; /* return 0 for a match like strcmp, 1 otherwise */
+}
+
 
 static int peer_markall_func(void *userobj, void *arg, int flags)
 {
@@ -18950,6 +19019,10 @@
 	struct sockaddr_in old_bindaddr = bindaddr;
 	int registry_count = 0, peer_count = 0, user_count = 0;
 	time_t run_start, run_end;
+	struct timeval before, loop_before;
+	int user_build_time=0, peer_build_time=0, user_link_time=0, peer_link_time=0, peer_ip_link_time=0, total_loop_time=0;
+	int user_build_cnt=0, peer_build_cnt=0, user_link_cnt=0, peer_link_cnt=0, peer_ip_link_cnt=0, total_loop_cnt=0;
+	
 	
 	run_start = time(0);
 	
@@ -19480,8 +19553,10 @@
 
 	/* Load peers, users and friends */
 	cat = NULL;
+	loop_before = ast_tvnow();
 	while ( (cat = ast_category_browse(cfg, cat)) ) {
 		const char *utype;
+		total_loop_cnt++;
 		if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication"))
 			continue;
 		utype = ast_variable_retrieve(cfg, cat, "type");
@@ -19501,22 +19576,37 @@
 				continue;
 			}
 			if (is_user) {
+				before = ast_tvnow();
 				user = build_user(cat, ast_variable_browse(cfg, cat), 0);
+				user_build_time += ast_tvdiff_us(ast_tvnow(),before);
+				user_build_cnt++;
 				if (user) {
+					before = ast_tvnow();
 					ao2_t_link(users, user, "link user into users table");
+					user_link_time += ast_tvdiff_us(ast_tvnow(),before);
+					user_link_cnt++;
 					unref_user(user,"unref_user from reload_config, near end");
 					user_count++;
 				}
 			}
 			if (is_peer) {
+				before = ast_tvnow();
 				peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
+				peer_build_time += ast_tvdiff_us(ast_tvnow(),before);
+				peer_build_cnt++;
 				if (peer) {
+					before = ast_tvnow();
 					ao2_t_link(peers, peer,"link peer into peers table");
+					peer_link_time += ast_tvdiff_us(ast_tvnow(),before);
+					peer_link_cnt++;
 					if (peer->addr.sin_addr.s_addr) {
 						char buf8[40];
 						addr2str(&peer->addr,buf8);
 						ast_log(LOG_NOTICE,"Inserted %s into peers_by_ip\n", buf8);
+						before = ast_tvnow();
 						ao2_t_link(peers_by_ip, peer,"link peer into peers_by_ip table");
+						peer_ip_link_time += ast_tvdiff_us(ast_tvnow(),before);
+						peer_ip_link_cnt++;
 					}
 					unref_peer(peer,"unref_peer: reload_config: just linked peer to two tables, peers and peers_by_ip");
 					peer_count++;
@@ -19524,7 +19614,13 @@
 			}
 		}
 	}
-	ast_log(LOG_NOTICE,"Reload: #6\n");
+	total_loop_time = ast_tvdiff_us(ast_tvnow(),loop_before);
+	
+	ast_log(LOG_NOTICE,"Reload: #6; total user build time=%d us; total peer build time = %d us;\n total user link time = %d us; total peer link time = %d us;\n total ip peer link time = %d us; total loop time = %d us.\n",
+			user_build_time, peer_build_time, user_link_time, peer_link_time, peer_ip_link_time, total_loop_time);
+	ast_log(LOG_NOTICE,"Reload: #6; total user build cnt=%d us; total peer build cnt = %d us;\n total user link cnt = %d us; total peer link cnt = %d us;\n total ip peer link cnt = %d us; total loop cnt = %d us.\n",
+			user_build_cnt, peer_build_cnt, user_link_cnt, peer_link_cnt, peer_ip_link_cnt, total_loop_cnt);
+	
 	bindaddr.sin_family = AF_INET;
 	internip = bindaddr;
 	if (ast_find_ourip(&internip.sin_addr, bindaddr)) {




More information about the asterisk-commits mailing list