[asterisk-commits] mmichelson: branch mmichelson/rls-notify r417793 - /team/mmichelson/rls-notif...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jul 2 19:32:10 CDT 2014


Author: mmichelson
Date: Wed Jul  2 19:32:07 2014
New Revision: 417793

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=417793
Log:
Add support for batched notifications


Modified:
    team/mmichelson/rls-notify/res/res_pjsip_pubsub.c

Modified: team/mmichelson/rls-notify/res/res_pjsip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/rls-notify/res/res_pjsip_pubsub.c?view=diff&rev=417793&r1=417792&r2=417793
==============================================================================
--- team/mmichelson/rls-notify/res/res_pjsip_pubsub.c (original)
+++ team/mmichelson/rls-notify/res/res_pjsip_pubsub.c Wed Jul  2 19:32:07 2014
@@ -359,6 +359,12 @@
 	pjsip_evsub *evsub;
 	/*! The underlying PJSIP dialog */
 	pjsip_dialog *dlg;
+	/*! Interval to use for batching notifications */
+	unsigned int notification_batch_interval;
+	/*! Scheduler ID for batched notification */
+	int notify_sched_id;
+	/*! Indicator if scheduled batched notification should be sent */
+	unsigned int send_scheduled_notify;
 };
 
 /*!
@@ -636,9 +642,11 @@
 	return find_body_generator(accept, num_accept_headers);
 }
 
+struct resource_tree;
+
 static struct ast_sip_subscription *create_real_subscription(const struct ast_sip_subscription_handler *handler,
 		struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, const char *resource,
-		struct ast_sip_pubsub_body_generator *generator);
+		struct ast_sip_pubsub_body_generator *generator, struct resource_tree *tree);
 
 /*!
  * \brief A node for a resource tree.
@@ -822,6 +830,7 @@
  */
 struct resource_tree {
 	struct tree_node *root;
+	unsigned int notification_batch_interval;
 };
 
 /*!
@@ -871,7 +880,10 @@
 	}
 
 	AST_VECTOR_INIT(&visited, AST_VECTOR_SIZE(&list->items));
+
 	tree->root = tree_node_alloc(resource, &visited);
+	tree->notification_batch_interval = list->notification_batch_interval;
+
 	build_node_children(endpoint, handler, list, tree->root, &visited);
 	AST_VECTOR_FREE(&visited);
 	ao2_cleanup(list);
@@ -1052,7 +1064,7 @@
 	struct ast_sip_subscription *sub;
 
 	/* Start by creating the root subscription. It's the only real subscription. */
-	sub = create_real_subscription(handler, endpoint, rdata, resource, generator);
+	sub = create_real_subscription(handler, endpoint, rdata, resource, generator, tree);
 	if (!sub) {
 		return NULL;
 	}
@@ -1287,7 +1299,7 @@
 
 static struct ast_sip_subscription *create_real_subscription(const struct ast_sip_subscription_handler *handler,
 		struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, const char *resource,
-		struct ast_sip_pubsub_body_generator *generator)
+		struct ast_sip_pubsub_body_generator *generator, struct resource_tree *tree)
 {
 	struct ast_sip_subscription *sub;
 	pjsip_dialog *dlg;
@@ -1323,6 +1335,7 @@
 
 	ast_sip_mod_data_set(dlg->pool, dlg->mod_data, pubsub_module.id, MOD_DATA_MSG,
 			pjsip_msg_clone(dlg->pool, rdata->msg_info.msg));
+	sub->reality.real.notification_batch_interval = tree->notification_batch_interval;
 
 	add_subscription(sub);
 	return sub;
@@ -1459,6 +1472,8 @@
 		pjsip_tx_data_dec_ref(tdata);
 		return -1;
 	}
+
+	sub->reality.real.send_scheduled_notify = 0;
 	
 	return 0;
 }
@@ -1475,6 +1490,46 @@
 	return 0;
 }
 
+static int serialized_send_notify(void *userdata)
+{
+	struct ast_sip_subscription *sub = userdata;
+
+	/* It's possible that between when the notification was scheduled
+	 * and now, that a new SUBSCRIBE arrived, requiring full state to be
+	 * sent out in an immediate NOTIFY. If that has happened, we need to
+	 * bail out here instead of sending the batched NOTIFY.
+	 */
+	if (!sub->reality.real.send_scheduled_notify) {
+		return 0;
+	}
+
+	return send_notify(sub, 0);
+}
+
+static int sched_cb(const void *data)
+{
+	/* Why the #*(@% does the scheduler give us const data?! */
+	struct ast_sip_subscription *sub = (struct ast_sip_subscription *) data;
+
+	ast_sip_push_task(sub->serializer, serialized_send_notify, sub);
+	return 0;
+}
+
+static int schedule_notification(struct ast_sip_subscription *sub)
+{
+	/* There's already a notification scheduled */
+	if (sub->reality.real.notify_sched_id > -1) {
+		return 0;
+	}
+
+	sub->reality.real.notify_sched_id = ast_sched_add(sched, sub->reality.real.notification_batch_interval, sched_cb, ao2_bump(sub));
+	if (sub->reality.real.notify_sched_id < 0) {
+		return -1;
+	}
+	sub->reality.real.send_scheduled_notify = 1;
+	return 0;
+}
+
 int ast_sip_subscription_notify(struct ast_sip_subscription *sub, void *notify_data,
 		int terminate)
 {
@@ -1490,9 +1545,11 @@
 		}
 	}
 
-	send_notify(sub, terminate);
-
-	return 0;
+	if (sub->reality.real.notification_batch_interval) {
+		return schedule_notification(sub);
+	} else {
+		return send_notify(sub, terminate);
+	}
 }
 
 void ast_sip_subscription_get_local_uri(struct ast_sip_subscription *sub, char *buf, size_t size)




More information about the asterisk-commits mailing list