[asterisk-scf-dev] Changes regarding state replicator keys

Mark Michelson mmichelson at digium.com
Mon Dec 13 12:01:37 CST 2010


Hey folks. I've come across a bit of an issue regarding the use of keys 
for state replicator objects in Asterisk SCF. To give a bit of 
background, I'm working on implementing a new storage backend for state 
replication that would use memcached. I've chosen to use libmemcached to 
access memcached because it is license-compatible with Asterisk SCF, has 
the necessary functionality, is used widely, has active development, has 
a Windows port, and has support for IPv6.

In the current C++ state replicator code, the item key used by state 
replicators is a templated type K. For the original storage 
implementation using an in-memory vector, this worked fine. However, 
using libmemcached is causing a bit of trouble because of two things:

1) libmemcached's API requires the size of the key to be given as a 
parameter to most functions.
2) libmemcached wants the key formatted as a const char * (i.e. a 
sequence of bytes).

Getting the size of a templated type or formatting it as a sequence of 
bytes is not something that can be done without making assumptions 
regarding the member operations of K. To rectify this deficiency, I've 
come up with several potential methods of dealing with the situation.

1) Instead of using a templated type for the key, use std::string. 
std::string has a .c_str() method that will give a const char * to the 
actual string content, and std::string has a size() method for reporting 
the size of the string.

Advantages: All implemented state replicator items as well as those 
under development are currently using std::string anyway, so it wouldn't 
require much change outside the state replicator itself.

Disadvantages: Forcing components to use std::string is restrictive and 
may force awkward conversions in components that can more naturally 
identify its items with other types.

2) Instead of using a templated type for the key, define a StateItemKey 
class in slice. Each component that provides replicated items will also 
define a subclass (or potentially more if it makes sense) of 
StateItemKey that has whatever information they wish to use to identify 
an item. By defining the key type as a slice class, this allows for the 
Ice streaming interface to convert the object into a byte stream. Its 
size can be determined from the resulting byte stream.

Advantages: Allows freedom for components to use keys that feel natural.

Disadvantages: Requires some rewriting of currently implemented code, 
though admittedly not much. Also, the Ice streaming interface is only 
available in C++, Java, and C#.

3) Don't make any changes to the state replicator code. Instead, in the 
memcached storage implementation, create a std::string key for every 
opaque state item key received. Then keep a map of local string keys and 
their matching opaque state item keys. Whenever an operation is invoked 
on the memcached state replicator that involves a key, first find the 
corresponding string key and then use that key for the calls into 
libmemcached.

Advantages: Requires no changes to be made at all to existing code.

Disadvantages: Adds extra overhead to the memcached state replicator code.

So those are the three methods I've come up with for addressing the 
situation. My personal preference is to either use method 2 or 3, but I 
am open to other suggestions.

Thanks,
Mark Michelson



More information about the asterisk-scf-dev mailing list