Couchbase
  • Why NoSQL?
  • Couchbase Server
  • Download
  • Resources
  • Careers
Home | Forums | SDKs | SDKs

When to create Couchbase Client in a web service (.NET)

13 replies [Last post]
  • Login or register to post comments
Fri, 10/05/2012 - 08:56
gunnduncan
Offline
Joined: 10/05/2012
Groups: None

This should be a ridiculously easy question, so apologies for this.

The wiki (http://www.couchbase.com/wiki/display/couchbase/Couchbase+.NET+Client+Li...) states that creating the client should be done once per app domain.

If I have a WCF web service (stateless), when should I create this client?

Any indications or pointers you can give me would be great

Thanks a lot

Duncan

Top
  • Login or register to post comments
Fri, 10/05/2012 - 11:07
john
Offline
Joined: 01/05/2012
Groups: None

My WCF experience is a bit limited, so I'm relying on some binging to provide an answer - so my apologies if my assumptions are flawed...

One approach would be to decorate your Service class with the attribute below making your service a singleton (single instance mode). Per session would at least reduce the number of times your service is created, but still, you'd end up creating a new CouchbaseClient instance per client.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
public class Service : IService
{
}

You could also enable ASP.NET compatibility (if using IIS and HTTP). I wrote up some more details/suggestions on the wiki:

http://www.couchbase.com/wiki/display/couchbase/Couchbase+.NET+Client+Li...

Top
  • Login or register to post comments
Mon, 10/08/2012 - 01:41
gunnduncan
Offline
Joined: 10/05/2012
Groups: None

Thanks John; I've had a look into this but I don't think single instance mode will help in this situation, mainly because I don't want to risk multi-threading code. However I'll have a look at ASP.NET compatibility, as this service will only ever be hosted in IIS, so my current thinking is to create the client on the Application, so all service instances will use this one instance.

Unless any .NET gurus could tell me that this will be a world of pain, thread safety wise??!

Top
  • Login or register to post comments
Mon, 10/08/2012 - 01:50
gunnduncan
Offline
Joined: 10/05/2012
Groups: None

Is this what I want to be doing?

public static class CouchbaseClientManager
{
private static CouchbaseClient _instance;

public static CouchbaseClient CouchbaseInstance
{
get
{
if (_instance == null)
{
_instance = new CouchbaseClient();
}
return _instance;
}
}
}

http://stackoverflow.com/questions/4984358/static-variables-in-wcf

Top
  • Login or register to post comments
Mon, 10/08/2012 - 03:32
gunnduncan
Offline
Joined: 10/05/2012
Groups: None

Hmm, by the looks of it I need to write some lock code to support the following, according to this:
http://www.couchbase.com/docs/couchbase-devguide-2.0/threading-in-sdks.html

public class NETCacheAdapter: ICacheAdapter
{
public object GetItemFromCache(string key)
{
object obj;
try
{
//Warning: This is not thread safe!
var client = HttpContext.Current.Application[Constants.C_COUCHBASE] as CouchbaseClient;
obj = client.Get(key);
}
catch
{
//If *anything* goes wrong then just carry on as usual
obj = null;
}
return obj;
}

Top
  • Login or register to post comments
Mon, 10/08/2012 - 08:10
john
Offline
Joined: 01/05/2012
Groups: None

If you're going to use the ASP.NET compatibility and you add a Global.asax, you should be able to use the approach outlined here - http://www.couchbase.com/docs/couchbase-sdk-net-1.1/stage2.html.

Top
  • Login or register to post comments
Fri, 12/14/2012 - 10:05
gunnduncan
Offline
Joined: 10/05/2012
Groups: None

I wanted to give this a *bump* as I'm still struggling with this. My stress tests can't get anywhere near the expected performance reported by Couchbase, and I suspect this is because I have to do an expensive using(var client = new CouchbaseClient()) call in each request.

WCF is completely stateless, so there will be no Application object etc (the example provided in the docs is for an ASP.NET application).

I can't change the InstanceContext I'm afraid.

Has there been any more discussion on this issue?

Thanks a lot
Duncan

Top
  • Login or register to post comments
Fri, 12/14/2012 - 10:20
ingenthr
Offline
Joined: 03/16/2010
Groups:

What's the normal approach with things that are stateful in WCF? I understand why from an application perspective it's completely stateless, but there are times having something stateful (like database connections) make sense for efficiency.

I think we'd like to help find a solution, for sure. Do you know how this sort of thing is normally handled?

Top
  • Login or register to post comments
Fri, 12/14/2012 - 16:19
john
Offline
Joined: 01/05/2012
Groups: None

Hi Duncan,

Unfortunately, I don't have an immediate suggestion for you. The client does need to bootstrap. Unlike many databases, Couchbase clients are "smart" - they know about the topology of the cluster. There's no man in the middle redirecting requests to the appropriate box. The discovery phase and initialization of connection pools is what's so expensive - and what is likely causing the slower performance. I'm going to spend some time soon to see what I can come up with and will post back here...

Top
  • Login or register to post comments
Wed, 12/19/2012 - 09:13
ekoostikmartin
Offline
Joined: 11/05/2012
Groups: None

I am following this thread, the response is very important to me as well. We intend to use couchbase extensively in WCF/WebAPI services, but are worried about this issue.

Setting services to single instance mode is not an option in our case.

Top
  • Login or register to post comments
Wed, 12/19/2012 - 16:25
gunnduncan
Offline
Joined: 10/05/2012
Groups: None

Thanks John, that's appreciated. It's great software and I'm sure other .NET devs will have the same question in time.

I changed it to SingleInstance and got a massive performance boost, so all the theory checks out, however I'm concerned with thread safety when moving to SingleInstance (but this is probably due to my own ignorance and I'll need to read up on it more)

Is the Couchbase client thread-safe? I did read an article that suggested it was not and we had to do our own locking of the client, but that may be a misunderstanding on my part.

Top
  • Login or register to post comments
Wed, 12/19/2012 - 16:25
gunnduncan
Offline
Joined: 10/05/2012
Groups: None

It's not something I usually concern myself with I'm afraid, as I've normally had acceptable performance from my services for the requirements. However we're now getting into an area of very high performance requirements and I need to be able to utilize technologies like Couchbase. My own stress tests show an improvement of at least 5 times, which is great.

AFAIK .NET automatically handles things like db connection pools etc, so a .NET programmer doesn't need to worry about this. However with 3rd party out-of-process apps like Couchbase or Mongo, we need to manage that state ourself, and surprisingly I've not been able to find that many answers (apart from making the service Single Instance) !

Top
  • Login or register to post comments
Fri, 12/21/2012 - 10:37
john
Offline
Joined: 01/05/2012
Groups: None

Well, we do have a connection pool that's part of the client. Unfortunately, that pool is created on the construction of the client instance.

Matt (from this thread) and I were discussing options for the WCF scenario. He had a thought on how we might avoid the bootstrapping on each client constructor. I've created an issue for it at http://www.couchbase.com/issues/browse/NCBC-188.

Another source of the slow startup for the object is creating that connection pool. By default, the client creates 10 connections to each server in your cluster. So if you have a multi-node cluster, that's 10 x n sockets being opened. One thing you could try in the near term is to modify the number of sockets that the client creates. Given the way WCF works, that's probably the correct thing to do, since you can't reuse the socket across requests.

To set that, add to your config a sibling of the servers element:

<couchbase>
    <servers>
      <add uri="http://127.0.0.1:8091/pools"/>
    </servers>
    <socketPool minPoolSize="1" maxPoolSize="1" />
</couchbase>

http://www.couchbase.com/docs/couchbase-sdk-net-1.2/couchbase-sdk-net-co...

Top
  • Login or register to post comments
Mon, 12/31/2012 - 07:58
gunnduncan
Offline
Joined: 10/05/2012
Groups: None

Hi John

Just wanted to provide some feedback for your reference. I tried what you suggested and while I got a little bit extra performance, it wasn't anywhere near when set to single instance.

For comparison (and these are to be referenced relatively):

- spin up client each time, without setting socketPool - approx 70 req/sec
- spin up client each time, using socketPool config outlined above - approx 100 req/sec
- single instance - approx 200 req/sec

Thanks for raising this as an issue
Duncan

Top
  • Login or register to post comments
  • Login or register to post comments
  • Login
  • Register

Company

  • About Us
  • Leadership
  • Customers
  • Partners
  • Contact Us

Product

  • Couchbase Server
  • Couchbase SDKs
  • Use Cases
  • Documentation
  • Forums

Open Source

  • Couchbase Project
  • Couchbase vs. CouchDB

Commercial

  • Subscriptions & Support
  • Training & Services

News

  • Blog
  • Newsletter
  • Press Releases
  • Buzz

Follow Us

    
  • Customer Login
  • Terms of Service
  • Privacy Policy
  • Trademark Policy
  • Site Map

© 2013 COUCHBASE All rights reserved.

Sign in to Couchbase Community

close
  • Create new account
  • Request new password
You are logging into the Forums, Wiki and Issue Tracker