Files
asterisk/include/asterisk/stasis_cache_pattern.h
David M. Lee e1b959ccbb 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
2013-08-01 13:49:34 +00:00

154 lines
4.5 KiB
C

/*
* 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 */