2013-05-14 21:45:08 +00:00
|
|
|
/*
|
|
|
|
* Asterisk -- An open source telephony toolkit.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013, Digium, Inc.
|
|
|
|
*
|
|
|
|
* David M. Lee, II <dlee@digium.com>
|
|
|
|
*
|
|
|
|
* See http://www.asterisk.org for more information about
|
|
|
|
* the Asterisk project. Please do not directly contact
|
|
|
|
* any of the maintainers of this project for assistance;
|
|
|
|
* the project provides a web site, mailing lists and IRC
|
|
|
|
* channels for your use.
|
|
|
|
*
|
|
|
|
* This program is free software, distributed under the terms of
|
|
|
|
* the GNU General Public License Version 2. See the LICENSE file
|
|
|
|
* at the top of the source tree.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*! \file
|
|
|
|
*
|
|
|
|
* \brief Stasis application support.
|
|
|
|
*
|
|
|
|
* \author David M. Lee, II <dlee@digium.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "asterisk.h"
|
|
|
|
|
|
|
|
#include "app.h"
|
2014-08-07 15:30:19 +00:00
|
|
|
#include "control.h"
|
Multiple revisions 420089-420090,420097
........
r420089 | mjordan | 2014-08-05 15:10:52 -0500 (Tue, 05 Aug 2014) | 72 lines
ARI: Add channel technology agnostic out of call text messaging
This patch adds the ability to send and receive text messages from various
technology stacks in Asterisk through ARI. This includes chan_sip (sip),
res_pjsip_messaging (pjsip), and res_xmpp (xmpp). Messages are sent using the
endpoints resource, and can be sent directly through that resource, or to a
particular endpoint.
For example, the following would send the message "Hello there" to PJSIP
endpoint alice with a display URI of sip:asterisk@mycooldomain.org:
ari/endpoints/sendMessage?to=pjsip:alice&from=sip:asterisk@mycooldomain.org&body=Hello+There
This is equivalent to the following as well:
ari/endpoints/PJSIP/alice/sendMessage?from=sip:asterisk@mycooldomain.org&body=Hello+There
Both forms are available for message technologies that allow for arbitrary
destinations, such as chan_sip.
Inbound messages can now be received over ARI as well. An ARI application that
subscribes to endpoints will receive messages from those endpoints:
{
"type": "TextMessageReceived",
"timestamp": "2014-07-12T22:53:13.494-0500",
"endpoint": {
"technology": "PJSIP",
"resource": "alice",
"state": "online",
"channel_ids": []
},
"message": {
"from": "\"alice\" <sip:alice@127.0.0.1>",
"to": "pjsip:asterisk@127.0.0.1",
"body": "Watson, come here.",
"variables": []
},
"application": "testsuite"
}
The above was made possible due to some rather major changes in the message
core. This includes (but is not limited to):
- Users of the message API can now register message handlers. A handler has
two callbacks: one to determine if the handler has a destination for the
message, and another to handle it.
- All dialplan functionality of handling a message was moved into a message
handler provided by the message API.
- Messages can now have the technology/endpoint associated with them.
Various other properties are also now more easily accessible.
- A number of ao2 containers that weren't really needed were replaced with
vectors. Iteration over ao2_containers is expensive and pointless when
the lifetime of things is well defined and the number of things is very
small.
res_stasis now has a new file that makes up its structure, messaging. The
messaging functionality implements a message handler, and passes received
messages that match an interested endpoint over to the app for processing.
Note that inadvertently while testing this, I reproduced ASTERISK-23969.
res_pjsip_messaging was incorrectly parsing out the 'to' field, such that
arbitrary SIP URIs mangled the endpoint lookup. This patch includes the
fix for that as well.
Review: https://reviewboard.asterisk.org/r/3726
ASTERISK-23692 #close
Reported by: Matt Jordan
ASTERISK-23969 #close
Reported by: Andrew Nagy
........
r420090 | mjordan | 2014-08-05 15:16:37 -0500 (Tue, 05 Aug 2014) | 2 lines
Remove automerge properties :-(
........
r420097 | mjordan | 2014-08-05 16:36:25 -0500 (Tue, 05 Aug 2014) | 2 lines
test_message: Fix strict-aliasing compilation issue
........
Merged revisions 420089-420090,420097 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@420098 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-08-05 21:44:09 +00:00
|
|
|
#include "messaging.h"
|
2013-05-14 21:45:08 +00:00
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
#include "asterisk/callerid.h"
|
2016-10-20 07:27:21 -05:00
|
|
|
#include "asterisk/cli.h"
|
2013-05-14 21:45:08 +00:00
|
|
|
#include "asterisk/stasis_app.h"
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
#include "asterisk/stasis_bridges.h"
|
2013-05-14 21:45:08 +00:00
|
|
|
#include "asterisk/stasis_channels.h"
|
2013-10-04 16:01:48 +00:00
|
|
|
#include "asterisk/stasis_endpoints.h"
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
#include "asterisk/stasis_message_router.h"
|
2013-06-10 13:07:11 +00:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
#define BRIDGE_ALL "__AST_BRIDGE_ALL_TOPIC"
|
|
|
|
#define CHANNEL_ALL "__AST_CHANNEL_ALL_TOPIC"
|
|
|
|
#define ENDPOINT_ALL "__AST_ENDPOINT_ALL_TOPIC"
|
|
|
|
|
2017-01-19 08:05:36 -07:00
|
|
|
/*! Global debug flag. No need for locking */
|
|
|
|
int global_debug;
|
|
|
|
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate);
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
struct stasis_app {
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
/*! Aggregation topic for this application. */
|
|
|
|
struct stasis_topic *topic;
|
|
|
|
/*! Router for handling messages forwarded to \a topic. */
|
|
|
|
struct stasis_message_router *router;
|
2014-02-01 16:26:57 +00:00
|
|
|
/*! Router for handling messages to the bridge all \a topic. */
|
|
|
|
struct stasis_message_router *bridge_router;
|
2015-09-04 12:25:07 -05:00
|
|
|
/*! Optional router for handling endpoint messages in 'all' subscriptions */
|
|
|
|
struct stasis_message_router *endpoint_router;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
/*! Container of the channel forwards to this app's topic. */
|
|
|
|
struct ao2_container *forwards;
|
2013-05-14 21:45:08 +00:00
|
|
|
/*! Callback function for this application. */
|
|
|
|
stasis_app_cb handler;
|
|
|
|
/*! Opaque data to hand to callback function. */
|
|
|
|
void *data;
|
2015-09-04 12:25:07 -05:00
|
|
|
/*! Subscription model for the application */
|
|
|
|
enum stasis_app_subscription_model subscription_model;
|
2016-10-20 07:27:21 -05:00
|
|
|
/*! Whether or not someone wants to see debug messages about this app */
|
|
|
|
int debug;
|
2019-02-08 14:48:27 -06:00
|
|
|
/*! An array of allowed events types for this application */
|
|
|
|
struct ast_json *events_allowed;
|
|
|
|
/*! An array of disallowed events types for this application */
|
|
|
|
struct ast_json *events_disallowed;
|
2013-05-14 21:45:08 +00:00
|
|
|
/*! Name of the Stasis application */
|
|
|
|
char name[];
|
|
|
|
};
|
|
|
|
|
2013-10-04 16:01:48 +00:00
|
|
|
enum forward_type {
|
|
|
|
FORWARD_CHANNEL,
|
|
|
|
FORWARD_BRIDGE,
|
|
|
|
FORWARD_ENDPOINT,
|
|
|
|
};
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
/*! Subscription info for a particular channel/bridge. */
|
|
|
|
struct app_forwards {
|
|
|
|
/*! Count of number of times this channel/bridge has been subscribed */
|
|
|
|
int interested;
|
|
|
|
|
|
|
|
/*! Forward for the regular topic */
|
Multiple revisions 399887,400138,400178,400180-400181
........
r399887 | dlee | 2013-09-26 10:41:47 -0500 (Thu, 26 Sep 2013) | 1 line
Minor performance bump by not allocate manager variable struct if we don't need it
........
r400138 | dlee | 2013-09-30 10:24:00 -0500 (Mon, 30 Sep 2013) | 23 lines
Stasis performance improvements
This patch addresses several performance problems that were found in
the initial performance testing of Asterisk 12.
The Stasis dispatch object was allocated as an AO2 object, even though
it has a very confined lifecycle. This was replaced with a straight
ast_malloc().
The Stasis message router was spending an inordinate amount of time
searching hash tables. In this case, most of our routers had 6 or
fewer routes in them to begin with. This was replaced with an array
that's searched linearly for the route.
We more heavily rely on AO2 objects in Asterisk 12, and the memset()
in ao2_ref() actually became noticeable on the profile. This was
#ifdef'ed to only run when AO2_DEBUG was enabled.
After being misled by an erroneous comment in taskprocessor.c during
profiling, the wrong comment was removed.
Review: https://reviewboard.asterisk.org/r/2873/
........
r400178 | dlee | 2013-09-30 13:26:27 -0500 (Mon, 30 Sep 2013) | 24 lines
Taskprocessor optimization; switch Stasis to use taskprocessors
This patch optimizes taskprocessor to use a semaphore for signaling,
which the OS can do a better job at managing contention and waiting
that we can with a mutex and condition.
The taskprocessor execution was also slightly optimized to reduce the
number of locks taken.
The only observable difference in the taskprocessor implementation is
that when the final reference to the taskprocessor goes away, it will
execute all tasks to completion instead of discarding the unexecuted
tasks.
For systems where unnamed semaphores are not supported, a really
simple semaphore implementation is provided. (Which gives identical
performance as the original taskprocessor implementation).
The way we ended up implementing Stasis caused the threadpool to be a
burden instead of a boost to performance. This was switched to just
use taskprocessors directly for subscriptions.
Review: https://reviewboard.asterisk.org/r/2881/
........
r400180 | dlee | 2013-09-30 13:39:34 -0500 (Mon, 30 Sep 2013) | 28 lines
Optimize how Stasis forwards are dispatched
This patch optimizes how forwards are dispatched in Stasis.
Originally, forwards were dispatched as subscriptions that are invoked
on the publishing thread. This did not account for the vast number of
forwards we would end up having in the system, and the amount of work it
would take to walk though the forward subscriptions.
This patch modifies Stasis so that rather than walking the tree of
forwards on every dispatch, when forwards and subscriptions are changed,
the subscriber list for every topic in the tree is changed.
This has a couple of benefits. First, this reduces the workload of
dispatching messages. It also reduces contention when dispatching to
different topics that happen to forward to the same aggregation topic
(as happens with all of the channel, bridge and endpoint topics).
Since forwards are no longer subscriptions, the bulk of this patch is
simply changing stasis_subscription objects to stasis_forward objects
(which, admittedly, I should have done in the first place.)
Since this required me to yet again put in a growing array, I finally
abstracted that out into a set of ast_vector macros in
asterisk/vector.h.
Review: https://reviewboard.asterisk.org/r/2883/
........
r400181 | dlee | 2013-09-30 13:48:57 -0500 (Mon, 30 Sep 2013) | 28 lines
Remove dispatch object allocation from Stasis publishing
While looking for areas for performance improvement, I realized that an
unused feature in Stasis was negatively impacting performance.
When a message is sent to a subscriber, a dispatch object is allocated
for the dispatch, containing the topic the message was published to, the
subscriber the message is being sent to, and the message itself.
The topic is actually unused by any subscriber in Asterisk today. And
the subscriber is associated with the taskprocessor the message is being
dispatched to.
First, this patch removes the unused topic parameter from Stasis
subscription callbacks.
Second, this patch introduces the concept of taskprocessor local data,
data that may be set on a taskprocessor and provided along with the data
pointer when a task is pushed using the ast_taskprocessor_push_local()
call. This allows the task to have both data specific to that
taskprocessor, in addition to data specific to that invocation.
With those two changes, the dispatch object can be removed completely,
and the message is simply refcounted and sent directly to the
taskprocessor.
Review: https://reviewboard.asterisk.org/r/2884/
........
Merged revisions 399887,400138,400178,400180-400181 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@400186 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-09-30 18:55:27 +00:00
|
|
|
struct stasis_forward *topic_forward;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
/*! Forward for the caching topic */
|
Multiple revisions 399887,400138,400178,400180-400181
........
r399887 | dlee | 2013-09-26 10:41:47 -0500 (Thu, 26 Sep 2013) | 1 line
Minor performance bump by not allocate manager variable struct if we don't need it
........
r400138 | dlee | 2013-09-30 10:24:00 -0500 (Mon, 30 Sep 2013) | 23 lines
Stasis performance improvements
This patch addresses several performance problems that were found in
the initial performance testing of Asterisk 12.
The Stasis dispatch object was allocated as an AO2 object, even though
it has a very confined lifecycle. This was replaced with a straight
ast_malloc().
The Stasis message router was spending an inordinate amount of time
searching hash tables. In this case, most of our routers had 6 or
fewer routes in them to begin with. This was replaced with an array
that's searched linearly for the route.
We more heavily rely on AO2 objects in Asterisk 12, and the memset()
in ao2_ref() actually became noticeable on the profile. This was
#ifdef'ed to only run when AO2_DEBUG was enabled.
After being misled by an erroneous comment in taskprocessor.c during
profiling, the wrong comment was removed.
Review: https://reviewboard.asterisk.org/r/2873/
........
r400178 | dlee | 2013-09-30 13:26:27 -0500 (Mon, 30 Sep 2013) | 24 lines
Taskprocessor optimization; switch Stasis to use taskprocessors
This patch optimizes taskprocessor to use a semaphore for signaling,
which the OS can do a better job at managing contention and waiting
that we can with a mutex and condition.
The taskprocessor execution was also slightly optimized to reduce the
number of locks taken.
The only observable difference in the taskprocessor implementation is
that when the final reference to the taskprocessor goes away, it will
execute all tasks to completion instead of discarding the unexecuted
tasks.
For systems where unnamed semaphores are not supported, a really
simple semaphore implementation is provided. (Which gives identical
performance as the original taskprocessor implementation).
The way we ended up implementing Stasis caused the threadpool to be a
burden instead of a boost to performance. This was switched to just
use taskprocessors directly for subscriptions.
Review: https://reviewboard.asterisk.org/r/2881/
........
r400180 | dlee | 2013-09-30 13:39:34 -0500 (Mon, 30 Sep 2013) | 28 lines
Optimize how Stasis forwards are dispatched
This patch optimizes how forwards are dispatched in Stasis.
Originally, forwards were dispatched as subscriptions that are invoked
on the publishing thread. This did not account for the vast number of
forwards we would end up having in the system, and the amount of work it
would take to walk though the forward subscriptions.
This patch modifies Stasis so that rather than walking the tree of
forwards on every dispatch, when forwards and subscriptions are changed,
the subscriber list for every topic in the tree is changed.
This has a couple of benefits. First, this reduces the workload of
dispatching messages. It also reduces contention when dispatching to
different topics that happen to forward to the same aggregation topic
(as happens with all of the channel, bridge and endpoint topics).
Since forwards are no longer subscriptions, the bulk of this patch is
simply changing stasis_subscription objects to stasis_forward objects
(which, admittedly, I should have done in the first place.)
Since this required me to yet again put in a growing array, I finally
abstracted that out into a set of ast_vector macros in
asterisk/vector.h.
Review: https://reviewboard.asterisk.org/r/2883/
........
r400181 | dlee | 2013-09-30 13:48:57 -0500 (Mon, 30 Sep 2013) | 28 lines
Remove dispatch object allocation from Stasis publishing
While looking for areas for performance improvement, I realized that an
unused feature in Stasis was negatively impacting performance.
When a message is sent to a subscriber, a dispatch object is allocated
for the dispatch, containing the topic the message was published to, the
subscriber the message is being sent to, and the message itself.
The topic is actually unused by any subscriber in Asterisk today. And
the subscriber is associated with the taskprocessor the message is being
dispatched to.
First, this patch removes the unused topic parameter from Stasis
subscription callbacks.
Second, this patch introduces the concept of taskprocessor local data,
data that may be set on a taskprocessor and provided along with the data
pointer when a task is pushed using the ast_taskprocessor_push_local()
call. This allows the task to have both data specific to that
taskprocessor, in addition to data specific to that invocation.
With those two changes, the dispatch object can be removed completely,
and the message is simply refcounted and sent directly to the
taskprocessor.
Review: https://reviewboard.asterisk.org/r/2884/
........
Merged revisions 399887,400138,400178,400180-400181 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@400186 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-09-30 18:55:27 +00:00
|
|
|
struct stasis_forward *topic_cached_forward;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2013-10-04 16:01:48 +00:00
|
|
|
/* Type of object being forwarded */
|
|
|
|
enum forward_type forward_type;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
/*! Unique id of the object being forwarded */
|
|
|
|
char id[];
|
|
|
|
};
|
|
|
|
|
|
|
|
static void forwards_dtor(void *obj)
|
|
|
|
{
|
2013-09-06 18:53:32 +00:00
|
|
|
#ifdef AST_DEVMODE
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
struct app_forwards *forwards = obj;
|
2013-09-06 18:53:32 +00:00
|
|
|
#endif /* AST_DEVMODE */
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
|
|
|
ast_assert(forwards->topic_forward == NULL);
|
|
|
|
ast_assert(forwards->topic_cached_forward == NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void forwards_unsubscribe(struct app_forwards *forwards)
|
|
|
|
{
|
Multiple revisions 399887,400138,400178,400180-400181
........
r399887 | dlee | 2013-09-26 10:41:47 -0500 (Thu, 26 Sep 2013) | 1 line
Minor performance bump by not allocate manager variable struct if we don't need it
........
r400138 | dlee | 2013-09-30 10:24:00 -0500 (Mon, 30 Sep 2013) | 23 lines
Stasis performance improvements
This patch addresses several performance problems that were found in
the initial performance testing of Asterisk 12.
The Stasis dispatch object was allocated as an AO2 object, even though
it has a very confined lifecycle. This was replaced with a straight
ast_malloc().
The Stasis message router was spending an inordinate amount of time
searching hash tables. In this case, most of our routers had 6 or
fewer routes in them to begin with. This was replaced with an array
that's searched linearly for the route.
We more heavily rely on AO2 objects in Asterisk 12, and the memset()
in ao2_ref() actually became noticeable on the profile. This was
#ifdef'ed to only run when AO2_DEBUG was enabled.
After being misled by an erroneous comment in taskprocessor.c during
profiling, the wrong comment was removed.
Review: https://reviewboard.asterisk.org/r/2873/
........
r400178 | dlee | 2013-09-30 13:26:27 -0500 (Mon, 30 Sep 2013) | 24 lines
Taskprocessor optimization; switch Stasis to use taskprocessors
This patch optimizes taskprocessor to use a semaphore for signaling,
which the OS can do a better job at managing contention and waiting
that we can with a mutex and condition.
The taskprocessor execution was also slightly optimized to reduce the
number of locks taken.
The only observable difference in the taskprocessor implementation is
that when the final reference to the taskprocessor goes away, it will
execute all tasks to completion instead of discarding the unexecuted
tasks.
For systems where unnamed semaphores are not supported, a really
simple semaphore implementation is provided. (Which gives identical
performance as the original taskprocessor implementation).
The way we ended up implementing Stasis caused the threadpool to be a
burden instead of a boost to performance. This was switched to just
use taskprocessors directly for subscriptions.
Review: https://reviewboard.asterisk.org/r/2881/
........
r400180 | dlee | 2013-09-30 13:39:34 -0500 (Mon, 30 Sep 2013) | 28 lines
Optimize how Stasis forwards are dispatched
This patch optimizes how forwards are dispatched in Stasis.
Originally, forwards were dispatched as subscriptions that are invoked
on the publishing thread. This did not account for the vast number of
forwards we would end up having in the system, and the amount of work it
would take to walk though the forward subscriptions.
This patch modifies Stasis so that rather than walking the tree of
forwards on every dispatch, when forwards and subscriptions are changed,
the subscriber list for every topic in the tree is changed.
This has a couple of benefits. First, this reduces the workload of
dispatching messages. It also reduces contention when dispatching to
different topics that happen to forward to the same aggregation topic
(as happens with all of the channel, bridge and endpoint topics).
Since forwards are no longer subscriptions, the bulk of this patch is
simply changing stasis_subscription objects to stasis_forward objects
(which, admittedly, I should have done in the first place.)
Since this required me to yet again put in a growing array, I finally
abstracted that out into a set of ast_vector macros in
asterisk/vector.h.
Review: https://reviewboard.asterisk.org/r/2883/
........
r400181 | dlee | 2013-09-30 13:48:57 -0500 (Mon, 30 Sep 2013) | 28 lines
Remove dispatch object allocation from Stasis publishing
While looking for areas for performance improvement, I realized that an
unused feature in Stasis was negatively impacting performance.
When a message is sent to a subscriber, a dispatch object is allocated
for the dispatch, containing the topic the message was published to, the
subscriber the message is being sent to, and the message itself.
The topic is actually unused by any subscriber in Asterisk today. And
the subscriber is associated with the taskprocessor the message is being
dispatched to.
First, this patch removes the unused topic parameter from Stasis
subscription callbacks.
Second, this patch introduces the concept of taskprocessor local data,
data that may be set on a taskprocessor and provided along with the data
pointer when a task is pushed using the ast_taskprocessor_push_local()
call. This allows the task to have both data specific to that
taskprocessor, in addition to data specific to that invocation.
With those two changes, the dispatch object can be removed completely,
and the message is simply refcounted and sent directly to the
taskprocessor.
Review: https://reviewboard.asterisk.org/r/2884/
........
Merged revisions 399887,400138,400178,400180-400181 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@400186 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-09-30 18:55:27 +00:00
|
|
|
stasis_forward_cancel(forwards->topic_forward);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
forwards->topic_forward = NULL;
|
Multiple revisions 399887,400138,400178,400180-400181
........
r399887 | dlee | 2013-09-26 10:41:47 -0500 (Thu, 26 Sep 2013) | 1 line
Minor performance bump by not allocate manager variable struct if we don't need it
........
r400138 | dlee | 2013-09-30 10:24:00 -0500 (Mon, 30 Sep 2013) | 23 lines
Stasis performance improvements
This patch addresses several performance problems that were found in
the initial performance testing of Asterisk 12.
The Stasis dispatch object was allocated as an AO2 object, even though
it has a very confined lifecycle. This was replaced with a straight
ast_malloc().
The Stasis message router was spending an inordinate amount of time
searching hash tables. In this case, most of our routers had 6 or
fewer routes in them to begin with. This was replaced with an array
that's searched linearly for the route.
We more heavily rely on AO2 objects in Asterisk 12, and the memset()
in ao2_ref() actually became noticeable on the profile. This was
#ifdef'ed to only run when AO2_DEBUG was enabled.
After being misled by an erroneous comment in taskprocessor.c during
profiling, the wrong comment was removed.
Review: https://reviewboard.asterisk.org/r/2873/
........
r400178 | dlee | 2013-09-30 13:26:27 -0500 (Mon, 30 Sep 2013) | 24 lines
Taskprocessor optimization; switch Stasis to use taskprocessors
This patch optimizes taskprocessor to use a semaphore for signaling,
which the OS can do a better job at managing contention and waiting
that we can with a mutex and condition.
The taskprocessor execution was also slightly optimized to reduce the
number of locks taken.
The only observable difference in the taskprocessor implementation is
that when the final reference to the taskprocessor goes away, it will
execute all tasks to completion instead of discarding the unexecuted
tasks.
For systems where unnamed semaphores are not supported, a really
simple semaphore implementation is provided. (Which gives identical
performance as the original taskprocessor implementation).
The way we ended up implementing Stasis caused the threadpool to be a
burden instead of a boost to performance. This was switched to just
use taskprocessors directly for subscriptions.
Review: https://reviewboard.asterisk.org/r/2881/
........
r400180 | dlee | 2013-09-30 13:39:34 -0500 (Mon, 30 Sep 2013) | 28 lines
Optimize how Stasis forwards are dispatched
This patch optimizes how forwards are dispatched in Stasis.
Originally, forwards were dispatched as subscriptions that are invoked
on the publishing thread. This did not account for the vast number of
forwards we would end up having in the system, and the amount of work it
would take to walk though the forward subscriptions.
This patch modifies Stasis so that rather than walking the tree of
forwards on every dispatch, when forwards and subscriptions are changed,
the subscriber list for every topic in the tree is changed.
This has a couple of benefits. First, this reduces the workload of
dispatching messages. It also reduces contention when dispatching to
different topics that happen to forward to the same aggregation topic
(as happens with all of the channel, bridge and endpoint topics).
Since forwards are no longer subscriptions, the bulk of this patch is
simply changing stasis_subscription objects to stasis_forward objects
(which, admittedly, I should have done in the first place.)
Since this required me to yet again put in a growing array, I finally
abstracted that out into a set of ast_vector macros in
asterisk/vector.h.
Review: https://reviewboard.asterisk.org/r/2883/
........
r400181 | dlee | 2013-09-30 13:48:57 -0500 (Mon, 30 Sep 2013) | 28 lines
Remove dispatch object allocation from Stasis publishing
While looking for areas for performance improvement, I realized that an
unused feature in Stasis was negatively impacting performance.
When a message is sent to a subscriber, a dispatch object is allocated
for the dispatch, containing the topic the message was published to, the
subscriber the message is being sent to, and the message itself.
The topic is actually unused by any subscriber in Asterisk today. And
the subscriber is associated with the taskprocessor the message is being
dispatched to.
First, this patch removes the unused topic parameter from Stasis
subscription callbacks.
Second, this patch introduces the concept of taskprocessor local data,
data that may be set on a taskprocessor and provided along with the data
pointer when a task is pushed using the ast_taskprocessor_push_local()
call. This allows the task to have both data specific to that
taskprocessor, in addition to data specific to that invocation.
With those two changes, the dispatch object can be removed completely,
and the message is simply refcounted and sent directly to the
taskprocessor.
Review: https://reviewboard.asterisk.org/r/2884/
........
Merged revisions 399887,400138,400178,400180-400181 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@400186 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-09-30 18:55:27 +00:00
|
|
|
stasis_forward_cancel(forwards->topic_cached_forward);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
forwards->topic_cached_forward = NULL;
|
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
static struct app_forwards *forwards_create(struct stasis_app *app,
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
const char *id)
|
|
|
|
{
|
2018-01-06 03:17:15 -05:00
|
|
|
struct app_forwards *forwards;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
|
|
|
if (!app || ast_strlen_zero(id)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
forwards = ao2_t_alloc(sizeof(*forwards) + strlen(id) + 1, forwards_dtor, id);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
if (!forwards) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
strcpy(forwards->id, id); /* SAFE */
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
|
|
|
return forwards;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*! Forward a channel's topics to an app */
|
2013-11-23 17:48:28 +00:00
|
|
|
static struct app_forwards *forwards_create_channel(struct stasis_app *app,
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
struct ast_channel *chan)
|
|
|
|
{
|
2015-09-04 12:25:07 -05:00
|
|
|
struct app_forwards *forwards;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
if (!app) {
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
forwards = forwards_create(app, chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
if (!forwards) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-10-04 16:01:48 +00:00
|
|
|
forwards->forward_type = FORWARD_CHANNEL;
|
2018-10-10 11:28:18 -03:00
|
|
|
forwards->topic_forward = stasis_forward_all(
|
|
|
|
chan ? ast_channel_topic(chan) : ast_channel_topic_all(),
|
2015-09-04 12:25:07 -05:00
|
|
|
app->topic);
|
|
|
|
|
2018-10-10 11:28:18 -03:00
|
|
|
if (!forwards->topic_forward) {
|
2015-09-04 12:25:07 -05:00
|
|
|
ao2_ref(forwards, -1);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return forwards;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*! Forward a bridge's topics to an app */
|
2013-11-23 17:48:28 +00:00
|
|
|
static struct app_forwards *forwards_create_bridge(struct stasis_app *app,
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
struct ast_bridge *bridge)
|
|
|
|
{
|
2015-09-04 12:25:07 -05:00
|
|
|
struct app_forwards *forwards;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
if (!app) {
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
forwards = forwards_create(app, bridge ? bridge->uniqueid : BRIDGE_ALL);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
if (!forwards) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-10-04 16:01:48 +00:00
|
|
|
forwards->forward_type = FORWARD_BRIDGE;
|
2018-09-19 13:34:41 -06:00
|
|
|
forwards->topic_forward = stasis_forward_all(ast_bridge_topic(bridge), app->topic);
|
2015-09-04 12:25:07 -05:00
|
|
|
|
2018-09-19 13:34:41 -06:00
|
|
|
if (!forwards->topic_forward && bridge) {
|
2015-09-04 12:25:07 -05:00
|
|
|
forwards_unsubscribe(forwards);
|
|
|
|
ao2_ref(forwards, -1);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return forwards;
|
|
|
|
}
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
static void endpoint_state_cb(void *data, struct stasis_subscription *sub,
|
|
|
|
struct stasis_message *message)
|
|
|
|
{
|
|
|
|
struct stasis_app *app = data;
|
|
|
|
|
|
|
|
stasis_publish(app->topic, message);
|
|
|
|
}
|
|
|
|
|
2013-10-04 16:01:48 +00:00
|
|
|
/*! Forward a endpoint's topics to an app */
|
2013-11-23 17:48:28 +00:00
|
|
|
static struct app_forwards *forwards_create_endpoint(struct stasis_app *app,
|
2013-10-04 16:01:48 +00:00
|
|
|
struct ast_endpoint *endpoint)
|
|
|
|
{
|
2015-09-04 12:25:07 -05:00
|
|
|
struct app_forwards *forwards;
|
|
|
|
int ret = 0;
|
2013-10-04 16:01:48 +00:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
if (!app) {
|
2013-10-04 16:01:48 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
forwards = forwards_create(app, endpoint ? ast_endpoint_get_id(endpoint) : ENDPOINT_ALL);
|
2013-10-04 16:01:48 +00:00
|
|
|
if (!forwards) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
forwards->forward_type = FORWARD_ENDPOINT;
|
2015-09-04 12:25:07 -05:00
|
|
|
if (endpoint) {
|
|
|
|
forwards->topic_forward = stasis_forward_all(ast_endpoint_topic(endpoint),
|
|
|
|
app->topic);
|
|
|
|
forwards->topic_cached_forward = stasis_forward_all(
|
|
|
|
ast_endpoint_topic_cached(endpoint), app->topic);
|
|
|
|
|
|
|
|
if (!forwards->topic_forward || !forwards->topic_cached_forward) {
|
|
|
|
/* Half-subscribed is a bad thing */
|
|
|
|
forwards_unsubscribe(forwards);
|
|
|
|
ao2_ref(forwards, -1);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Since endpoint subscriptions also subscribe to channels, in the case
|
|
|
|
* of all endpoint subscriptions, we only want messages for the endpoints.
|
|
|
|
* As such, we route those particular messages and then re-publish them
|
|
|
|
* on the app's topic.
|
|
|
|
*/
|
|
|
|
ast_assert(app->endpoint_router == NULL);
|
|
|
|
app->endpoint_router = stasis_message_router_create(ast_endpoint_topic_all_cached());
|
|
|
|
if (!app->endpoint_router) {
|
|
|
|
forwards_unsubscribe(forwards);
|
|
|
|
ao2_ref(forwards, -1);
|
|
|
|
return NULL;
|
|
|
|
}
|
2013-10-04 16:01:48 +00:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
ret |= stasis_message_router_add(app->endpoint_router,
|
|
|
|
ast_endpoint_state_type(), endpoint_state_cb, app);
|
|
|
|
ret |= stasis_message_router_add(app->endpoint_router,
|
|
|
|
ast_endpoint_contact_state_type(), endpoint_state_cb, app);
|
|
|
|
|
|
|
|
if (ret) {
|
|
|
|
ao2_ref(app->endpoint_router, -1);
|
|
|
|
app->endpoint_router = NULL;
|
|
|
|
ao2_ref(forwards, -1);
|
|
|
|
return NULL;
|
|
|
|
}
|
2013-10-04 16:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return forwards;
|
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
static int forwards_sort(const void *obj_left, const void *obj_right, int flags)
|
|
|
|
{
|
2013-10-25 22:03:04 +00:00
|
|
|
const struct app_forwards *object_left = obj_left;
|
|
|
|
const struct app_forwards *object_right = obj_right;
|
|
|
|
const char *right_key = obj_right;
|
|
|
|
int cmp;
|
|
|
|
|
|
|
|
switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
|
|
|
|
case OBJ_POINTER:
|
|
|
|
right_key = object_right->id;
|
|
|
|
/* Fall through */
|
|
|
|
case OBJ_KEY:
|
|
|
|
cmp = strcmp(object_left->id, right_key);
|
|
|
|
break;
|
|
|
|
case OBJ_PARTIAL_KEY:
|
|
|
|
/*
|
|
|
|
* We could also use a partial key struct containing a length
|
|
|
|
* so strlen() does not get called for every comparison instead.
|
|
|
|
*/
|
|
|
|
cmp = strncmp(object_left->id, right_key, strlen(right_key));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Sort can only work on something with a full or partial key. */
|
|
|
|
ast_assert(0);
|
|
|
|
cmp = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return cmp;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
|
|
|
|
2013-05-14 21:45:08 +00:00
|
|
|
static void app_dtor(void *obj)
|
|
|
|
{
|
2013-11-23 17:48:28 +00:00
|
|
|
struct stasis_app *app = obj;
|
2019-01-29 10:48:49 -06:00
|
|
|
size_t size = strlen("stasis-") + strlen(app->name) + 1;
|
|
|
|
char context_name[size];
|
2013-05-14 21:45:08 +00:00
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
ast_verb(1, "Destroying Stasis app %s\n", app->name);
|
|
|
|
|
|
|
|
ast_assert(app->router == NULL);
|
2014-02-01 16:26:57 +00:00
|
|
|
ast_assert(app->bridge_router == NULL);
|
2015-09-04 12:25:07 -05:00
|
|
|
ast_assert(app->endpoint_router == NULL);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2019-01-29 10:48:49 -06:00
|
|
|
/* If we created a context for this application, remove it */
|
|
|
|
strcpy(context_name, "stasis-");
|
|
|
|
strcat(context_name, app->name);
|
|
|
|
ast_context_destroy_by_name(context_name, "res_stasis");
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
ao2_cleanup(app->topic);
|
|
|
|
app->topic = NULL;
|
|
|
|
ao2_cleanup(app->forwards);
|
|
|
|
app->forwards = NULL;
|
2013-05-14 21:45:08 +00:00
|
|
|
ao2_cleanup(app->data);
|
|
|
|
app->data = NULL;
|
2019-02-08 14:48:27 -06:00
|
|
|
|
|
|
|
ast_json_unref(app->events_allowed);
|
|
|
|
app->events_allowed = NULL;
|
|
|
|
ast_json_unref(app->events_disallowed);
|
|
|
|
app->events_disallowed = NULL;
|
|
|
|
|
2013-05-14 21:45:08 +00:00
|
|
|
}
|
|
|
|
|
2013-12-14 17:19:41 +00:00
|
|
|
static void call_forwarded_handler(struct stasis_app *app, struct stasis_message *message)
|
|
|
|
{
|
|
|
|
struct ast_multi_channel_blob *payload = stasis_message_data(message);
|
|
|
|
struct ast_channel_snapshot *snapshot = ast_multi_channel_blob_get_channel(payload, "forwarded");
|
|
|
|
struct ast_channel *chan;
|
|
|
|
|
|
|
|
if (!snapshot) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-11-07 13:18:34 -04:00
|
|
|
chan = ast_channel_get_by_name(snapshot->base->uniqueid);
|
2013-12-14 17:19:41 +00:00
|
|
|
if (!chan) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
app_subscribe_channel(app, chan);
|
|
|
|
ast_channel_unref(chan);
|
|
|
|
}
|
|
|
|
|
2019-01-10 15:34:32 -04:00
|
|
|
static void sub_subscription_change_handler(void *data, struct stasis_subscription *sub,
|
Multiple revisions 399887,400138,400178,400180-400181
........
r399887 | dlee | 2013-09-26 10:41:47 -0500 (Thu, 26 Sep 2013) | 1 line
Minor performance bump by not allocate manager variable struct if we don't need it
........
r400138 | dlee | 2013-09-30 10:24:00 -0500 (Mon, 30 Sep 2013) | 23 lines
Stasis performance improvements
This patch addresses several performance problems that were found in
the initial performance testing of Asterisk 12.
The Stasis dispatch object was allocated as an AO2 object, even though
it has a very confined lifecycle. This was replaced with a straight
ast_malloc().
The Stasis message router was spending an inordinate amount of time
searching hash tables. In this case, most of our routers had 6 or
fewer routes in them to begin with. This was replaced with an array
that's searched linearly for the route.
We more heavily rely on AO2 objects in Asterisk 12, and the memset()
in ao2_ref() actually became noticeable on the profile. This was
#ifdef'ed to only run when AO2_DEBUG was enabled.
After being misled by an erroneous comment in taskprocessor.c during
profiling, the wrong comment was removed.
Review: https://reviewboard.asterisk.org/r/2873/
........
r400178 | dlee | 2013-09-30 13:26:27 -0500 (Mon, 30 Sep 2013) | 24 lines
Taskprocessor optimization; switch Stasis to use taskprocessors
This patch optimizes taskprocessor to use a semaphore for signaling,
which the OS can do a better job at managing contention and waiting
that we can with a mutex and condition.
The taskprocessor execution was also slightly optimized to reduce the
number of locks taken.
The only observable difference in the taskprocessor implementation is
that when the final reference to the taskprocessor goes away, it will
execute all tasks to completion instead of discarding the unexecuted
tasks.
For systems where unnamed semaphores are not supported, a really
simple semaphore implementation is provided. (Which gives identical
performance as the original taskprocessor implementation).
The way we ended up implementing Stasis caused the threadpool to be a
burden instead of a boost to performance. This was switched to just
use taskprocessors directly for subscriptions.
Review: https://reviewboard.asterisk.org/r/2881/
........
r400180 | dlee | 2013-09-30 13:39:34 -0500 (Mon, 30 Sep 2013) | 28 lines
Optimize how Stasis forwards are dispatched
This patch optimizes how forwards are dispatched in Stasis.
Originally, forwards were dispatched as subscriptions that are invoked
on the publishing thread. This did not account for the vast number of
forwards we would end up having in the system, and the amount of work it
would take to walk though the forward subscriptions.
This patch modifies Stasis so that rather than walking the tree of
forwards on every dispatch, when forwards and subscriptions are changed,
the subscriber list for every topic in the tree is changed.
This has a couple of benefits. First, this reduces the workload of
dispatching messages. It also reduces contention when dispatching to
different topics that happen to forward to the same aggregation topic
(as happens with all of the channel, bridge and endpoint topics).
Since forwards are no longer subscriptions, the bulk of this patch is
simply changing stasis_subscription objects to stasis_forward objects
(which, admittedly, I should have done in the first place.)
Since this required me to yet again put in a growing array, I finally
abstracted that out into a set of ast_vector macros in
asterisk/vector.h.
Review: https://reviewboard.asterisk.org/r/2883/
........
r400181 | dlee | 2013-09-30 13:48:57 -0500 (Mon, 30 Sep 2013) | 28 lines
Remove dispatch object allocation from Stasis publishing
While looking for areas for performance improvement, I realized that an
unused feature in Stasis was negatively impacting performance.
When a message is sent to a subscriber, a dispatch object is allocated
for the dispatch, containing the topic the message was published to, the
subscriber the message is being sent to, and the message itself.
The topic is actually unused by any subscriber in Asterisk today. And
the subscriber is associated with the taskprocessor the message is being
dispatched to.
First, this patch removes the unused topic parameter from Stasis
subscription callbacks.
Second, this patch introduces the concept of taskprocessor local data,
data that may be set on a taskprocessor and provided along with the data
pointer when a task is pushed using the ast_taskprocessor_push_local()
call. This allows the task to have both data specific to that
taskprocessor, in addition to data specific to that invocation.
With those two changes, the dispatch object can be removed completely,
and the message is simply refcounted and sent directly to the
taskprocessor.
Review: https://reviewboard.asterisk.org/r/2884/
........
Merged revisions 399887,400138,400178,400180-400181 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@400186 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-09-30 18:55:27 +00:00
|
|
|
struct stasis_message *message)
|
2013-05-14 21:45:08 +00:00
|
|
|
{
|
2013-11-23 17:48:28 +00:00
|
|
|
struct stasis_app *app = data;
|
2013-05-14 21:45:08 +00:00
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
if (stasis_subscription_final_message(sub, message)) {
|
|
|
|
ao2_cleanup(app);
|
|
|
|
}
|
2019-01-10 15:34:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_default_handler(void *data, struct stasis_subscription *sub,
|
|
|
|
struct stasis_message *message)
|
|
|
|
{
|
|
|
|
struct stasis_app *app = data;
|
|
|
|
struct ast_json *json;
|
2013-05-14 21:45:08 +00:00
|
|
|
|
2019-01-10 15:34:32 -04:00
|
|
|
/* The dial type can be converted to JSON so it will always be passed
|
|
|
|
* here.
|
|
|
|
*/
|
2013-12-14 17:19:41 +00:00
|
|
|
if (stasis_message_type(message) == ast_channel_dial_type()) {
|
|
|
|
call_forwarded_handler(app, message);
|
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
/* By default, send any message that has a JSON representation */
|
2013-11-22 20:10:46 +00:00
|
|
|
json = stasis_message_to_json(message, stasis_app_get_sanitizer());
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
if (!json) {
|
|
|
|
return;
|
|
|
|
}
|
2013-07-23 13:42:46 +00:00
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
app_send(app, json);
|
2018-01-06 03:17:15 -05:00
|
|
|
ast_json_unref(json);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
2013-05-14 21:45:08 +00:00
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
/*! \brief Typedef for callbacks that get called on channel snapshot updates */
|
|
|
|
typedef struct ast_json *(*channel_snapshot_monitor)(
|
|
|
|
struct ast_channel_snapshot *old_snapshot,
|
|
|
|
struct ast_channel_snapshot *new_snapshot,
|
|
|
|
const struct timeval *tv);
|
|
|
|
|
|
|
|
static struct ast_json *simple_channel_event(
|
|
|
|
const char *type,
|
|
|
|
struct ast_channel_snapshot *snapshot,
|
|
|
|
const struct timeval *tv)
|
|
|
|
{
|
2013-11-22 20:10:46 +00:00
|
|
|
struct ast_json *json_channel = ast_channel_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
|
|
|
|
|
|
|
|
if (!json_channel) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return ast_json_pack("{s: s, s: o, s: o}",
|
|
|
|
"type", type,
|
|
|
|
"timestamp", ast_json_timeval(*tv, NULL),
|
2013-11-22 20:10:46 +00:00
|
|
|
"channel", json_channel);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct ast_json *channel_created_event(
|
|
|
|
struct ast_channel_snapshot *snapshot,
|
|
|
|
const struct timeval *tv)
|
|
|
|
{
|
|
|
|
return simple_channel_event("ChannelCreated", snapshot, tv);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct ast_json *channel_destroyed_event(
|
|
|
|
struct ast_channel_snapshot *snapshot,
|
|
|
|
const struct timeval *tv)
|
|
|
|
{
|
2013-11-22 20:10:46 +00:00
|
|
|
struct ast_json *json_channel = ast_channel_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
|
|
|
|
|
|
|
|
if (!json_channel) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return ast_json_pack("{s: s, s: o, s: i, s: s, s: o}",
|
|
|
|
"type", "ChannelDestroyed",
|
|
|
|
"timestamp", ast_json_timeval(*tv, NULL),
|
2018-11-07 13:18:34 -04:00
|
|
|
"cause", snapshot->hangup->cause,
|
|
|
|
"cause_txt", ast_cause2str(snapshot->hangup->cause),
|
2013-11-22 20:10:46 +00:00
|
|
|
"channel", json_channel);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct ast_json *channel_state_change_event(
|
|
|
|
struct ast_channel_snapshot *snapshot,
|
|
|
|
const struct timeval *tv)
|
|
|
|
{
|
|
|
|
return simple_channel_event("ChannelStateChange", snapshot, tv);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*! \brief Handle channel state changes */
|
|
|
|
static struct ast_json *channel_state(
|
|
|
|
struct ast_channel_snapshot *old_snapshot,
|
|
|
|
struct ast_channel_snapshot *new_snapshot,
|
|
|
|
const struct timeval *tv)
|
|
|
|
{
|
|
|
|
struct ast_channel_snapshot *snapshot = new_snapshot ?
|
|
|
|
new_snapshot : old_snapshot;
|
|
|
|
|
|
|
|
if (!old_snapshot) {
|
|
|
|
return channel_created_event(snapshot, tv);
|
2018-10-10 11:28:18 -03:00
|
|
|
} else if (ast_test_flag(&new_snapshot->flags, AST_FLAG_DEAD)) {
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return channel_destroyed_event(snapshot, tv);
|
|
|
|
} else if (old_snapshot->state != new_snapshot->state) {
|
|
|
|
return channel_state_change_event(snapshot, tv);
|
2013-05-14 21:45:08 +00:00
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2013-05-14 21:45:08 +00:00
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
static struct ast_json *channel_dialplan(
|
|
|
|
struct ast_channel_snapshot *old_snapshot,
|
|
|
|
struct ast_channel_snapshot *new_snapshot,
|
|
|
|
const struct timeval *tv)
|
|
|
|
{
|
2013-11-22 20:10:46 +00:00
|
|
|
struct ast_json *json_channel;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2018-10-10 11:28:18 -03:00
|
|
|
/* No Newexten event on first channel snapshot */
|
|
|
|
if (!old_snapshot) {
|
2013-05-14 21:45:08 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
/* Empty application is not valid for a Newexten event */
|
2018-11-07 13:18:34 -04:00
|
|
|
if (ast_strlen_zero(new_snapshot->dialplan->appl)) {
|
2013-06-10 13:07:11 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
if (ast_channel_snapshot_cep_equal(old_snapshot, new_snapshot)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-11-22 20:10:46 +00:00
|
|
|
json_channel = ast_channel_snapshot_to_json(new_snapshot, stasis_app_get_sanitizer());
|
|
|
|
if (!json_channel) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return ast_json_pack("{s: s, s: o, s: s, s: s, s: o}",
|
|
|
|
"type", "ChannelDialplan",
|
|
|
|
"timestamp", ast_json_timeval(*tv, NULL),
|
2018-11-07 13:18:34 -04:00
|
|
|
"dialplan_app", new_snapshot->dialplan->appl,
|
|
|
|
"dialplan_app_data", AST_JSON_UTF8_VALIDATE(new_snapshot->dialplan->data),
|
2013-11-22 20:10:46 +00:00
|
|
|
"channel", json_channel);
|
2013-05-14 21:45:08 +00:00
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
static struct ast_json *channel_callerid(
|
|
|
|
struct ast_channel_snapshot *old_snapshot,
|
|
|
|
struct ast_channel_snapshot *new_snapshot,
|
|
|
|
const struct timeval *tv)
|
2013-05-14 21:45:08 +00:00
|
|
|
{
|
2013-11-22 20:10:46 +00:00
|
|
|
struct ast_json *json_channel;
|
2013-07-23 13:42:46 +00:00
|
|
|
|
2018-10-10 11:28:18 -03:00
|
|
|
/* No NewCallerid event on first channel snapshot */
|
|
|
|
if (!old_snapshot) {
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2013-07-23 13:42:46 +00:00
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
if (ast_channel_snapshot_caller_id_equal(old_snapshot, new_snapshot)) {
|
|
|
|
return NULL;
|
2013-07-23 13:42:46 +00:00
|
|
|
}
|
2013-05-14 21:45:08 +00:00
|
|
|
|
2013-11-22 20:10:46 +00:00
|
|
|
json_channel = ast_channel_snapshot_to_json(new_snapshot, stasis_app_get_sanitizer());
|
|
|
|
if (!json_channel) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return ast_json_pack("{s: s, s: o, s: i, s: s, s: o}",
|
|
|
|
"type", "ChannelCallerId",
|
|
|
|
"timestamp", ast_json_timeval(*tv, NULL),
|
2018-11-07 13:18:34 -04:00
|
|
|
"caller_presentation", new_snapshot->caller->pres,
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
"caller_presentation_txt", ast_describe_caller_presentation(
|
2018-11-07 13:18:34 -04:00
|
|
|
new_snapshot->caller->pres),
|
2013-11-22 20:10:46 +00:00
|
|
|
"channel", json_channel);
|
2013-05-14 21:45:08 +00:00
|
|
|
}
|
|
|
|
|
2014-12-08 16:24:36 +00:00
|
|
|
static struct ast_json *channel_connected_line(
|
|
|
|
struct ast_channel_snapshot *old_snapshot,
|
|
|
|
struct ast_channel_snapshot *new_snapshot,
|
|
|
|
const struct timeval *tv)
|
|
|
|
{
|
|
|
|
struct ast_json *json_channel;
|
|
|
|
|
2018-10-10 11:28:18 -03:00
|
|
|
/* No ChannelConnectedLine event on first channel snapshot */
|
|
|
|
if (!old_snapshot) {
|
2014-12-08 16:24:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ast_channel_snapshot_connected_line_equal(old_snapshot, new_snapshot)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
json_channel = ast_channel_snapshot_to_json(new_snapshot, stasis_app_get_sanitizer());
|
|
|
|
if (!json_channel) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ast_json_pack("{s: s, s: o, s: o}",
|
|
|
|
"type", "ChannelConnectedLine",
|
|
|
|
"timestamp", ast_json_timeval(*tv, NULL),
|
|
|
|
"channel", json_channel);
|
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
static channel_snapshot_monitor channel_monitors[] = {
|
|
|
|
channel_state,
|
|
|
|
channel_dialplan,
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
channel_callerid,
|
2014-12-08 16:24:36 +00:00
|
|
|
channel_connected_line,
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void sub_channel_update_handler(void *data,
|
2013-10-25 22:03:04 +00:00
|
|
|
struct stasis_subscription *sub,
|
|
|
|
struct stasis_message *message)
|
2013-05-14 21:45:08 +00:00
|
|
|
{
|
2013-11-23 17:48:28 +00:00
|
|
|
struct stasis_app *app = data;
|
2018-10-10 11:28:18 -03:00
|
|
|
struct ast_channel_snapshot_update *update = stasis_message_data(message);
|
2013-10-25 22:03:04 +00:00
|
|
|
int i;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2013-10-25 22:03:04 +00:00
|
|
|
for (i = 0; i < ARRAY_LEN(channel_monitors); ++i) {
|
2018-01-06 03:17:15 -05:00
|
|
|
struct ast_json *msg;
|
2013-05-14 21:45:08 +00:00
|
|
|
|
2018-10-10 11:28:18 -03:00
|
|
|
msg = channel_monitors[i](update->old_snapshot, update->new_snapshot,
|
|
|
|
stasis_message_timestamp(message));
|
2013-10-25 22:03:04 +00:00
|
|
|
if (msg) {
|
|
|
|
app_send(app, msg);
|
2018-01-06 03:17:15 -05:00
|
|
|
ast_json_unref(msg);
|
2013-10-25 22:03:04 +00:00
|
|
|
}
|
|
|
|
}
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
|
2018-10-10 11:28:18 -03:00
|
|
|
if (ast_test_flag(&update->new_snapshot->flags, AST_FLAG_DEAD)) {
|
2018-11-07 13:18:34 -04:00
|
|
|
unsubscribe(app, "channel", update->new_snapshot->base->uniqueid, 1);
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
}
|
2013-05-14 21:45:08 +00:00
|
|
|
}
|
|
|
|
|
2013-10-04 16:01:48 +00:00
|
|
|
static struct ast_json *simple_endpoint_event(
|
2013-10-25 22:03:04 +00:00
|
|
|
const char *type,
|
|
|
|
struct ast_endpoint_snapshot *snapshot,
|
|
|
|
const struct timeval *tv)
|
2013-10-04 16:01:48 +00:00
|
|
|
{
|
2013-11-22 20:10:46 +00:00
|
|
|
struct ast_json *json_endpoint = ast_endpoint_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
|
|
|
|
|
|
|
|
if (!json_endpoint) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-10-25 22:03:04 +00:00
|
|
|
return ast_json_pack("{s: s, s: o, s: o}",
|
|
|
|
"type", type,
|
|
|
|
"timestamp", ast_json_timeval(*tv, NULL),
|
2013-11-22 20:10:46 +00:00
|
|
|
"endpoint", json_endpoint);
|
2013-10-04 16:01:48 +00:00
|
|
|
}
|
|
|
|
|
Multiple revisions 420089-420090,420097
........
r420089 | mjordan | 2014-08-05 15:10:52 -0500 (Tue, 05 Aug 2014) | 72 lines
ARI: Add channel technology agnostic out of call text messaging
This patch adds the ability to send and receive text messages from various
technology stacks in Asterisk through ARI. This includes chan_sip (sip),
res_pjsip_messaging (pjsip), and res_xmpp (xmpp). Messages are sent using the
endpoints resource, and can be sent directly through that resource, or to a
particular endpoint.
For example, the following would send the message "Hello there" to PJSIP
endpoint alice with a display URI of sip:asterisk@mycooldomain.org:
ari/endpoints/sendMessage?to=pjsip:alice&from=sip:asterisk@mycooldomain.org&body=Hello+There
This is equivalent to the following as well:
ari/endpoints/PJSIP/alice/sendMessage?from=sip:asterisk@mycooldomain.org&body=Hello+There
Both forms are available for message technologies that allow for arbitrary
destinations, such as chan_sip.
Inbound messages can now be received over ARI as well. An ARI application that
subscribes to endpoints will receive messages from those endpoints:
{
"type": "TextMessageReceived",
"timestamp": "2014-07-12T22:53:13.494-0500",
"endpoint": {
"technology": "PJSIP",
"resource": "alice",
"state": "online",
"channel_ids": []
},
"message": {
"from": "\"alice\" <sip:alice@127.0.0.1>",
"to": "pjsip:asterisk@127.0.0.1",
"body": "Watson, come here.",
"variables": []
},
"application": "testsuite"
}
The above was made possible due to some rather major changes in the message
core. This includes (but is not limited to):
- Users of the message API can now register message handlers. A handler has
two callbacks: one to determine if the handler has a destination for the
message, and another to handle it.
- All dialplan functionality of handling a message was moved into a message
handler provided by the message API.
- Messages can now have the technology/endpoint associated with them.
Various other properties are also now more easily accessible.
- A number of ao2 containers that weren't really needed were replaced with
vectors. Iteration over ao2_containers is expensive and pointless when
the lifetime of things is well defined and the number of things is very
small.
res_stasis now has a new file that makes up its structure, messaging. The
messaging functionality implements a message handler, and passes received
messages that match an interested endpoint over to the app for processing.
Note that inadvertently while testing this, I reproduced ASTERISK-23969.
res_pjsip_messaging was incorrectly parsing out the 'to' field, such that
arbitrary SIP URIs mangled the endpoint lookup. This patch includes the
fix for that as well.
Review: https://reviewboard.asterisk.org/r/3726
ASTERISK-23692 #close
Reported by: Matt Jordan
ASTERISK-23969 #close
Reported by: Andrew Nagy
........
r420090 | mjordan | 2014-08-05 15:16:37 -0500 (Tue, 05 Aug 2014) | 2 lines
Remove automerge properties :-(
........
r420097 | mjordan | 2014-08-05 16:36:25 -0500 (Tue, 05 Aug 2014) | 2 lines
test_message: Fix strict-aliasing compilation issue
........
Merged revisions 420089-420090,420097 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@420098 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-08-05 21:44:09 +00:00
|
|
|
static int message_received_handler(const char *endpoint_id, struct ast_json *json_msg, void *pvt)
|
|
|
|
{
|
2018-01-06 03:17:15 -05:00
|
|
|
struct ast_endpoint_snapshot *snapshot;
|
Multiple revisions 420089-420090,420097
........
r420089 | mjordan | 2014-08-05 15:10:52 -0500 (Tue, 05 Aug 2014) | 72 lines
ARI: Add channel technology agnostic out of call text messaging
This patch adds the ability to send and receive text messages from various
technology stacks in Asterisk through ARI. This includes chan_sip (sip),
res_pjsip_messaging (pjsip), and res_xmpp (xmpp). Messages are sent using the
endpoints resource, and can be sent directly through that resource, or to a
particular endpoint.
For example, the following would send the message "Hello there" to PJSIP
endpoint alice with a display URI of sip:asterisk@mycooldomain.org:
ari/endpoints/sendMessage?to=pjsip:alice&from=sip:asterisk@mycooldomain.org&body=Hello+There
This is equivalent to the following as well:
ari/endpoints/PJSIP/alice/sendMessage?from=sip:asterisk@mycooldomain.org&body=Hello+There
Both forms are available for message technologies that allow for arbitrary
destinations, such as chan_sip.
Inbound messages can now be received over ARI as well. An ARI application that
subscribes to endpoints will receive messages from those endpoints:
{
"type": "TextMessageReceived",
"timestamp": "2014-07-12T22:53:13.494-0500",
"endpoint": {
"technology": "PJSIP",
"resource": "alice",
"state": "online",
"channel_ids": []
},
"message": {
"from": "\"alice\" <sip:alice@127.0.0.1>",
"to": "pjsip:asterisk@127.0.0.1",
"body": "Watson, come here.",
"variables": []
},
"application": "testsuite"
}
The above was made possible due to some rather major changes in the message
core. This includes (but is not limited to):
- Users of the message API can now register message handlers. A handler has
two callbacks: one to determine if the handler has a destination for the
message, and another to handle it.
- All dialplan functionality of handling a message was moved into a message
handler provided by the message API.
- Messages can now have the technology/endpoint associated with them.
Various other properties are also now more easily accessible.
- A number of ao2 containers that weren't really needed were replaced with
vectors. Iteration over ao2_containers is expensive and pointless when
the lifetime of things is well defined and the number of things is very
small.
res_stasis now has a new file that makes up its structure, messaging. The
messaging functionality implements a message handler, and passes received
messages that match an interested endpoint over to the app for processing.
Note that inadvertently while testing this, I reproduced ASTERISK-23969.
res_pjsip_messaging was incorrectly parsing out the 'to' field, such that
arbitrary SIP URIs mangled the endpoint lookup. This patch includes the
fix for that as well.
Review: https://reviewboard.asterisk.org/r/3726
ASTERISK-23692 #close
Reported by: Matt Jordan
ASTERISK-23969 #close
Reported by: Andrew Nagy
........
r420090 | mjordan | 2014-08-05 15:16:37 -0500 (Tue, 05 Aug 2014) | 2 lines
Remove automerge properties :-(
........
r420097 | mjordan | 2014-08-05 16:36:25 -0500 (Tue, 05 Aug 2014) | 2 lines
test_message: Fix strict-aliasing compilation issue
........
Merged revisions 420089-420090,420097 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@420098 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-08-05 21:44:09 +00:00
|
|
|
struct ast_json *json_endpoint;
|
2017-11-06 18:21:53 -05:00
|
|
|
struct ast_json *message;
|
Multiple revisions 420089-420090,420097
........
r420089 | mjordan | 2014-08-05 15:10:52 -0500 (Tue, 05 Aug 2014) | 72 lines
ARI: Add channel technology agnostic out of call text messaging
This patch adds the ability to send and receive text messages from various
technology stacks in Asterisk through ARI. This includes chan_sip (sip),
res_pjsip_messaging (pjsip), and res_xmpp (xmpp). Messages are sent using the
endpoints resource, and can be sent directly through that resource, or to a
particular endpoint.
For example, the following would send the message "Hello there" to PJSIP
endpoint alice with a display URI of sip:asterisk@mycooldomain.org:
ari/endpoints/sendMessage?to=pjsip:alice&from=sip:asterisk@mycooldomain.org&body=Hello+There
This is equivalent to the following as well:
ari/endpoints/PJSIP/alice/sendMessage?from=sip:asterisk@mycooldomain.org&body=Hello+There
Both forms are available for message technologies that allow for arbitrary
destinations, such as chan_sip.
Inbound messages can now be received over ARI as well. An ARI application that
subscribes to endpoints will receive messages from those endpoints:
{
"type": "TextMessageReceived",
"timestamp": "2014-07-12T22:53:13.494-0500",
"endpoint": {
"technology": "PJSIP",
"resource": "alice",
"state": "online",
"channel_ids": []
},
"message": {
"from": "\"alice\" <sip:alice@127.0.0.1>",
"to": "pjsip:asterisk@127.0.0.1",
"body": "Watson, come here.",
"variables": []
},
"application": "testsuite"
}
The above was made possible due to some rather major changes in the message
core. This includes (but is not limited to):
- Users of the message API can now register message handlers. A handler has
two callbacks: one to determine if the handler has a destination for the
message, and another to handle it.
- All dialplan functionality of handling a message was moved into a message
handler provided by the message API.
- Messages can now have the technology/endpoint associated with them.
Various other properties are also now more easily accessible.
- A number of ao2 containers that weren't really needed were replaced with
vectors. Iteration over ao2_containers is expensive and pointless when
the lifetime of things is well defined and the number of things is very
small.
res_stasis now has a new file that makes up its structure, messaging. The
messaging functionality implements a message handler, and passes received
messages that match an interested endpoint over to the app for processing.
Note that inadvertently while testing this, I reproduced ASTERISK-23969.
res_pjsip_messaging was incorrectly parsing out the 'to' field, such that
arbitrary SIP URIs mangled the endpoint lookup. This patch includes the
fix for that as well.
Review: https://reviewboard.asterisk.org/r/3726
ASTERISK-23692 #close
Reported by: Matt Jordan
ASTERISK-23969 #close
Reported by: Andrew Nagy
........
r420090 | mjordan | 2014-08-05 15:16:37 -0500 (Tue, 05 Aug 2014) | 2 lines
Remove automerge properties :-(
........
r420097 | mjordan | 2014-08-05 16:36:25 -0500 (Tue, 05 Aug 2014) | 2 lines
test_message: Fix strict-aliasing compilation issue
........
Merged revisions 420089-420090,420097 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@420098 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-08-05 21:44:09 +00:00
|
|
|
struct stasis_app *app = pvt;
|
|
|
|
char *tech;
|
|
|
|
char *resource;
|
|
|
|
|
|
|
|
tech = ast_strdupa(endpoint_id);
|
|
|
|
resource = strchr(tech, '/');
|
|
|
|
if (resource) {
|
|
|
|
resource[0] = '\0';
|
|
|
|
resource++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ast_strlen_zero(tech) || ast_strlen_zero(resource)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
snapshot = ast_endpoint_latest_snapshot(tech, resource);
|
|
|
|
if (!snapshot) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
json_endpoint = ast_endpoint_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_ref(snapshot, -1);
|
Multiple revisions 420089-420090,420097
........
r420089 | mjordan | 2014-08-05 15:10:52 -0500 (Tue, 05 Aug 2014) | 72 lines
ARI: Add channel technology agnostic out of call text messaging
This patch adds the ability to send and receive text messages from various
technology stacks in Asterisk through ARI. This includes chan_sip (sip),
res_pjsip_messaging (pjsip), and res_xmpp (xmpp). Messages are sent using the
endpoints resource, and can be sent directly through that resource, or to a
particular endpoint.
For example, the following would send the message "Hello there" to PJSIP
endpoint alice with a display URI of sip:asterisk@mycooldomain.org:
ari/endpoints/sendMessage?to=pjsip:alice&from=sip:asterisk@mycooldomain.org&body=Hello+There
This is equivalent to the following as well:
ari/endpoints/PJSIP/alice/sendMessage?from=sip:asterisk@mycooldomain.org&body=Hello+There
Both forms are available for message technologies that allow for arbitrary
destinations, such as chan_sip.
Inbound messages can now be received over ARI as well. An ARI application that
subscribes to endpoints will receive messages from those endpoints:
{
"type": "TextMessageReceived",
"timestamp": "2014-07-12T22:53:13.494-0500",
"endpoint": {
"technology": "PJSIP",
"resource": "alice",
"state": "online",
"channel_ids": []
},
"message": {
"from": "\"alice\" <sip:alice@127.0.0.1>",
"to": "pjsip:asterisk@127.0.0.1",
"body": "Watson, come here.",
"variables": []
},
"application": "testsuite"
}
The above was made possible due to some rather major changes in the message
core. This includes (but is not limited to):
- Users of the message API can now register message handlers. A handler has
two callbacks: one to determine if the handler has a destination for the
message, and another to handle it.
- All dialplan functionality of handling a message was moved into a message
handler provided by the message API.
- Messages can now have the technology/endpoint associated with them.
Various other properties are also now more easily accessible.
- A number of ao2 containers that weren't really needed were replaced with
vectors. Iteration over ao2_containers is expensive and pointless when
the lifetime of things is well defined and the number of things is very
small.
res_stasis now has a new file that makes up its structure, messaging. The
messaging functionality implements a message handler, and passes received
messages that match an interested endpoint over to the app for processing.
Note that inadvertently while testing this, I reproduced ASTERISK-23969.
res_pjsip_messaging was incorrectly parsing out the 'to' field, such that
arbitrary SIP URIs mangled the endpoint lookup. This patch includes the
fix for that as well.
Review: https://reviewboard.asterisk.org/r/3726
ASTERISK-23692 #close
Reported by: Matt Jordan
ASTERISK-23969 #close
Reported by: Andrew Nagy
........
r420090 | mjordan | 2014-08-05 15:16:37 -0500 (Tue, 05 Aug 2014) | 2 lines
Remove automerge properties :-(
........
r420097 | mjordan | 2014-08-05 16:36:25 -0500 (Tue, 05 Aug 2014) | 2 lines
test_message: Fix strict-aliasing compilation issue
........
Merged revisions 420089-420090,420097 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@420098 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-08-05 21:44:09 +00:00
|
|
|
if (!json_endpoint) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-11-06 18:21:53 -05:00
|
|
|
message = ast_json_pack("{s: s, s: o, s: o, s: o}",
|
Multiple revisions 420089-420090,420097
........
r420089 | mjordan | 2014-08-05 15:10:52 -0500 (Tue, 05 Aug 2014) | 72 lines
ARI: Add channel technology agnostic out of call text messaging
This patch adds the ability to send and receive text messages from various
technology stacks in Asterisk through ARI. This includes chan_sip (sip),
res_pjsip_messaging (pjsip), and res_xmpp (xmpp). Messages are sent using the
endpoints resource, and can be sent directly through that resource, or to a
particular endpoint.
For example, the following would send the message "Hello there" to PJSIP
endpoint alice with a display URI of sip:asterisk@mycooldomain.org:
ari/endpoints/sendMessage?to=pjsip:alice&from=sip:asterisk@mycooldomain.org&body=Hello+There
This is equivalent to the following as well:
ari/endpoints/PJSIP/alice/sendMessage?from=sip:asterisk@mycooldomain.org&body=Hello+There
Both forms are available for message technologies that allow for arbitrary
destinations, such as chan_sip.
Inbound messages can now be received over ARI as well. An ARI application that
subscribes to endpoints will receive messages from those endpoints:
{
"type": "TextMessageReceived",
"timestamp": "2014-07-12T22:53:13.494-0500",
"endpoint": {
"technology": "PJSIP",
"resource": "alice",
"state": "online",
"channel_ids": []
},
"message": {
"from": "\"alice\" <sip:alice@127.0.0.1>",
"to": "pjsip:asterisk@127.0.0.1",
"body": "Watson, come here.",
"variables": []
},
"application": "testsuite"
}
The above was made possible due to some rather major changes in the message
core. This includes (but is not limited to):
- Users of the message API can now register message handlers. A handler has
two callbacks: one to determine if the handler has a destination for the
message, and another to handle it.
- All dialplan functionality of handling a message was moved into a message
handler provided by the message API.
- Messages can now have the technology/endpoint associated with them.
Various other properties are also now more easily accessible.
- A number of ao2 containers that weren't really needed were replaced with
vectors. Iteration over ao2_containers is expensive and pointless when
the lifetime of things is well defined and the number of things is very
small.
res_stasis now has a new file that makes up its structure, messaging. The
messaging functionality implements a message handler, and passes received
messages that match an interested endpoint over to the app for processing.
Note that inadvertently while testing this, I reproduced ASTERISK-23969.
res_pjsip_messaging was incorrectly parsing out the 'to' field, such that
arbitrary SIP URIs mangled the endpoint lookup. This patch includes the
fix for that as well.
Review: https://reviewboard.asterisk.org/r/3726
ASTERISK-23692 #close
Reported by: Matt Jordan
ASTERISK-23969 #close
Reported by: Andrew Nagy
........
r420090 | mjordan | 2014-08-05 15:16:37 -0500 (Tue, 05 Aug 2014) | 2 lines
Remove automerge properties :-(
........
r420097 | mjordan | 2014-08-05 16:36:25 -0500 (Tue, 05 Aug 2014) | 2 lines
test_message: Fix strict-aliasing compilation issue
........
Merged revisions 420089-420090,420097 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@420098 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-08-05 21:44:09 +00:00
|
|
|
"type", "TextMessageReceived",
|
|
|
|
"timestamp", ast_json_timeval(ast_tvnow(), NULL),
|
|
|
|
"endpoint", json_endpoint,
|
2017-11-06 18:21:53 -05:00
|
|
|
"message", ast_json_ref(json_msg));
|
|
|
|
if (message) {
|
|
|
|
app_send(app, message);
|
|
|
|
ast_json_unref(message);
|
|
|
|
}
|
Multiple revisions 420089-420090,420097
........
r420089 | mjordan | 2014-08-05 15:10:52 -0500 (Tue, 05 Aug 2014) | 72 lines
ARI: Add channel technology agnostic out of call text messaging
This patch adds the ability to send and receive text messages from various
technology stacks in Asterisk through ARI. This includes chan_sip (sip),
res_pjsip_messaging (pjsip), and res_xmpp (xmpp). Messages are sent using the
endpoints resource, and can be sent directly through that resource, or to a
particular endpoint.
For example, the following would send the message "Hello there" to PJSIP
endpoint alice with a display URI of sip:asterisk@mycooldomain.org:
ari/endpoints/sendMessage?to=pjsip:alice&from=sip:asterisk@mycooldomain.org&body=Hello+There
This is equivalent to the following as well:
ari/endpoints/PJSIP/alice/sendMessage?from=sip:asterisk@mycooldomain.org&body=Hello+There
Both forms are available for message technologies that allow for arbitrary
destinations, such as chan_sip.
Inbound messages can now be received over ARI as well. An ARI application that
subscribes to endpoints will receive messages from those endpoints:
{
"type": "TextMessageReceived",
"timestamp": "2014-07-12T22:53:13.494-0500",
"endpoint": {
"technology": "PJSIP",
"resource": "alice",
"state": "online",
"channel_ids": []
},
"message": {
"from": "\"alice\" <sip:alice@127.0.0.1>",
"to": "pjsip:asterisk@127.0.0.1",
"body": "Watson, come here.",
"variables": []
},
"application": "testsuite"
}
The above was made possible due to some rather major changes in the message
core. This includes (but is not limited to):
- Users of the message API can now register message handlers. A handler has
two callbacks: one to determine if the handler has a destination for the
message, and another to handle it.
- All dialplan functionality of handling a message was moved into a message
handler provided by the message API.
- Messages can now have the technology/endpoint associated with them.
Various other properties are also now more easily accessible.
- A number of ao2 containers that weren't really needed were replaced with
vectors. Iteration over ao2_containers is expensive and pointless when
the lifetime of things is well defined and the number of things is very
small.
res_stasis now has a new file that makes up its structure, messaging. The
messaging functionality implements a message handler, and passes received
messages that match an interested endpoint over to the app for processing.
Note that inadvertently while testing this, I reproduced ASTERISK-23969.
res_pjsip_messaging was incorrectly parsing out the 'to' field, such that
arbitrary SIP URIs mangled the endpoint lookup. This patch includes the
fix for that as well.
Review: https://reviewboard.asterisk.org/r/3726
ASTERISK-23692 #close
Reported by: Matt Jordan
ASTERISK-23969 #close
Reported by: Andrew Nagy
........
r420090 | mjordan | 2014-08-05 15:16:37 -0500 (Tue, 05 Aug 2014) | 2 lines
Remove automerge properties :-(
........
r420097 | mjordan | 2014-08-05 16:36:25 -0500 (Tue, 05 Aug 2014) | 2 lines
test_message: Fix strict-aliasing compilation issue
........
Merged revisions 420089-420090,420097 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@420098 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-08-05 21:44:09 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-10-04 16:01:48 +00:00
|
|
|
static void sub_endpoint_update_handler(void *data,
|
2013-10-25 22:03:04 +00:00
|
|
|
struct stasis_subscription *sub,
|
|
|
|
struct stasis_message *message)
|
2013-10-04 16:01:48 +00:00
|
|
|
{
|
2013-11-23 17:48:28 +00:00
|
|
|
struct stasis_app *app = data;
|
2013-10-25 22:03:04 +00:00
|
|
|
struct stasis_cache_update *update;
|
|
|
|
struct ast_endpoint_snapshot *new_snapshot;
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
struct ast_endpoint_snapshot *old_snapshot;
|
2013-10-25 22:03:04 +00:00
|
|
|
const struct timeval *tv;
|
2013-10-04 16:01:48 +00:00
|
|
|
|
|
|
|
ast_assert(stasis_message_type(message) == stasis_cache_update_type());
|
|
|
|
|
|
|
|
update = stasis_message_data(message);
|
|
|
|
|
|
|
|
ast_assert(update->type == ast_endpoint_snapshot_type());
|
|
|
|
|
|
|
|
new_snapshot = stasis_message_data(update->new_snapshot);
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
old_snapshot = stasis_message_data(update->old_snapshot);
|
2013-10-04 16:01:48 +00:00
|
|
|
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
if (new_snapshot) {
|
2018-01-06 03:17:15 -05:00
|
|
|
struct ast_json *json;
|
|
|
|
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
tv = stasis_message_timestamp(update->new_snapshot);
|
2013-10-04 16:01:48 +00:00
|
|
|
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
json = simple_endpoint_event("EndpointStateChange", new_snapshot, tv);
|
|
|
|
if (!json) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
app_send(app, json);
|
2018-01-06 03:17:15 -05:00
|
|
|
ast_json_unref(json);
|
2013-10-25 22:03:04 +00:00
|
|
|
}
|
2013-10-04 16:01:48 +00:00
|
|
|
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
if (!new_snapshot && old_snapshot) {
|
|
|
|
unsubscribe(app, "endpoint", old_snapshot->id, 1);
|
|
|
|
}
|
2013-10-04 16:01:48 +00:00
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
static struct ast_json *simple_bridge_event(
|
2013-10-25 22:03:04 +00:00
|
|
|
const char *type,
|
|
|
|
struct ast_bridge_snapshot *snapshot,
|
|
|
|
const struct timeval *tv)
|
2013-06-10 13:07:11 +00:00
|
|
|
{
|
2013-11-22 20:10:46 +00:00
|
|
|
struct ast_json *json_bridge = ast_bridge_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
|
|
|
|
if (!json_bridge) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-10-25 22:03:04 +00:00
|
|
|
return ast_json_pack("{s: s, s: o, s: o}",
|
|
|
|
"type", type,
|
|
|
|
"timestamp", ast_json_timeval(*tv, NULL),
|
2013-11-22 20:10:46 +00:00
|
|
|
"bridge", json_bridge);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
2013-07-23 13:42:46 +00:00
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
static void sub_bridge_update_handler(void *data,
|
2013-10-25 22:03:04 +00:00
|
|
|
struct stasis_subscription *sub,
|
|
|
|
struct stasis_message *message)
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
{
|
2018-01-06 03:17:15 -05:00
|
|
|
struct ast_json *json = NULL;
|
2013-11-23 17:48:28 +00:00
|
|
|
struct stasis_app *app = data;
|
2018-09-19 13:34:41 -06:00
|
|
|
struct ast_bridge_snapshot_update *update;
|
2013-10-25 22:03:04 +00:00
|
|
|
const struct timeval *tv;
|
2013-07-23 13:42:46 +00:00
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
update = stasis_message_data(message);
|
|
|
|
|
2018-09-19 13:34:41 -06:00
|
|
|
tv = stasis_message_timestamp(message);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2018-09-19 13:34:41 -06:00
|
|
|
if (!update->new_snapshot) {
|
|
|
|
json = simple_bridge_event("BridgeDestroyed", update->old_snapshot, tv);
|
|
|
|
} else if (!update->old_snapshot) {
|
|
|
|
json = simple_bridge_event("BridgeCreated", update->new_snapshot, tv);
|
|
|
|
} else if (update->new_snapshot && update->old_snapshot
|
|
|
|
&& strcmp(update->new_snapshot->video_source_id, update->old_snapshot->video_source_id)) {
|
|
|
|
json = simple_bridge_event("BridgeVideoSourceChanged", update->new_snapshot, tv);
|
|
|
|
if (json && !ast_strlen_zero(update->old_snapshot->video_source_id)) {
|
2016-11-08 10:11:41 -06:00
|
|
|
ast_json_object_set(json, "old_video_source_id",
|
2018-09-19 13:34:41 -06:00
|
|
|
ast_json_string_create(update->old_snapshot->video_source_id));
|
2016-11-08 10:11:41 -06:00
|
|
|
}
|
2013-10-25 22:03:04 +00:00
|
|
|
}
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
if (json) {
|
|
|
|
app_send(app, json);
|
2018-01-06 03:17:15 -05:00
|
|
|
ast_json_unref(json);
|
2013-10-25 22:03:04 +00:00
|
|
|
}
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2018-09-19 13:34:41 -06:00
|
|
|
if (!update->new_snapshot && update->old_snapshot) {
|
|
|
|
unsubscribe(app, "bridge", update->old_snapshot->uniqueid, 1);
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
}
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
|
|
|
|
2014-02-01 16:26:57 +00:00
|
|
|
|
|
|
|
/*! \brief Helper function for determining if the application is subscribed to a given entity */
|
|
|
|
static int bridge_app_subscribed(struct stasis_app *app, const char *uniqueid)
|
|
|
|
{
|
|
|
|
struct app_forwards *forwards = NULL;
|
|
|
|
|
|
|
|
forwards = ao2_find(app->forwards, uniqueid, OBJ_SEARCH_KEY);
|
|
|
|
if (!forwards) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ao2_ref(forwards, -1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
static void bridge_merge_handler(void *data, struct stasis_subscription *sub,
|
Multiple revisions 399887,400138,400178,400180-400181
........
r399887 | dlee | 2013-09-26 10:41:47 -0500 (Thu, 26 Sep 2013) | 1 line
Minor performance bump by not allocate manager variable struct if we don't need it
........
r400138 | dlee | 2013-09-30 10:24:00 -0500 (Mon, 30 Sep 2013) | 23 lines
Stasis performance improvements
This patch addresses several performance problems that were found in
the initial performance testing of Asterisk 12.
The Stasis dispatch object was allocated as an AO2 object, even though
it has a very confined lifecycle. This was replaced with a straight
ast_malloc().
The Stasis message router was spending an inordinate amount of time
searching hash tables. In this case, most of our routers had 6 or
fewer routes in them to begin with. This was replaced with an array
that's searched linearly for the route.
We more heavily rely on AO2 objects in Asterisk 12, and the memset()
in ao2_ref() actually became noticeable on the profile. This was
#ifdef'ed to only run when AO2_DEBUG was enabled.
After being misled by an erroneous comment in taskprocessor.c during
profiling, the wrong comment was removed.
Review: https://reviewboard.asterisk.org/r/2873/
........
r400178 | dlee | 2013-09-30 13:26:27 -0500 (Mon, 30 Sep 2013) | 24 lines
Taskprocessor optimization; switch Stasis to use taskprocessors
This patch optimizes taskprocessor to use a semaphore for signaling,
which the OS can do a better job at managing contention and waiting
that we can with a mutex and condition.
The taskprocessor execution was also slightly optimized to reduce the
number of locks taken.
The only observable difference in the taskprocessor implementation is
that when the final reference to the taskprocessor goes away, it will
execute all tasks to completion instead of discarding the unexecuted
tasks.
For systems where unnamed semaphores are not supported, a really
simple semaphore implementation is provided. (Which gives identical
performance as the original taskprocessor implementation).
The way we ended up implementing Stasis caused the threadpool to be a
burden instead of a boost to performance. This was switched to just
use taskprocessors directly for subscriptions.
Review: https://reviewboard.asterisk.org/r/2881/
........
r400180 | dlee | 2013-09-30 13:39:34 -0500 (Mon, 30 Sep 2013) | 28 lines
Optimize how Stasis forwards are dispatched
This patch optimizes how forwards are dispatched in Stasis.
Originally, forwards were dispatched as subscriptions that are invoked
on the publishing thread. This did not account for the vast number of
forwards we would end up having in the system, and the amount of work it
would take to walk though the forward subscriptions.
This patch modifies Stasis so that rather than walking the tree of
forwards on every dispatch, when forwards and subscriptions are changed,
the subscriber list for every topic in the tree is changed.
This has a couple of benefits. First, this reduces the workload of
dispatching messages. It also reduces contention when dispatching to
different topics that happen to forward to the same aggregation topic
(as happens with all of the channel, bridge and endpoint topics).
Since forwards are no longer subscriptions, the bulk of this patch is
simply changing stasis_subscription objects to stasis_forward objects
(which, admittedly, I should have done in the first place.)
Since this required me to yet again put in a growing array, I finally
abstracted that out into a set of ast_vector macros in
asterisk/vector.h.
Review: https://reviewboard.asterisk.org/r/2883/
........
r400181 | dlee | 2013-09-30 13:48:57 -0500 (Mon, 30 Sep 2013) | 28 lines
Remove dispatch object allocation from Stasis publishing
While looking for areas for performance improvement, I realized that an
unused feature in Stasis was negatively impacting performance.
When a message is sent to a subscriber, a dispatch object is allocated
for the dispatch, containing the topic the message was published to, the
subscriber the message is being sent to, and the message itself.
The topic is actually unused by any subscriber in Asterisk today. And
the subscriber is associated with the taskprocessor the message is being
dispatched to.
First, this patch removes the unused topic parameter from Stasis
subscription callbacks.
Second, this patch introduces the concept of taskprocessor local data,
data that may be set on a taskprocessor and provided along with the data
pointer when a task is pushed using the ast_taskprocessor_push_local()
call. This allows the task to have both data specific to that
taskprocessor, in addition to data specific to that invocation.
With those two changes, the dispatch object can be removed completely,
and the message is simply refcounted and sent directly to the
taskprocessor.
Review: https://reviewboard.asterisk.org/r/2884/
........
Merged revisions 399887,400138,400178,400180-400181 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@400186 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-09-30 18:55:27 +00:00
|
|
|
struct stasis_message *message)
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
{
|
2013-11-23 17:48:28 +00:00
|
|
|
struct stasis_app *app = data;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
struct ast_bridge_merge_message *merge;
|
|
|
|
|
2014-02-01 16:26:57 +00:00
|
|
|
merge = stasis_message_data(message);
|
|
|
|
|
|
|
|
/* Find out if we're subscribed to either bridge */
|
|
|
|
if (bridge_app_subscribed(app, merge->from->uniqueid) ||
|
|
|
|
bridge_app_subscribed(app, merge->to->uniqueid)) {
|
|
|
|
/* Forward the message to the app */
|
|
|
|
stasis_publish(app->topic, message);
|
2013-07-23 13:42:46 +00:00
|
|
|
}
|
2014-02-01 16:26:57 +00:00
|
|
|
}
|
2013-06-10 13:07:11 +00:00
|
|
|
|
2014-02-01 16:26:57 +00:00
|
|
|
/*! \brief Callback function for checking if channels in a bridge are subscribed to */
|
|
|
|
static int bridge_app_subscribed_involved(struct stasis_app *app, struct ast_bridge_snapshot *snapshot)
|
|
|
|
{
|
|
|
|
int subscribed = 0;
|
|
|
|
struct ao2_iterator iter;
|
|
|
|
char *uniqueid;
|
|
|
|
|
|
|
|
if (bridge_app_subscribed(app, snapshot->uniqueid)) {
|
|
|
|
return 1;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
|
|
|
|
2014-02-01 16:26:57 +00:00
|
|
|
iter = ao2_iterator_init(snapshot->channels, 0);
|
|
|
|
for (; (uniqueid = ao2_iterator_next(&iter)); ao2_ref(uniqueid, -1)) {
|
|
|
|
if (bridge_app_subscribed(app, uniqueid)) {
|
|
|
|
subscribed = 1;
|
|
|
|
ao2_ref(uniqueid, -1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ao2_iterator_destroy(&iter);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2014-02-01 16:26:57 +00:00
|
|
|
return subscribed;
|
|
|
|
}
|
|
|
|
|
2014-08-20 13:06:33 +00:00
|
|
|
static void bridge_blind_transfer_handler(void *data, struct stasis_subscription *sub,
|
|
|
|
struct stasis_message *message)
|
|
|
|
{
|
|
|
|
struct stasis_app *app = data;
|
|
|
|
struct ast_blind_transfer_message *transfer_msg = stasis_message_data(message);
|
Fix race condition that could result in ARI transfer messages not being sent.
From reviewboard:
"During blind transfer testing, it was noticed that tests were failing
occasionally because the ARI blind transfer event was not being sent.
After investigating, I detected a race condition in the blind transfer
code. When blind transferring a single channel, the actual transfer
operation (i.e. removing the transferee from the bridge and directing
them to the proper dialplan location) is queued onto the transferee
bridge channel. After queuing the transfer operation, the blind transfer
Stasis message is published. At the time of publication, snapshots of
the channels and bridge involved are created. The ARI subscriber to the
blind transfer Stasis message then attempts to determine if the bridge
or any of the involved channels are subscribed to by ARI applications.
If so, then the blind transfer message is sent to the applications. The
way that the ARI blind transfer message handler works is to first see
if the transferer channel is subscribed to. If not, then iterate over
all the channel IDs in the bridge snapshot and determine if any of
those are subscribed to. In the test we were running, the lone
transferee channel was subscribed to, so an ARI event should have been
sent to our application. Occasionally, though, the bridge snapshot did
not have any channels IDs on it at all. Why?
The problem is that since the blind transfer operation is handled by a
separate thread, it is possible that the transfer will have completed and
the channels removed from the bridge before we publish the blind transfer
Stasis message. Since the blind transfer has completed, the bridge on
which the transfer occurred no longer has any channels on it, so the
resulting bridge snapshot has no channels on it. Through investigation of
the code, I found that attended transfers can have this issue too for the
case where a transferee is transferred to an application."
The fix employed here is to decouple the creation of snapshots for the transfer
messages from the publication of the transfer messages. This way, snapshots
can be created to reflect what they are at the time of the transfer operation.
Review: https://reviewboard.asterisk.org/r/4135
........
Merged revisions 427848 from http://svn.asterisk.org/svn/asterisk/branches/12
........
Merged revisions 427870 from http://svn.asterisk.org/svn/asterisk/branches/13
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@427873 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-11-14 15:28:42 +00:00
|
|
|
struct ast_bridge_snapshot *bridge = transfer_msg->bridge;
|
2014-08-20 13:06:33 +00:00
|
|
|
|
2018-11-07 13:18:34 -04:00
|
|
|
if (bridge_app_subscribed(app, transfer_msg->transferer->base->uniqueid) ||
|
2014-08-20 13:06:33 +00:00
|
|
|
(bridge && bridge_app_subscribed_involved(app, bridge))) {
|
|
|
|
stasis_publish(app->topic, message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-01 16:26:57 +00:00
|
|
|
static void bridge_attended_transfer_handler(void *data, struct stasis_subscription *sub,
|
|
|
|
struct stasis_message *message)
|
|
|
|
{
|
|
|
|
struct stasis_app *app = data;
|
|
|
|
struct ast_attended_transfer_message *transfer_msg = stasis_message_data(message);
|
|
|
|
int subscribed = 0;
|
|
|
|
|
2018-11-07 13:18:34 -04:00
|
|
|
subscribed = bridge_app_subscribed(app, transfer_msg->to_transferee.channel_snapshot->base->uniqueid);
|
2014-02-01 16:26:57 +00:00
|
|
|
if (!subscribed) {
|
2018-11-07 13:18:34 -04:00
|
|
|
subscribed = bridge_app_subscribed(app, transfer_msg->to_transfer_target.channel_snapshot->base->uniqueid);
|
2014-02-01 16:26:57 +00:00
|
|
|
}
|
|
|
|
if (!subscribed && transfer_msg->to_transferee.bridge_snapshot) {
|
|
|
|
subscribed = bridge_app_subscribed_involved(app, transfer_msg->to_transferee.bridge_snapshot);
|
|
|
|
}
|
|
|
|
if (!subscribed && transfer_msg->to_transfer_target.bridge_snapshot) {
|
|
|
|
subscribed = bridge_app_subscribed_involved(app, transfer_msg->to_transfer_target.bridge_snapshot);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!subscribed) {
|
|
|
|
switch (transfer_msg->dest_type) {
|
|
|
|
case AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE:
|
|
|
|
subscribed = bridge_app_subscribed(app, transfer_msg->dest.bridge);
|
|
|
|
break;
|
|
|
|
case AST_ATTENDED_TRANSFER_DEST_LINK:
|
2018-11-07 13:18:34 -04:00
|
|
|
subscribed = bridge_app_subscribed(app, transfer_msg->dest.links[0]->base->uniqueid);
|
2014-02-01 16:26:57 +00:00
|
|
|
if (!subscribed) {
|
2018-11-07 13:18:34 -04:00
|
|
|
subscribed = bridge_app_subscribed(app, transfer_msg->dest.links[1]->base->uniqueid);
|
2014-02-01 16:26:57 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case AST_ATTENDED_TRANSFER_DEST_THREEWAY:
|
|
|
|
subscribed = bridge_app_subscribed_involved(app, transfer_msg->dest.threeway.bridge_snapshot);
|
|
|
|
if (!subscribed) {
|
2018-11-07 13:18:34 -04:00
|
|
|
subscribed = bridge_app_subscribed(app, transfer_msg->dest.threeway.channel_snapshot->base->uniqueid);
|
2014-02-01 16:26:57 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
|
|
|
|
2014-02-01 16:26:57 +00:00
|
|
|
if (subscribed) {
|
|
|
|
stasis_publish(app->topic, message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-10 15:34:32 -04:00
|
|
|
static void bridge_subscription_change_handler(void *data, struct stasis_subscription *sub,
|
2014-02-01 16:26:57 +00:00
|
|
|
struct stasis_message *message)
|
|
|
|
{
|
|
|
|
struct stasis_app *app = data;
|
|
|
|
|
|
|
|
if (stasis_subscription_final_message(sub, message)) {
|
|
|
|
ao2_cleanup(app);
|
|
|
|
}
|
2013-06-10 13:07:11 +00:00
|
|
|
}
|
|
|
|
|
2017-01-19 08:05:36 -07:00
|
|
|
void stasis_app_set_debug(struct stasis_app *app, int debug)
|
2016-10-20 07:27:21 -05:00
|
|
|
{
|
|
|
|
if (!app) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-01-19 08:05:36 -07:00
|
|
|
app->debug = debug;
|
|
|
|
}
|
|
|
|
|
|
|
|
void stasis_app_set_debug_by_name(const char *app_name, int debug)
|
|
|
|
{
|
|
|
|
struct stasis_app *app = stasis_app_get_by_name(app_name);
|
|
|
|
|
|
|
|
if (!app) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
app->debug = debug;
|
|
|
|
ao2_cleanup(app);
|
|
|
|
}
|
|
|
|
|
|
|
|
int stasis_app_get_debug(struct stasis_app *app)
|
|
|
|
{
|
|
|
|
return (app ? app->debug : 0) || global_debug;
|
|
|
|
}
|
|
|
|
|
|
|
|
int stasis_app_get_debug_by_name(const char *app_name)
|
|
|
|
{
|
2017-11-03 16:14:15 -05:00
|
|
|
int debug_enabled = 0;
|
2017-01-19 08:05:36 -07:00
|
|
|
|
2017-11-03 16:14:15 -05:00
|
|
|
if (global_debug) {
|
|
|
|
debug_enabled = 1;
|
|
|
|
} else {
|
|
|
|
struct stasis_app *app = stasis_app_get_by_name(app_name);
|
|
|
|
|
|
|
|
if (app) {
|
|
|
|
if (app->debug) {
|
|
|
|
debug_enabled = 1;
|
|
|
|
}
|
|
|
|
ao2_ref(app, -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return debug_enabled;
|
2017-01-19 08:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void stasis_app_set_global_debug(int debug)
|
|
|
|
{
|
|
|
|
global_debug = debug;
|
|
|
|
if (!global_debug) {
|
|
|
|
struct ao2_container *app_names = stasis_app_get_all();
|
|
|
|
struct ao2_iterator it_app_names;
|
|
|
|
char *app_name;
|
|
|
|
struct stasis_app *app;
|
|
|
|
|
|
|
|
if (!app_names || !ao2_container_count(app_names)) {
|
|
|
|
ao2_cleanup(app_names);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
it_app_names = ao2_iterator_init(app_names, 0);
|
|
|
|
while ((app_name = ao2_iterator_next(&it_app_names))) {
|
|
|
|
if ((app = stasis_app_get_by_name(app_name))) {
|
|
|
|
stasis_app_set_debug(app, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
ao2_cleanup(app_name);
|
|
|
|
ao2_cleanup(app);
|
|
|
|
}
|
|
|
|
ao2_iterator_cleanup(&it_app_names);
|
|
|
|
ao2_cleanup(app_names);
|
2016-10-20 07:27:21 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
struct stasis_app *app_create(const char *name, stasis_app_cb handler, void *data, enum stasis_app_subscription_model subscription_model)
|
2013-06-10 13:07:11 +00:00
|
|
|
{
|
2013-11-23 17:48:28 +00:00
|
|
|
RAII_VAR(struct stasis_app *, app, NULL, ao2_cleanup);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
size_t size;
|
|
|
|
int res = 0;
|
2019-01-29 10:48:49 -06:00
|
|
|
size_t context_size = strlen("stasis-") + strlen(name) + 1;
|
|
|
|
char context_name[context_size];
|
2019-03-07 08:28:31 -04:00
|
|
|
char *topic_name;
|
|
|
|
int ret;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
|
|
|
ast_assert(name != NULL);
|
|
|
|
ast_assert(handler != NULL);
|
|
|
|
|
|
|
|
ast_verb(1, "Creating Stasis app '%s'\n", name);
|
|
|
|
|
|
|
|
size = sizeof(*app) + strlen(name) + 1;
|
|
|
|
app = ao2_alloc_options(size, app_dtor, AO2_ALLOC_OPT_LOCK_MUTEX);
|
|
|
|
if (!app) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2015-09-04 12:25:07 -05:00
|
|
|
app->subscription_model = subscription_model;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
|
|
|
app->forwards = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_MUTEX,
|
|
|
|
AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT,
|
|
|
|
forwards_sort, NULL);
|
|
|
|
if (!app->forwards) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-03-07 08:28:31 -04:00
|
|
|
ret = ast_asprintf(&topic_name, "ari:application/%s", name);
|
|
|
|
if (ret < 0) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
app->topic = stasis_topic_create(topic_name);
|
|
|
|
ast_free(topic_name);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
if (!app->topic) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-02-01 16:26:57 +00:00
|
|
|
app->bridge_router = stasis_message_router_create(ast_bridge_topic_all());
|
|
|
|
if (!app->bridge_router) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
res |= stasis_message_router_add(app->bridge_router,
|
|
|
|
ast_bridge_merge_message_type(), bridge_merge_handler, app);
|
|
|
|
|
|
|
|
res |= stasis_message_router_add(app->bridge_router,
|
|
|
|
ast_blind_transfer_type(), bridge_blind_transfer_handler, app);
|
|
|
|
|
|
|
|
res |= stasis_message_router_add(app->bridge_router,
|
|
|
|
ast_attended_transfer_type(), bridge_attended_transfer_handler, app);
|
|
|
|
|
2019-01-10 15:34:32 -04:00
|
|
|
res |= stasis_message_router_add(app->bridge_router,
|
|
|
|
stasis_subscription_change_type(), bridge_subscription_change_handler, app);
|
2014-02-01 16:26:57 +00:00
|
|
|
|
|
|
|
if (res != 0) {
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2014-02-01 16:26:57 +00:00
|
|
|
/* Bridge router holds a reference */
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
ao2_ref(app, +1);
|
|
|
|
|
|
|
|
app->router = stasis_message_router_create(app->topic);
|
|
|
|
if (!app->router) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-09-19 13:34:41 -06:00
|
|
|
res |= stasis_message_router_add(app->router,
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
ast_bridge_snapshot_type(), sub_bridge_update_handler, app);
|
|
|
|
|
2018-10-10 11:28:18 -03:00
|
|
|
res |= stasis_message_router_add(app->router,
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
ast_channel_snapshot_type(), sub_channel_update_handler, app);
|
|
|
|
|
2013-10-25 22:03:04 +00:00
|
|
|
res |= stasis_message_router_add_cache_update(app->router,
|
2013-10-04 16:01:48 +00:00
|
|
|
ast_endpoint_snapshot_type(), sub_endpoint_update_handler, app);
|
|
|
|
|
2019-01-10 15:34:32 -04:00
|
|
|
res |= stasis_message_router_add(app->router,
|
|
|
|
stasis_subscription_change_type(), sub_subscription_change_handler, app);
|
|
|
|
|
|
|
|
stasis_message_router_set_formatters_default(app->router,
|
|
|
|
sub_default_handler, app, STASIS_SUBSCRIPTION_FORMATTER_JSON);
|
2013-07-23 13:42:46 +00:00
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
if (res != 0) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/* Router holds a reference */
|
|
|
|
ao2_ref(app, +1);
|
|
|
|
|
|
|
|
strncpy(app->name, name, size - sizeof(*app));
|
|
|
|
app->handler = handler;
|
2015-05-17 20:36:41 -05:00
|
|
|
app->data = ao2_bump(data);
|
2013-06-10 13:07:11 +00:00
|
|
|
|
2019-01-29 10:48:49 -06:00
|
|
|
/* Create a context, a match-all extension, and a 'h' extension for this application. Note that
|
|
|
|
* this should only be done if a context does not already exist. */
|
|
|
|
strcpy(context_name, "stasis-");
|
|
|
|
strcat(context_name, name);
|
|
|
|
if (!ast_context_find(context_name)) {
|
|
|
|
if (!ast_context_find_or_create(NULL, NULL, context_name, "res_stasis")) {
|
|
|
|
ast_log(LOG_WARNING, "Could not create context '%s' for Stasis application '%s'\n", context_name, name);
|
|
|
|
} else {
|
|
|
|
ast_add_extension(context_name, 0, "_.", 1, NULL, NULL, "Stasis", ast_strdup(name), ast_free_ptr, "res_stasis");
|
|
|
|
ast_add_extension(context_name, 0, "h", 1, NULL, NULL, "NoOp", NULL, NULL, "res_stasis");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ast_log(LOG_WARNING, "Not creating context '%s' for Stasis application '%s' because it already exists\n",
|
|
|
|
context_name, name);
|
|
|
|
}
|
|
|
|
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
ao2_ref(app, +1);
|
|
|
|
return app;
|
2013-06-10 13:07:11 +00:00
|
|
|
}
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
struct stasis_topic *ast_app_get_topic(struct stasis_app *app)
|
|
|
|
{
|
2014-05-22 16:09:51 +00:00
|
|
|
return app->topic;
|
|
|
|
}
|
|
|
|
|
2013-05-14 21:45:08 +00:00
|
|
|
/*!
|
|
|
|
* \brief Send a message to the given application.
|
|
|
|
* \param app App to send the message to.
|
|
|
|
* \param message Message to send.
|
|
|
|
*/
|
2013-11-23 17:48:28 +00:00
|
|
|
void app_send(struct stasis_app *app, struct ast_json *message)
|
2013-05-14 21:45:08 +00:00
|
|
|
{
|
2013-07-23 13:42:46 +00:00
|
|
|
stasis_app_cb handler;
|
2016-10-15 20:05:05 -05:00
|
|
|
char eid[20];
|
2018-01-06 03:17:15 -05:00
|
|
|
void *data;
|
2013-07-23 13:42:46 +00:00
|
|
|
|
2016-10-15 20:05:05 -05:00
|
|
|
if (ast_json_object_set(message, "asterisk_id", ast_json_string_create(
|
|
|
|
ast_eid_to_str(eid, sizeof(eid), &ast_eid_default)))) {
|
|
|
|
ast_log(AST_LOG_WARNING, "Failed to append EID to outgoing event %s\n",
|
|
|
|
ast_json_string_get(ast_json_object_get(message, "type")));
|
|
|
|
}
|
|
|
|
|
2013-07-23 13:42:46 +00:00
|
|
|
/* Copy off mutable state with lock held */
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_lock(app);
|
|
|
|
handler = app->handler;
|
|
|
|
data = ao2_bump(app->data);
|
|
|
|
ao2_unlock(app);
|
|
|
|
/* Name is immutable; no need to copy */
|
|
|
|
|
|
|
|
if (handler) {
|
|
|
|
handler(data, app->name, message);
|
|
|
|
} else {
|
2013-07-23 13:42:46 +00:00
|
|
|
ast_verb(3,
|
|
|
|
"Inactive Stasis app '%s' missed message\n", app->name);
|
|
|
|
}
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_cleanup(data);
|
2013-07-23 13:42:46 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
void app_deactivate(struct stasis_app *app)
|
2013-07-23 13:42:46 +00:00
|
|
|
{
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_lock(app);
|
|
|
|
|
2013-07-23 13:42:46 +00:00
|
|
|
ast_verb(1, "Deactivating Stasis app '%s'\n", app->name);
|
|
|
|
app->handler = NULL;
|
|
|
|
ao2_cleanup(app->data);
|
|
|
|
app->data = NULL;
|
2018-01-06 03:17:15 -05:00
|
|
|
|
|
|
|
ao2_unlock(app);
|
2013-07-23 13:42:46 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
void app_shutdown(struct stasis_app *app)
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
{
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_lock(app);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
|
|
|
ast_assert(app_is_finished(app));
|
|
|
|
|
|
|
|
stasis_message_router_unsubscribe(app->router);
|
|
|
|
app->router = NULL;
|
2014-02-01 16:26:57 +00:00
|
|
|
stasis_message_router_unsubscribe(app->bridge_router);
|
|
|
|
app->bridge_router = NULL;
|
2015-09-04 12:25:07 -05:00
|
|
|
stasis_message_router_unsubscribe(app->endpoint_router);
|
|
|
|
app->endpoint_router = NULL;
|
2018-01-06 03:17:15 -05:00
|
|
|
|
|
|
|
ao2_unlock(app);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
int app_is_active(struct stasis_app *app)
|
2013-07-23 13:42:46 +00:00
|
|
|
{
|
2018-01-06 03:17:15 -05:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
ao2_lock(app);
|
|
|
|
ret = app->handler != NULL;
|
|
|
|
ao2_unlock(app);
|
|
|
|
|
|
|
|
return ret;
|
2013-07-23 13:42:46 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
int app_is_finished(struct stasis_app *app)
|
2013-07-23 13:42:46 +00:00
|
|
|
{
|
2018-01-06 03:17:15 -05:00
|
|
|
int ret;
|
2013-07-23 13:42:46 +00:00
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_lock(app);
|
|
|
|
ret = app->handler == NULL && ao2_container_count(app->forwards) == 0;
|
|
|
|
ao2_unlock(app);
|
2013-07-23 13:42:46 +00:00
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
return ret;
|
2013-05-14 21:45:08 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
void app_update(struct stasis_app *app, stasis_app_cb handler, void *data)
|
2013-05-14 21:45:08 +00:00
|
|
|
{
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_lock(app);
|
2015-05-17 20:36:41 -05:00
|
|
|
if (app->handler && app->data) {
|
2018-01-06 03:17:15 -05:00
|
|
|
struct ast_json *msg;
|
2013-07-23 13:42:46 +00:00
|
|
|
|
|
|
|
ast_verb(1, "Replacing Stasis app '%s'\n", app->name);
|
|
|
|
|
2019-03-06 23:21:42 +01:00
|
|
|
msg = ast_json_pack("{s: s, s: o?, s: s}",
|
2013-07-23 13:42:46 +00:00
|
|
|
"type", "ApplicationReplaced",
|
2019-03-06 23:21:42 +01:00
|
|
|
"timestamp", ast_json_timeval(ast_tvnow(), NULL),
|
2013-07-26 17:42:08 +00:00
|
|
|
"application", app->name);
|
2013-07-23 13:42:46 +00:00
|
|
|
if (msg) {
|
2020-01-27 12:01:15 -06:00
|
|
|
/*
|
|
|
|
* The app must be unlocked before calling 'send' since a handler may
|
|
|
|
* subsequently attempt to grab the app lock after first obtaining a
|
|
|
|
* lock for another object, thus causing a deadlock.
|
|
|
|
*/
|
|
|
|
ao2_unlock(app);
|
2013-07-23 13:42:46 +00:00
|
|
|
app_send(app, msg);
|
2020-01-27 12:01:15 -06:00
|
|
|
ao2_lock(app);
|
2018-01-06 03:17:15 -05:00
|
|
|
ast_json_unref(msg);
|
2020-01-27 12:01:15 -06:00
|
|
|
if (!app->handler) {
|
|
|
|
/*
|
|
|
|
* If the handler disappeared then the app was deactivated. In that
|
|
|
|
* case don't replace. Re-activation will reset the handler later.
|
|
|
|
*/
|
|
|
|
ao2_unlock(app);
|
|
|
|
return;
|
|
|
|
}
|
2013-07-23 13:42:46 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ast_verb(1, "Activating Stasis app '%s'\n", app->name);
|
|
|
|
}
|
|
|
|
|
2013-05-14 21:45:08 +00:00
|
|
|
app->handler = handler;
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_replace(app->data, data);
|
|
|
|
ao2_unlock(app);
|
2013-05-14 21:45:08 +00:00
|
|
|
}
|
|
|
|
|
2017-01-19 08:05:36 -07:00
|
|
|
const char *stasis_app_name(const struct stasis_app *app)
|
2013-05-14 21:45:08 +00:00
|
|
|
{
|
|
|
|
return app->name;
|
|
|
|
}
|
|
|
|
|
2016-10-20 07:27:21 -05:00
|
|
|
static int forwards_filter_by_type(void *obj, void *arg, int flags)
|
|
|
|
{
|
|
|
|
struct app_forwards *forward = obj;
|
|
|
|
enum forward_type *forward_type = arg;
|
|
|
|
|
|
|
|
if (forward->forward_type == *forward_type) {
|
|
|
|
return CMP_MATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-01-19 08:05:36 -07:00
|
|
|
void stasis_app_to_cli(const struct stasis_app *app, struct ast_cli_args *a)
|
2016-10-20 07:27:21 -05:00
|
|
|
{
|
|
|
|
struct ao2_iterator *channels;
|
|
|
|
struct ao2_iterator *endpoints;
|
|
|
|
struct ao2_iterator *bridges;
|
|
|
|
struct app_forwards *forward;
|
|
|
|
enum forward_type forward_type;
|
|
|
|
|
|
|
|
ast_cli(a->fd, "Name: %s\n"
|
|
|
|
" Debug: %s\n"
|
|
|
|
" Subscription Model: %s\n",
|
|
|
|
app->name,
|
|
|
|
app->debug ? "Yes" : "No",
|
|
|
|
app->subscription_model == STASIS_APP_SUBSCRIBE_ALL ?
|
|
|
|
"Global Resource Subscription" :
|
|
|
|
"Application/Explicit Resource Subscription");
|
|
|
|
ast_cli(a->fd, " Subscriptions: %d\n", ao2_container_count(app->forwards));
|
|
|
|
|
|
|
|
ast_cli(a->fd, " Channels:\n");
|
|
|
|
forward_type = FORWARD_CHANNEL;
|
|
|
|
channels = ao2_callback(app->forwards, OBJ_MULTIPLE,
|
|
|
|
forwards_filter_by_type, &forward_type);
|
|
|
|
if (channels) {
|
|
|
|
while ((forward = ao2_iterator_next(channels))) {
|
|
|
|
ast_cli(a->fd, " %s (%d)\n", forward->id, forward->interested);
|
|
|
|
ao2_ref(forward, -1);
|
|
|
|
}
|
|
|
|
ao2_iterator_destroy(channels);
|
|
|
|
}
|
|
|
|
|
|
|
|
ast_cli(a->fd, " Bridges:\n");
|
|
|
|
forward_type = FORWARD_BRIDGE;
|
|
|
|
bridges = ao2_callback(app->forwards, OBJ_MULTIPLE,
|
|
|
|
forwards_filter_by_type, &forward_type);
|
|
|
|
if (bridges) {
|
|
|
|
while ((forward = ao2_iterator_next(bridges))) {
|
|
|
|
ast_cli(a->fd, " %s (%d)\n", forward->id, forward->interested);
|
|
|
|
ao2_ref(forward, -1);
|
|
|
|
}
|
|
|
|
ao2_iterator_destroy(bridges);
|
|
|
|
}
|
|
|
|
|
|
|
|
ast_cli(a->fd, " Endpoints:\n");
|
|
|
|
forward_type = FORWARD_ENDPOINT;
|
|
|
|
endpoints = ao2_callback(app->forwards, OBJ_MULTIPLE,
|
|
|
|
forwards_filter_by_type, &forward_type);
|
|
|
|
if (endpoints) {
|
|
|
|
while ((forward = ao2_iterator_next(endpoints))) {
|
|
|
|
ast_cli(a->fd, " %s (%d)\n", forward->id, forward->interested);
|
|
|
|
ao2_ref(forward, -1);
|
|
|
|
}
|
|
|
|
ao2_iterator_destroy(endpoints);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
struct ast_json *app_to_json(const struct stasis_app *app)
|
2013-10-04 16:01:48 +00:00
|
|
|
{
|
2018-01-06 03:17:15 -05:00
|
|
|
struct ast_json *json;
|
2013-10-04 16:01:48 +00:00
|
|
|
struct ast_json *channels;
|
|
|
|
struct ast_json *bridges;
|
|
|
|
struct ast_json *endpoints;
|
|
|
|
struct ao2_iterator i;
|
2018-01-06 03:17:15 -05:00
|
|
|
struct app_forwards *forwards;
|
2013-10-04 16:01:48 +00:00
|
|
|
|
|
|
|
json = ast_json_pack("{s: s, s: [], s: [], s: []}",
|
|
|
|
"name", app->name,
|
|
|
|
"channel_ids", "bridge_ids", "endpoint_ids");
|
2018-01-06 03:17:15 -05:00
|
|
|
if (!json) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2013-10-04 16:01:48 +00:00
|
|
|
channels = ast_json_object_get(json, "channel_ids");
|
|
|
|
bridges = ast_json_object_get(json, "bridge_ids");
|
|
|
|
endpoints = ast_json_object_get(json, "endpoint_ids");
|
|
|
|
|
|
|
|
i = ao2_iterator_init(app->forwards, 0);
|
2018-01-06 03:17:15 -05:00
|
|
|
while ((forwards = ao2_iterator_next(&i))) {
|
|
|
|
struct ast_json *array = NULL;
|
|
|
|
int append_res;
|
2013-10-04 16:01:48 +00:00
|
|
|
|
|
|
|
switch (forwards->forward_type) {
|
|
|
|
case FORWARD_CHANNEL:
|
2018-01-06 03:17:15 -05:00
|
|
|
array = channels;
|
2013-10-04 16:01:48 +00:00
|
|
|
break;
|
|
|
|
case FORWARD_BRIDGE:
|
2018-01-06 03:17:15 -05:00
|
|
|
array = bridges;
|
2013-10-04 16:01:48 +00:00
|
|
|
break;
|
|
|
|
case FORWARD_ENDPOINT:
|
2018-01-06 03:17:15 -05:00
|
|
|
array = endpoints;
|
2013-10-04 16:01:48 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
/* If forward_type value is unexpected this will safely return an error. */
|
|
|
|
append_res = ast_json_array_append(array, ast_json_string_create(forwards->id));
|
|
|
|
ao2_ref(forwards, -1);
|
|
|
|
|
2013-10-04 16:01:48 +00:00
|
|
|
if (append_res != 0) {
|
|
|
|
ast_log(LOG_ERROR, "Error building response\n");
|
|
|
|
ao2_iterator_destroy(&i);
|
2018-01-06 03:17:15 -05:00
|
|
|
ast_json_unref(json);
|
|
|
|
|
2013-10-04 16:01:48 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ao2_iterator_destroy(&i);
|
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
return json;
|
2013-10-04 16:01:48 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
int app_subscribe_channel(struct stasis_app *app, struct ast_channel *chan)
|
2013-05-14 21:45:08 +00:00
|
|
|
{
|
2015-09-04 12:25:07 -05:00
|
|
|
struct app_forwards *forwards;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
if (!app) {
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return -1;
|
2015-09-04 12:25:07 -05:00
|
|
|
}
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_lock(app->forwards);
|
2015-09-04 12:25:07 -05:00
|
|
|
/* If subscribed to all, don't subscribe again */
|
|
|
|
forwards = ao2_find(app->forwards, CHANNEL_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
|
|
|
if (forwards) {
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_unlock(app->forwards);
|
2015-09-04 12:25:07 -05:00
|
|
|
ao2_ref(forwards, -1);
|
2018-01-06 03:17:15 -05:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
return 0;
|
|
|
|
}
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
forwards = ao2_find(app->forwards,
|
|
|
|
chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL,
|
|
|
|
OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
|
|
|
if (!forwards) {
|
2018-01-06 03:17:15 -05:00
|
|
|
int res;
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
/* Forwards not found, create one */
|
|
|
|
forwards = forwards_create_channel(app, chan);
|
|
|
|
if (!forwards) {
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_unlock(app->forwards);
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
return -1;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
res = ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
|
2015-09-04 12:25:07 -05:00
|
|
|
if (!res) {
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_unlock(app->forwards);
|
2015-09-04 12:25:07 -05:00
|
|
|
ao2_ref(forwards, -1);
|
2018-01-06 03:17:15 -05:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
return -1;
|
|
|
|
}
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
2015-09-04 12:25:07 -05:00
|
|
|
|
|
|
|
++forwards->interested;
|
|
|
|
ast_debug(3, "Channel '%s' is %d interested in %s\n",
|
|
|
|
chan ? ast_channel_uniqueid(chan) : "ALL",
|
|
|
|
forwards->interested,
|
|
|
|
app->name);
|
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_unlock(app->forwards);
|
2015-09-04 12:25:07 -05:00
|
|
|
ao2_ref(forwards, -1);
|
2018-01-06 03:17:15 -05:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
return 0;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
static int subscribe_channel(struct stasis_app *app, void *obj)
|
|
|
|
{
|
|
|
|
return app_subscribe_channel(app, obj);
|
|
|
|
}
|
|
|
|
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate)
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
{
|
2018-01-06 03:17:15 -05:00
|
|
|
struct app_forwards *forwards;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
if (!id) {
|
|
|
|
if (!strcmp(kind, "bridge")) {
|
|
|
|
id = BRIDGE_ALL;
|
|
|
|
} else if (!strcmp(kind, "channel")) {
|
|
|
|
id = CHANNEL_ALL;
|
|
|
|
} else if (!strcmp(kind, "endpoint")) {
|
|
|
|
id = ENDPOINT_ALL;
|
|
|
|
} else {
|
|
|
|
ast_log(LOG_WARNING, "Unknown subscription kind '%s'\n", kind);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_lock(app->forwards);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
forwards = ao2_find(app->forwards, id, OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
|
|
|
if (!forwards) {
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_unlock(app->forwards);
|
2014-08-18 00:57:01 +00:00
|
|
|
ast_debug(3, "App '%s' not subscribed to %s '%s'\n", app->name, kind, id);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2014-03-16 20:27:28 +00:00
|
|
|
forwards->interested--;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2014-03-16 20:27:28 +00:00
|
|
|
ast_debug(3, "%s '%s': is %d interested in %s\n", kind, id, forwards->interested, app->name);
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
if (forwards->interested == 0 || terminate) {
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
/* No one is interested any more; unsubscribe */
|
2014-03-16 20:27:28 +00:00
|
|
|
ast_debug(3, "%s '%s' unsubscribed from %s\n", kind, id, app->name);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
forwards_unsubscribe(forwards);
|
|
|
|
ao2_find(app->forwards, forwards,
|
|
|
|
OBJ_POINTER | OBJ_NOLOCK | OBJ_UNLINK |
|
|
|
|
OBJ_NODATA);
|
Multiple revisions 420089-420090,420097
........
r420089 | mjordan | 2014-08-05 15:10:52 -0500 (Tue, 05 Aug 2014) | 72 lines
ARI: Add channel technology agnostic out of call text messaging
This patch adds the ability to send and receive text messages from various
technology stacks in Asterisk through ARI. This includes chan_sip (sip),
res_pjsip_messaging (pjsip), and res_xmpp (xmpp). Messages are sent using the
endpoints resource, and can be sent directly through that resource, or to a
particular endpoint.
For example, the following would send the message "Hello there" to PJSIP
endpoint alice with a display URI of sip:asterisk@mycooldomain.org:
ari/endpoints/sendMessage?to=pjsip:alice&from=sip:asterisk@mycooldomain.org&body=Hello+There
This is equivalent to the following as well:
ari/endpoints/PJSIP/alice/sendMessage?from=sip:asterisk@mycooldomain.org&body=Hello+There
Both forms are available for message technologies that allow for arbitrary
destinations, such as chan_sip.
Inbound messages can now be received over ARI as well. An ARI application that
subscribes to endpoints will receive messages from those endpoints:
{
"type": "TextMessageReceived",
"timestamp": "2014-07-12T22:53:13.494-0500",
"endpoint": {
"technology": "PJSIP",
"resource": "alice",
"state": "online",
"channel_ids": []
},
"message": {
"from": "\"alice\" <sip:alice@127.0.0.1>",
"to": "pjsip:asterisk@127.0.0.1",
"body": "Watson, come here.",
"variables": []
},
"application": "testsuite"
}
The above was made possible due to some rather major changes in the message
core. This includes (but is not limited to):
- Users of the message API can now register message handlers. A handler has
two callbacks: one to determine if the handler has a destination for the
message, and another to handle it.
- All dialplan functionality of handling a message was moved into a message
handler provided by the message API.
- Messages can now have the technology/endpoint associated with them.
Various other properties are also now more easily accessible.
- A number of ao2 containers that weren't really needed were replaced with
vectors. Iteration over ao2_containers is expensive and pointless when
the lifetime of things is well defined and the number of things is very
small.
res_stasis now has a new file that makes up its structure, messaging. The
messaging functionality implements a message handler, and passes received
messages that match an interested endpoint over to the app for processing.
Note that inadvertently while testing this, I reproduced ASTERISK-23969.
res_pjsip_messaging was incorrectly parsing out the 'to' field, such that
arbitrary SIP URIs mangled the endpoint lookup. This patch includes the
fix for that as well.
Review: https://reviewboard.asterisk.org/r/3726
ASTERISK-23692 #close
Reported by: Matt Jordan
ASTERISK-23969 #close
Reported by: Andrew Nagy
........
r420090 | mjordan | 2014-08-05 15:16:37 -0500 (Tue, 05 Aug 2014) | 2 lines
Remove automerge properties :-(
........
r420097 | mjordan | 2014-08-05 16:36:25 -0500 (Tue, 05 Aug 2014) | 2 lines
test_message: Fix strict-aliasing compilation issue
........
Merged revisions 420089-420090,420097 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@420098 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-08-05 21:44:09 +00:00
|
|
|
|
|
|
|
if (!strcmp(kind, "endpoint")) {
|
|
|
|
messaging_app_unsubscribe_endpoint(app->name, id);
|
|
|
|
}
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_unlock(app->forwards);
|
|
|
|
ao2_ref(forwards, -1);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
|
|
|
return 0;
|
2013-05-14 21:45:08 +00:00
|
|
|
}
|
2013-06-10 13:07:11 +00:00
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
int app_unsubscribe_channel(struct stasis_app *app, struct ast_channel *chan)
|
2013-06-10 13:07:11 +00:00
|
|
|
{
|
2015-09-04 12:25:07 -05:00
|
|
|
if (!app) {
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
return app_unsubscribe_channel_id(app, chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL);
|
2013-10-04 16:01:48 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
int app_unsubscribe_channel_id(struct stasis_app *app, const char *channel_id)
|
2013-10-04 16:01:48 +00:00
|
|
|
{
|
2015-09-04 12:25:07 -05:00
|
|
|
if (!app) {
|
2013-10-04 16:01:48 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
return unsubscribe(app, "channel", channel_id, 0);
|
2013-10-04 16:01:48 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
int app_is_subscribed_channel_id(struct stasis_app *app, const char *channel_id)
|
2013-10-04 16:01:48 +00:00
|
|
|
{
|
2018-01-06 03:17:15 -05:00
|
|
|
struct app_forwards *forwards;
|
2015-09-04 12:25:07 -05:00
|
|
|
|
|
|
|
if (ast_strlen_zero(channel_id)) {
|
|
|
|
channel_id = CHANNEL_ALL;
|
|
|
|
}
|
2013-10-04 16:01:48 +00:00
|
|
|
forwards = ao2_find(app->forwards, channel_id, OBJ_SEARCH_KEY);
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_cleanup(forwards);
|
|
|
|
|
2013-10-04 16:01:48 +00:00
|
|
|
return forwards != NULL;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
static void *channel_find(const struct stasis_app *app, const char *id)
|
|
|
|
{
|
|
|
|
return ast_channel_get_by_name(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct stasis_app_event_source channel_event_source = {
|
|
|
|
.scheme = "channel:",
|
|
|
|
.find = channel_find,
|
|
|
|
.subscribe = subscribe_channel,
|
|
|
|
.unsubscribe = app_unsubscribe_channel_id,
|
|
|
|
.is_subscribed = app_is_subscribed_channel_id
|
|
|
|
};
|
|
|
|
|
|
|
|
int app_subscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
{
|
2015-09-04 12:25:07 -05:00
|
|
|
struct app_forwards *forwards;
|
|
|
|
|
|
|
|
if (!app) {
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return -1;
|
2015-09-04 12:25:07 -05:00
|
|
|
}
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_lock(app->forwards);
|
2015-09-04 12:25:07 -05:00
|
|
|
/* If subscribed to all, don't subscribe again */
|
|
|
|
forwards = ao2_find(app->forwards, BRIDGE_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
|
|
|
if (forwards) {
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_unlock(app->forwards);
|
2015-09-04 12:25:07 -05:00
|
|
|
ao2_ref(forwards, -1);
|
2018-01-06 03:17:15 -05:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
return 0;
|
|
|
|
}
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
forwards = ao2_find(app->forwards,
|
|
|
|
bridge ? bridge->uniqueid : BRIDGE_ALL,
|
2015-09-04 12:25:07 -05:00
|
|
|
OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
|
|
|
if (!forwards) {
|
2018-01-06 03:17:15 -05:00
|
|
|
int res;
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
/* Forwards not found, create one */
|
|
|
|
forwards = forwards_create_bridge(app, bridge);
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
if (!forwards) {
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_unlock(app->forwards);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
res = ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
|
|
|
|
if (!res) {
|
|
|
|
ao2_unlock(app->forwards);
|
|
|
|
ao2_ref(forwards, -1);
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
return -1;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
|
|
|
}
|
2015-09-04 12:25:07 -05:00
|
|
|
|
|
|
|
++forwards->interested;
|
|
|
|
ast_debug(3, "Bridge '%s' is %d interested in %s\n",
|
|
|
|
bridge ? bridge->uniqueid : "ALL",
|
|
|
|
forwards->interested,
|
|
|
|
app->name);
|
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_unlock(app->forwards);
|
2015-09-04 12:25:07 -05:00
|
|
|
ao2_ref(forwards, -1);
|
2018-01-06 03:17:15 -05:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
return 0;
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
static int subscribe_bridge(struct stasis_app *app, void *obj)
|
|
|
|
{
|
|
|
|
return app_subscribe_bridge(app, obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
int app_unsubscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
{
|
2015-09-04 12:25:07 -05:00
|
|
|
if (!app) {
|
ARI: WebSocket event cleanup
Stasis events (which get distributed over the ARI WebSocket) are created
by subscribing to the channel_all_cached and bridge_all_cached topics,
filtering out events for channels/bridges currently subscribed to.
There are two issues with that. First was a race condition, where
messages in-flight to the master subscribe-to-all-things topic would get
sent out, even though the events happened before the channel was put
into Stasis. Secondly, as the number of channels and bridges grow in the
system, the work spent filtering messages becomes excessive.
Since r395954, individual channels and bridges have caching topics, and
can be subscribed to individually. This patch takes advantage, so that
channels and bridges are subscribed to on demand, instead of filtering
the global topics.
The one case where filtering is still required is handling BridgeMerge
messages, which are published directly to the bridge_all topic.
Other than the change to how subscriptions work, this patch mostly just
moves code around. Most of the work generating JSON objects from
messages was moved to .to_json handlers on the message types. The
callback functions handling app subscriptions were moved from res_stasis
(b/c they were global to the model) to stasis/app.c (b/c they are local
to the app now).
(closes issue ASTERISK-21969)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2754/
........
Merged revisions 397816 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397820 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2013-08-27 19:19:36 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
return app_unsubscribe_bridge_id(app, bridge ? bridge->uniqueid : BRIDGE_ALL);
|
2013-10-04 16:01:48 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
int app_unsubscribe_bridge_id(struct stasis_app *app, const char *bridge_id)
|
2013-10-04 16:01:48 +00:00
|
|
|
{
|
2015-09-04 12:25:07 -05:00
|
|
|
if (!app) {
|
2013-10-04 16:01:48 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
return unsubscribe(app, "bridge", bridge_id, 0);
|
2013-10-04 16:01:48 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
int app_is_subscribed_bridge_id(struct stasis_app *app, const char *bridge_id)
|
2013-10-04 16:01:48 +00:00
|
|
|
{
|
2015-09-04 12:25:07 -05:00
|
|
|
struct app_forwards *forwards;
|
|
|
|
|
|
|
|
if (ast_strlen_zero(bridge_id)) {
|
|
|
|
bridge_id = BRIDGE_ALL;
|
|
|
|
}
|
|
|
|
|
2018-01-07 21:21:13 -05:00
|
|
|
forwards = ao2_find(app->forwards, bridge_id, OBJ_SEARCH_KEY);
|
|
|
|
ao2_cleanup(forwards);
|
2015-09-04 12:25:07 -05:00
|
|
|
|
2018-01-07 21:21:13 -05:00
|
|
|
return forwards != NULL;
|
2013-10-04 16:01:48 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
static void *bridge_find(const struct stasis_app *app, const char *id)
|
|
|
|
{
|
|
|
|
return stasis_app_bridge_find_by_id(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct stasis_app_event_source bridge_event_source = {
|
|
|
|
.scheme = "bridge:",
|
|
|
|
.find = bridge_find,
|
|
|
|
.subscribe = subscribe_bridge,
|
|
|
|
.unsubscribe = app_unsubscribe_bridge_id,
|
|
|
|
.is_subscribed = app_is_subscribed_bridge_id
|
|
|
|
};
|
|
|
|
|
|
|
|
int app_subscribe_endpoint(struct stasis_app *app, struct ast_endpoint *endpoint)
|
2013-10-04 16:01:48 +00:00
|
|
|
{
|
2015-09-04 12:25:07 -05:00
|
|
|
struct app_forwards *forwards;
|
|
|
|
|
|
|
|
if (!app) {
|
2013-10-04 16:01:48 +00:00
|
|
|
return -1;
|
2015-09-04 12:25:07 -05:00
|
|
|
}
|
2013-10-04 16:01:48 +00:00
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_lock(app->forwards);
|
2015-09-04 12:25:07 -05:00
|
|
|
/* If subscribed to all, don't subscribe again */
|
|
|
|
forwards = ao2_find(app->forwards, ENDPOINT_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
|
|
|
if (forwards) {
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_unlock(app->forwards);
|
2015-09-04 12:25:07 -05:00
|
|
|
ao2_ref(forwards, -1);
|
2018-01-06 03:17:15 -05:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
return 0;
|
|
|
|
}
|
2013-10-04 16:01:48 +00:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
forwards = ao2_find(app->forwards,
|
|
|
|
endpoint ? ast_endpoint_get_id(endpoint) : ENDPOINT_ALL,
|
|
|
|
OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
|
|
|
if (!forwards) {
|
2018-01-06 03:17:15 -05:00
|
|
|
int res;
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
/* Forwards not found, create one */
|
|
|
|
forwards = forwards_create_endpoint(app, endpoint);
|
2013-10-04 16:01:48 +00:00
|
|
|
if (!forwards) {
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_unlock(app->forwards);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
res = ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
|
|
|
|
if (!res) {
|
|
|
|
ao2_unlock(app->forwards);
|
|
|
|
ao2_ref(forwards, -1);
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
return -1;
|
2013-10-04 16:01:48 +00:00
|
|
|
}
|
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
/* Subscribe for messages */
|
|
|
|
messaging_app_subscribe_endpoint(app->name, endpoint, &message_received_handler, app);
|
2013-10-04 16:01:48 +00:00
|
|
|
}
|
2015-09-04 12:25:07 -05:00
|
|
|
|
|
|
|
++forwards->interested;
|
|
|
|
ast_debug(3, "Endpoint '%s' is %d interested in %s\n",
|
|
|
|
endpoint ? ast_endpoint_get_id(endpoint) : "ALL",
|
|
|
|
forwards->interested,
|
|
|
|
app->name);
|
|
|
|
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_unlock(app->forwards);
|
2015-09-04 12:25:07 -05:00
|
|
|
ao2_ref(forwards, -1);
|
2018-01-06 03:17:15 -05:00
|
|
|
|
2015-09-04 12:25:07 -05:00
|
|
|
return 0;
|
2013-06-10 13:07:11 +00:00
|
|
|
}
|
2013-10-31 14:45:03 +00:00
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
static int subscribe_endpoint(struct stasis_app *app, void *obj)
|
|
|
|
{
|
|
|
|
return app_subscribe_endpoint(app, obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
int app_unsubscribe_endpoint_id(struct stasis_app *app, const char *endpoint_id)
|
2013-10-31 14:45:03 +00:00
|
|
|
{
|
2015-09-04 12:25:07 -05:00
|
|
|
if (!app) {
|
2013-10-31 14:45:03 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
ARI/res_stasis: Subscribe to both Local channel halves when originating to app
This patch fixes two bugs:
1. When originating a channel into a Stasis application, we already create a
subscription for the channel that is going into our Stasis app.
Unfortunately, when you create a Local channel and pass it off to a Stasis
app, you really aren't creating just one channel: you're creating two. This
patch snags the second half of the Local channel pair (assuming it is a
Local channel pair, but luckily core_local is kind about such assumptions)
and subscribes to it as well.
2. Subscriptions are a bit sticky right now. If a subscription is made, the
'interest' count gets bumped on the Stasis subscription - but unless
something explicitly unsubscribes the channel, said subscription sticks
around. This is not much of a problem is a user is creating the subscription
- if they made it, they must want it. However, when we are creating
implicit subscriptions, we need to make sure something clears them out.
This patch takes a pessimistic approach: it watches the cache updates
coming from Stasis and, if we notice that the cache just cleared out an
object, we delete our subscription object. This keeps our ao2 container of
Stasis forwards in an application from growing out of hand; it also is a
bit more forgiving for end users who may not realize they were supposed to
unsubscribe from that channel that just hung up.
Review: https://reviewboard.asterisk.org/r/3710/
#ASTERISK-23939 #close
........
Merged revisions 418089 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-07 02:15:00 +00:00
|
|
|
return unsubscribe(app, "endpoint", endpoint_id, 0);
|
2013-10-31 14:45:03 +00:00
|
|
|
}
|
|
|
|
|
2013-11-23 17:48:28 +00:00
|
|
|
int app_is_subscribed_endpoint_id(struct stasis_app *app, const char *endpoint_id)
|
2013-10-31 14:45:03 +00:00
|
|
|
{
|
2018-01-06 03:17:15 -05:00
|
|
|
struct app_forwards *forwards;
|
2015-09-04 12:25:07 -05:00
|
|
|
|
|
|
|
if (ast_strlen_zero(endpoint_id)) {
|
|
|
|
endpoint_id = ENDPOINT_ALL;
|
|
|
|
}
|
2013-10-31 14:45:03 +00:00
|
|
|
forwards = ao2_find(app->forwards, endpoint_id, OBJ_SEARCH_KEY);
|
2018-01-06 03:17:15 -05:00
|
|
|
ao2_cleanup(forwards);
|
|
|
|
|
2013-10-31 14:45:03 +00:00
|
|
|
return forwards != NULL;
|
|
|
|
}
|
2013-11-23 17:48:28 +00:00
|
|
|
|
|
|
|
static void *endpoint_find(const struct stasis_app *app, const char *id)
|
|
|
|
{
|
|
|
|
return ast_endpoint_find_by_id(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct stasis_app_event_source endpoint_event_source = {
|
|
|
|
.scheme = "endpoint:",
|
|
|
|
.find = endpoint_find,
|
|
|
|
.subscribe = subscribe_endpoint,
|
|
|
|
.unsubscribe = app_unsubscribe_endpoint_id,
|
|
|
|
.is_subscribed = app_is_subscribed_endpoint_id
|
|
|
|
};
|
|
|
|
|
|
|
|
void stasis_app_register_event_sources(void)
|
|
|
|
{
|
|
|
|
stasis_app_register_event_source(&channel_event_source);
|
|
|
|
stasis_app_register_event_source(&bridge_event_source);
|
|
|
|
stasis_app_register_event_source(&endpoint_event_source);
|
|
|
|
}
|
|
|
|
|
|
|
|
void stasis_app_unregister_event_sources(void)
|
|
|
|
{
|
|
|
|
stasis_app_unregister_event_source(&endpoint_event_source);
|
|
|
|
stasis_app_unregister_event_source(&bridge_event_source);
|
|
|
|
stasis_app_unregister_event_source(&channel_event_source);
|
|
|
|
}
|
2019-02-08 14:48:27 -06:00
|
|
|
|
|
|
|
struct ast_json *stasis_app_event_filter_to_json(struct stasis_app *app, struct ast_json *json)
|
|
|
|
{
|
|
|
|
if (!app || !json) {
|
|
|
|
return json;
|
|
|
|
}
|
|
|
|
|
|
|
|
ast_json_object_set(json, "events_allowed", app->events_allowed ?
|
|
|
|
ast_json_ref(app->events_allowed) : ast_json_array_create());
|
|
|
|
ast_json_object_set(json, "events_disallowed", app->events_disallowed ?
|
|
|
|
ast_json_ref(app->events_disallowed) : ast_json_array_create());
|
|
|
|
|
|
|
|
return json;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int app_event_filter_set(struct stasis_app *app, struct ast_json **member,
|
|
|
|
struct ast_json *filter, const char *filter_type)
|
|
|
|
{
|
|
|
|
if (filter && ast_json_typeof(filter) == AST_JSON_OBJECT) {
|
|
|
|
if (!ast_json_object_size(filter)) {
|
|
|
|
/* If no filters are specified then reset this filter type */
|
|
|
|
filter = NULL;
|
|
|
|
} else {
|
|
|
|
/* Otherwise try to get the filter array for this type */
|
|
|
|
filter = ast_json_object_get(filter, filter_type);
|
|
|
|
if (!filter) {
|
|
|
|
/* A filter type exists, but not this one, so don't update */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* At this point the filter object should be an array */
|
|
|
|
if (filter && ast_json_typeof(filter) != AST_JSON_ARRAY) {
|
|
|
|
ast_log(LOG_ERROR, "Invalid json type event filter - app: %s, filter: %s\n",
|
|
|
|
app->name, filter_type);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filter) {
|
|
|
|
/* Confirm that at least the type names are specified */
|
|
|
|
struct ast_json *obj;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ast_json_array_size(filter) &&
|
|
|
|
(obj = ast_json_array_get(filter, i)); ++i) {
|
|
|
|
|
|
|
|
if (ast_strlen_zero(ast_json_object_string_get(obj, "type"))) {
|
|
|
|
ast_log(LOG_ERROR, "Filter event must have a type - app: %s, "
|
|
|
|
"filter: %s\n", app->name, filter_type);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ao2_lock(app);
|
|
|
|
ast_json_unref(*member);
|
|
|
|
*member = filter ? ast_json_ref(filter) : NULL;
|
|
|
|
ao2_unlock(app);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int app_events_allowed_set(struct stasis_app *app, struct ast_json *filter)
|
|
|
|
{
|
|
|
|
return app_event_filter_set(app, &app->events_allowed, filter, "allowed");
|
|
|
|
}
|
|
|
|
|
|
|
|
static int app_events_disallowed_set(struct stasis_app *app, struct ast_json *filter)
|
|
|
|
{
|
|
|
|
return app_event_filter_set(app, &app->events_disallowed, filter, "disallowed");
|
|
|
|
}
|
|
|
|
|
|
|
|
int stasis_app_event_filter_set(struct stasis_app *app, struct ast_json *filter)
|
|
|
|
{
|
|
|
|
return app_events_disallowed_set(app, filter) || app_events_allowed_set(app, filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int app_event_filter_matched(struct ast_json *array, struct ast_json *event, int empty)
|
|
|
|
{
|
|
|
|
struct ast_json *obj;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!array || !ast_json_array_size(array)) {
|
|
|
|
return empty;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < ast_json_array_size(array) &&
|
|
|
|
(obj = ast_json_array_get(array, i)); ++i) {
|
|
|
|
|
|
|
|
if (ast_strings_equal(ast_json_object_string_get(obj, "type"),
|
|
|
|
ast_json_object_string_get(event, "type"))) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int stasis_app_event_allowed(const char *app_name, struct ast_json *event)
|
|
|
|
{
|
|
|
|
struct stasis_app *app = stasis_app_get_by_name(app_name);
|
|
|
|
int res;
|
|
|
|
|
|
|
|
if (!app) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ao2_lock(app);
|
|
|
|
res = !app_event_filter_matched(app->events_disallowed, event, 0) &&
|
|
|
|
app_event_filter_matched(app->events_allowed, event, 1);
|
|
|
|
ao2_unlock(app);
|
|
|
|
ao2_ref(app, -1);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|