Sharing a Bucket across request

#1

I am using .NET SDK for connection to a Server (Currently only a single machine), I am using it for my cache and the CouchBase Server communication is handled by a singleton class which opens a bucket initially and kept it open , the code inside my class to open the bucket is
var _cluster = ClusterHelper.Get();
var _defaultBucket = ClusterHelper.GetBucket(_bucket);// _bucket is initailised to my bucket name currently default.

And I am using this in a web application , above code is executed only on the first request. subsequent requests use the same object and uses the _default bucket to add/ edit/delete docs from the bucket.but it seems that after some time my Server communication is either time out or too slow, Is there a problem sharing the same object across different requests(each request adds a unique key value pair and read it.)

The code for adding a document is as below

public bool Add(string key, T value)
{
CheckConnection();
if (_defaultBucket.Exists(key))
return _defaultBucket.Upsert(key, value).Success;
var result = _defaultBucket.Insert(key, value);

        return result.Success;


    }

private void CheckConnection()
{
if (!_initialized) Initilize();
if (!_cluster.IsOpen(_bucket)) _defaultBucket = ClusterHelper.GetBucket(_bucket);
}

#2

Hi @jereesh,
We recommend sharing a single instance of a bucket for the lifetime of the application. This is due to the setup time and resources need to configure setup the bucket connection.

ClusterHelper found in the SDK is a singleton implementation and the recommended way to get a bucket instance.

First call ClusterHelper.Initialize, with the settings for the cluster.
There after call ClusterHelper.GetBucket, with bucket name and password to get a shared a thread safe instance to the bucket.

I hope this helps
Martin

1 Like
#3

Hi Martin,
I am using it as singleton only Here is my code , All classes using interface ISingleton is Singleton Which are created by an IOC container

public class CouchCacheBase : ISingletonContext
{
IList _cacheServers;
bool _initialized;
ClientConfiguration _clientConfig;
bool _disposed;
IBucket _defaultBucket;
Cluster _cluster;
string _bucket;

    public CouchCacheBase(IList<Uri> servers,string bucket)
    {
       
        _bucket = bucket;
        _cacheServers = servers == null ? new List<Uri>() : servers;
    }


    public void Initilize()
    {
        _clientConfig = new ClientConfiguration();

        if (_cacheServers.Count == 0)
        {
            _cacheServers.Add(new Uri(Properties.Settings.Default.CouchUri));
        }
        _clientConfig.Servers.AddRange(_cacheServers);
        ClusterHelper.Initialize(_clientConfig);
        _cluster = ClusterHelper.Get();
        _defaultBucket = ClusterHelper.GetBucket(_bucket);

        _initialized = true;

    }
    public bool Add<T>(string key, T value)
    {
        CheckConnection();
        if (_defaultBucket.Exists(key))
            return _defaultBucket.Upsert<T>(key, value).Success;
        var result = _defaultBucket.Insert<T>(key, value);
      
                   

        return result.Success;


    }
    public bool AddOrUpdate<T>(string key, T value)
    {
        CheckConnection();
        var result = _defaultBucket.Upsert<T>(key, value);
        return result.Success;
    }
    public T Get<T>(string key)
    {
        CheckConnection();
        var result = _defaultBucket.Get<T>(key);
        if (result.Success)
            return result.Value;
        else
            return default(T);
    }
    public T Remove<T>(string key)
    {

        CheckConnection();

        if (!_defaultBucket.Exists(key))
            return default(T);
        else
        {
            var result = _defaultBucket.Get<T>(key);
            _defaultBucket.Remove(key);
            return result.Value;
        }

    }

    public void Dispose()
    {

        if (!_disposed)
        {
            if (ClusterHelper.Get().IsOpen(_bucket))
            {
                ClusterHelper.Get().Dispose();
            }

            _disposed = true;
        }

    }

    private void CheckConnection()
    {
        if (!_initialized) Initilize();
        if (!_cluster.IsOpen(_bucket)) _defaultBucket = ClusterHelper.GetBucket(_bucket);
    }
}

Is anything Wrong with the code ? Or is it My server is causing issues.
Cheers,
Jereesh

#4

Hi @jereesh,
The code look okay nothing that stands out as being wrong.
What IOC Framework are you using? Is it possible that it creates more than one instance?

#5

I have just tried to see how I could get two instances using ClusterHelper…

        ClusterHelper.Initialize(config);

        var c1 = ClusterHelper.Get();

        ClusterHelper.Initialize(config);

        var c2 = ClusterHelper.Get();
        bool equal = c1 == c2; // FALSE

Could it be that the ICO framework runs Initialize more than once?

#6

@Martin,
I am using Castle Windsor as IOC, The object is created only once and I have tested it by adding some logs. The Initialize method is called only once when the Object first get created then it is being reused for all subsequent requests.

#7

@jereesh -

Can you enable logging and post them? Instructions are here: http://docs.couchbase.com/developer/dotnet-2.1/setting-up-logging.html

-Jeff