stasis: Add internal filtering of messages.
[asterisk/asterisk.git] / include / asterisk / stasis_message_router.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * David M. Lee, II <dlee@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 #ifndef _ASTERISK_STASIS_MESSAGE_ROUTER_H
20 #define _ASTERISK_STASIS_MESSAGE_ROUTER_H
21
22 /*!
23  * \brief A simplistic router for \ref stasis_message's.
24  *
25  * Often times, when subscribing to a topic, one wants to handle different
26  * message types differently. While one could cascade if/else statements through
27  * the subscription handler, it is much cleaner to specify a different callback
28  * for each message type. The \ref stasis_message_router is here to help!
29  *
30  * A \ref stasis_message_router is constructed for a particular \ref
31  * stasis_topic, which is subscribes to. Call
32  * stasis_message_router_unsubscribe() to cancel that subscription.
33  *
34  * Once constructed, routes can be added using stasis_message_router_add() (or
35  * stasis_message_router_set_default() for any messages not handled by other
36  * routes). There may be only one route per \ref stasis_message_type. The
37  * route's \a callback is invoked just as if it were a callback for a
38  * subscription; but it only gets called for messages of the specified type.
39  *
40  * \since 12
41  */
42
43 #include "asterisk/stasis.h"
44
45 /*! \brief Stasis message routing object */
46 struct stasis_message_router;
47
48 /*!
49  * \brief Create a new message router object.
50  *
51  * \param topic Topic to subscribe route to.
52  *
53  * \return New \ref stasis_message_router.
54  * \return \c NULL on error.
55  *
56  * \since 12
57  */
58 struct stasis_message_router *stasis_message_router_create(
59         struct stasis_topic *topic);
60
61 /*!
62  * \brief Create a new message router object.
63  *
64  * The subscription created for this message router will dispatch
65  * callbacks on a thread pool.
66  *
67  * \param topic Topic to subscribe route to.
68  *
69  * \return New \ref stasis_message_router.
70  * \return \c NULL on error.
71  *
72  * \since 12.8.0
73  */
74 struct stasis_message_router *stasis_message_router_create_pool(
75         struct stasis_topic *topic);
76
77 /*!
78  * \brief Unsubscribe the router from the upstream topic.
79  *
80  * \param router Router to unsubscribe.
81  *
82  * \since 12
83  */
84 void stasis_message_router_unsubscribe(struct stasis_message_router *router);
85
86 /*!
87  * \brief Unsubscribe the router from the upstream topic, blocking until the
88  * final message has been processed.
89  *
90  * See stasis_unsubscribe_and_join() for info on when to use this
91  * vs. stasis_message_router_unsubscribe().
92  *
93  * \param router Router to unsubscribe.
94  *
95  * \since 12
96  */
97 void stasis_message_router_unsubscribe_and_join(
98         struct stasis_message_router *router);
99
100 /*!
101  * \brief Returns whether \a router has received its final message.
102  *
103  * \param router Router.
104  *
105  * \return True (non-zero) if stasis_subscription_final_message() has been
106  *         received.
107  * \return False (zero) if waiting for the end.
108  */
109 int stasis_message_router_is_done(struct stasis_message_router *router);
110
111 /*!
112  * \brief Publish a message to a message router's subscription synchronously
113  *
114  * \param router Router
115  * \param message The \ref stasis message
116  *
117  * This should be used when a message needs to be published synchronously to
118  * the underlying subscription created by a message router. This is analagous
119  * to \ref stasis_publish_sync.
120  *
121  * Note that the caller will be blocked until the thread servicing the message
122  * on the message router's subscription completes handling of the message.
123  *
124  * \since 12.1.0
125  */
126 void stasis_message_router_publish_sync(struct stasis_message_router *router,
127         struct stasis_message *message);
128
129 /*!
130  * \brief Set the high and low alert water marks of the stasis message router.
131  * \since 13.10.0
132  *
133  * \param router Pointer to a stasis message router
134  * \param low_water New queue low water mark. (-1 to set as 90% of high_water)
135  * \param high_water New queue high water mark.
136  *
137  * \retval 0 on success.
138  * \retval -1 on error (water marks not changed).
139  */
140 int stasis_message_router_set_congestion_limits(struct stasis_message_router *router,
141         long low_water, long high_water);
142
143 /*!
144  * \brief Add a route to a message router.
145  *
146  * A particular \a message_type may have at most one route per \a router. If
147  * you route \ref stasis_cache_update messages, the callback will only receive
148  * updates for types not handled by routes added with
149  * stasis_message_router_add_cache_update().
150  *
151  * Adding multiple routes for the same message type results in undefined
152  * behavior.
153  *
154  * \param router Router to add the route to.
155  * \param message_type Type of message to route.
156  * \param callback Callback to forard messages of \a message_type to.
157  * \param data Data pointer to pass to \a callback.
158  *
159  * \retval 0 on success
160  * \retval -1 on failure
161  *
162  * \since 12
163  */
164 int stasis_message_router_add(struct stasis_message_router *router,
165         struct stasis_message_type *message_type,
166         stasis_subscription_cb callback, void *data);
167
168 /*!
169  * \brief Add a route for \ref stasis_cache_update messages to a message router.
170  *
171  * A particular \a message_type may have at most one cache route per \a router.
172  * These are distinct from regular routes, so one could have both a regular
173  * route and a cache route for the same \a message_type.
174  *
175  * Adding multiple routes for the same message type results in undefined
176  * behavior.
177  *
178  * \param router Router to add the route to.
179  * \param message_type Subtype of cache update to route.
180  * \param callback Callback to forard messages of \a message_type to.
181  * \param data Data pointer to pass to \a callback.
182  *
183  * \retval 0 on success
184  * \retval -1 on failure
185  *
186  * \since 12
187  */
188 int stasis_message_router_add_cache_update(struct stasis_message_router *router,
189         struct stasis_message_type *message_type,
190         stasis_subscription_cb callback, void *data);
191
192 /*!
193  * \brief Remove a route from a message router.
194  *
195  * If a route is removed from another thread, there is no notification that
196  * all messages using this route have been processed. This typically means that
197  * the associated \c data pointer for this route must be kept until the
198  * route itself is disposed of.
199  *
200  * \param router Router to remove the route from.
201  * \param message_type Type of message to route.
202  *
203  * \since 12
204  */
205 void stasis_message_router_remove(struct stasis_message_router *router,
206         struct stasis_message_type *message_type);
207
208 /*!
209  * \brief Remove a cache route from a message router.
210  *
211  * If a route is removed from another thread, there is no notification that
212  * all messages using this route have been processed. This typically means that
213  * the associated \c data pointer for this route must be kept until the
214  * route itself is disposed of.
215  *
216  * \param router Router to remove the route from.
217  * \param message_type Type of message to route.
218  *
219  * \since 12
220  */
221 void stasis_message_router_remove_cache_update(
222         struct stasis_message_router *router,
223         struct stasis_message_type *message_type);
224
225 /*!
226  * \brief Sets the default route of a router.
227  *
228  * \param router Router to set the default route of.
229  * \param callback Callback to forard messages which otherwise have no home.
230  * \param data Data pointer to pass to \a callback.
231  *
232  * \retval 0 on success
233  * \retval -1 on failure
234  *
235  * \since 12
236  *
237  * \note Setting a default callback will automatically cause the underlying
238  * subscription to receive all messages and not be filtered. If filtering is
239  * desired then a specific route for each message type should be provided.
240  */
241 int stasis_message_router_set_default(struct stasis_message_router *router,
242                                       stasis_subscription_cb callback,
243                                       void *data);
244
245 #endif /* _ASTERISK_STASIS_MESSAGE_ROUTER_H */