diff options
author | David M. Lee <dlee@digium.com> | 2013-08-01 13:49:34 +0000 |
---|---|---|
committer | David M. Lee <dlee@digium.com> | 2013-08-01 13:49:34 +0000 |
commit | e1b959ccbb4e47421b37a0f75a2bf89ccd34dcb1 (patch) | |
tree | 3026c96da713bafcf1126c77bde6994f348280bb /include/asterisk/stasis_cache_pattern.h | |
parent | 5c1396946929ab19e94c117f8ad3db5f78a450bc (diff) |
Split caching out from the stasis_caching_topic.
In working with res_stasis, I discovered a significant limitation to
the current structure of stasis_caching_topics: you cannot subscribe
to cache updates for a single channel/bridge/endpoint/etc.
To address this, this patch splits the cache away from the
stasis_caching_topic, making it a first class object. The stasis_cache
object is shared amongst individual stasis_caching_topics that are
created per channel/endpoint/etc. These are still forwarded to global
whatever_all_cached topics, so their use from most of the code does
not change.
In making these changes, I noticed that we frequently used a similar
pattern for bridges, endpoints and channels:
single_topic ----------------> all_topic
^
|
single_topic_cached ----+----> all_topic_cached
|
+----> cache
This pattern was extracted as the 'Stasis Caching Pattern', defined in
stasis_caching_pattern.h. This avoids a lot of duplicate code between
the different domain objects.
Since the cache is now disassociated from its upstream caching topics,
this also necessitated a change to how the 'guaranteed' flag worked
for retrieving from a cache. The code for handling the caching
guarantee was extracted into a 'stasis_topic_wait' function, which
works for any stasis_topic.
(closes issue ASTERISK-22002)
Review: https://reviewboard.asterisk.org/r/2672/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@395954 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'include/asterisk/stasis_cache_pattern.h')
-rw-r--r-- | include/asterisk/stasis_cache_pattern.h | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/include/asterisk/stasis_cache_pattern.h b/include/asterisk/stasis_cache_pattern.h new file mode 100644 index 000000000..2ea643e19 --- /dev/null +++ b/include/asterisk/stasis_cache_pattern.h @@ -0,0 +1,153 @@ +/* + * 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. + */ + +#ifndef _ASTERISK_STASIS_CACHE_PATTERN_H +#define _ASTERISK_STASIS_CACHE_PATTERN_H + +/*! \file + * + * \brief Caching pattern for \ref stasis topics. + * + * A typical pattern for Stasis objects is to have individual objects, which + * have their own topic and caching topic. These individual topics feed an + * upstream aggregate topics, and a shared cache. + * + * The \ref stasis_cp_all object contains the aggregate topics and shared cache. + * This is built with the base name for the topics, and the identity function to + * identify messages in the cache. + * + * The \ref stasis_cp_single object contains the \ref stasis_topic for a single + * instance, and the corresponding \ref stasis_caching_topic. + * + * Since the \ref stasis_cp_single object has subscriptions for forwarding + * and caching, it must be disposed of using stasis_cp_single_unsubscribe() + * instead of simply ao2_cleanup(). + */ + +#include "asterisk/stasis.h" + +/*! + * \brief The 'all' side of the cache pattern. These are typically built as + * global objects for specific modules. + */ +struct stasis_cp_all; + +/*! + * \brief Create an all instance of the cache pattern. + * + * This object is AO2 managed, so dispose of it with ao2_cleanup(). + * + * \param name Base name of the topics. + * \param id_fn Identity function for the cache. + * \return All side instance. + * \return \c NULL on error. + */ +struct stasis_cp_all *stasis_cp_all_create(const char *name, + snapshot_get_id id_fn); + +/*! + * \brief Get the aggregate topic. + * + * This topic aggregates all messages published to corresponding + * stasis_cp_single_topic() topics. + * + * \param all All side caching pattern object. + * \return The aggregate topic. + * \return \c NULL if \a all is \c NULL + */ +struct stasis_topic *stasis_cp_all_topic(struct stasis_cp_all *all); + +/*! + * \brief Get the caching topic. + * + * This topic aggregates all messages from the corresponding + * stasis_cp_single_topic_cached() topics. + * + * Note that one normally only subscribes to the caching topic, since data + * is fed to it from its upstream topic. + * + * \param all All side caching pattern object. + * \return The aggregate caching topic. + * \return \c NULL if \a all is \c NULL + */ +struct stasis_topic *stasis_cp_all_topic_cached( + struct stasis_cp_all *all); + +/*! + * \brief Get the cache. + * + * This is the shared cache for all corresponding \ref stasis_cp_single objects. + * + * \param all All side caching pattern object. + * \return The cache. + * \return \c NULL if \a all is \c NULL + */ +struct stasis_cache *stasis_cp_all_cache(struct stasis_cp_all *all); + +/*! + * \brief The 'one' side of the cache pattern. These are built per-instance for + * some corresponding object, and must be explicitly disposed of using + * stasis_cp_single_unsubscribe(). + */ +struct stasis_cp_single; + +/*! + * \brief Create the 'one' side of the cache pattern. + * + * Dispose of using stasis_cp_single_unsubscribe(). + * + * \param all Corresponding all side. + * \param name Base name for the topics. + * \return One side instance + */ +struct stasis_cp_single *stasis_cp_single_create(struct stasis_cp_all *all, + const char *name); + +/*! + * \brief Stops caching and forwarding messages. + * + * \param one One side of the cache pattern. + */ +void stasis_cp_single_unsubscribe(struct stasis_cp_single *one); + +/*! + * \brief Get the topic for this instance. + * + * This is the topic to which one would post instance-specific messages, or + * subscribe for single-instance, uncached messages. + * + * \param one One side of the cache pattern. + * \return The main topic. + * \return \c NULL if \a one is \c NULL + */ +struct stasis_topic *stasis_cp_single_topic(struct stasis_cp_single *one); + +/*! + * \brief Get the caching topic for this instance. + * + * Note that one normally only subscribes to the caching topic, since data + * is fed to it from its upstream topic. + * + * \param one One side of the cache pattern. + * \return The caching topic. + * \return \c NULL if \a one is \c NULL + */ +struct stasis_topic *stasis_cp_single_topic_cached( + struct stasis_cp_single *one); + +#endif /* _ASTERISK_STASIS_CACHE_PATTERN_H */ |