a) It is a costly operation to create a new LDAP connection
b) It might give you problems under heavy load, with problems like "LDAP
Server not available".
Let look at problem b) closer. Please correct me if my analysis is
wrong. I think the problem is that when a LDAP connection is closed it
will still use up a TCP port/conection with state "time_wait". So with a
lot of concurrent calls you might end up running out of available TCP
ports. Even if they have been closed form the applicaton they still take
up a tcp port fr some time after it has been closed.
If you instead use one LDAP connection which you reuse for all calls
then there will be only one conection (but which will be in use).
To cache that connection in a static objetc or something should not be a
problem. However I see two possible problems:
1) Is it safe to use the same LDAP connection concurrently by different
threads or must each thread have its own connection? if a single
connection can't be used by more than one thread then we need to have
multiple conections and mark each as "in use" when one thread is using
it and then ut it back again after use.
2) LDAP server is down or other problems which might have made the
connection no longer available, we need to recreate a new connection.
AFAIK, there are no method to test that a current LDAP connection is
still available other than executing a call and check if we get an
exception ("LDAP Server not available" probably) and in that case
recreate a new connection and run the command again.
Connection pooling should handle your connections behind the scenes
seamlessly. I cannot find documentation on how it works with sds.protocols,
except the discussion in this thread:
http://directoryprogramming.net/forums/permalink/5917/5972/ShowThread.aspx#5972
In other environments I keep my connection open and let the provider manage
things for me. When I need to use the connection, the provider gives me one
from the pool. When the connection is not in use it is returned to the pool.
To me it looks like I have one connection open the whole time.
--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--
AFAIK, there is no Connection pooling for SDS.Protocols, only for SDS.
There have been a number of discussion threads concerning this subject on my
forum (www.directoryprogramming.net) that you might want to look at.
The bottom line is that you DO want to minimize the number of connections to
the server by implementing some type of shared pool if possible. My
understanding is that the connection itself is supposed to be thread safe
for multiple operations, but I've also seen code from Microsoft that
carefully serializes access to the shared connection object(s). Not sure if
they are doing that to be safe or if it is really needed. :)
In terms of implementing a pool, you could create your own data structure to
manage them or perhaps use thread local storage for storage of
thread-specific connection objects. Either approach could work. You could
also just have one shared one.
In terms of implementing failover, that's basically a separate topic. As I
recall, as person posting on the forum recently concluded that they got very
good behavior by using the constructor for the DirectoryIdentifier that
allows you to specify multiple host names. I'd try to find that thread and
see if it provides you with additional useful details.
--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
"Magnusb" <mag...@sbbs.se> wrote in message
news:MPG.254fe71f3...@msnews.microsoft.com...
> There have been a number of discussion threads concerning this subject on my
> forum (www.directoryprogramming.net) that you might want to look at.
Yes, I know. Maybe need to check again for more info.
> The bottom line is that you DO want to minimize the number of connections to
> the server by implementing some type of shared pool if possible. My
> understanding is that the connection itself is supposed to be thread safe
> for multiple operations, but I've also seen code from Microsoft that
> carefully serializes access to the shared connection object(s). Not sure if
> they are doing that to be safe or if it is really needed. :)
I have run some tests and it seems there are no problem (so far) when
multiple threads is using the same connection. Not got any errors at
least. However, it looks like you can't change SessionOptions settings
on an existing connection (which will require you to do a new Bind().
For example sometimes I need to set SessionOptions.Sealing= true (not
sure when you need this but looks like setting password require it).
When I did that on a foreground thread, the background thread throw a
DirectoryOperation exception.
However I expected to get some problems when doing so.
> In terms of implementing a pool, you could create your own data structure to
> manage them or perhaps use thread local storage for storage of
> thread-specific connection objects. Either approach could work. You could
> also just have one shared one.
What I have done so far is to use one global shared connection (or more
correctly one connection for each domain the application connects to).
Note: We always use the same service account for accessing the domains
so no need to have sepearate connections for different credentials (as I
think Connection pooling in SDS does it).
But our approach means that we keep the connection alive for as long as
the webapplication runs (which means forever or when recycled). Do you
think there are any problems doing so?
Also is there any possible performance problems using one single
connection for multiple concurrent requests? Will there be a queue for
each request so maybe one single shared connection is less efficient
than one connection for each thread?
We got a kind of legacy code problem and trying to find a solution which
works without having to change to much code. From the beginning every
method that is doing som AD operation will create it's own connection
and close it after use. Some of these methods are very basic (in a
separate assembly as well) doing one specific thing. So for example the
operation to create a new user might mean we do something like this:
1) Check if user exists ( CheckUserExists(...)
2) Create new user (CreateUser(...))
3) Set password (SetPassword(...)
4) Add user to group X, Y, Z (AddMember(...))
In this example it would mean we would call 4 different methods each
creating a new conection.
A better solution would of course be to first create a connection then
do all the operations using the same connection. Or possibly have a
single method doing everything (but this might be a worse design for
other reasons). But that would require a lot of changes to code and it
is not a trivial application. So we try to find a solution which would
let us share connections but without having to change a lot of code.
The current solution using one single connection works pretty well so
far and it was possible to do with minimal code changes.
if we create individual connections for each concurrent thread/session
might require keeping track of connections and closing them when no
longer in use etc.
BTW, I have noticed that there seem to be some automatic
closing/reopening connection. I had an ongoing connection but after
leaving it without doing anything for a while and I checked netstat and
the connection was gone. But when I made the next access using the same
connection in .NET it created a new physical connection automatically.
> In terms of implementing failover, that's basically a separate topic. As I
> recall, as person posting on the forum recently concluded that they got very
> good behavior by using the constructor for the DirectoryIdentifier that
> allows you to specify multiple host names. I'd try to find that thread and
> see if it provides you with additional useful details.
Hehe no need to do that. It was I who posted about it. Yes very nice and
well hidden feature :-).
Thank you for your reply.
Magnus