Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 7 of 7 total
Thread ADO.NET broken upgrading from 227b1 to 228b5?
Wed, Aug 8 2018 6:20 AMPermanent Link

Hedley Muscroft

I've updated my app from EDB 227b1 to 228b5 and am now randomly receiving the following error :-

ElevateDB Error #1100 A connection to the server at 'localhost' cannot be established
Only one usage of each socket address (protocol/network address/port) is normally permitted

It's a WinForms app but I do use background threads, so my guess is that something has changed internally in your ADO.NET driver which is causing this problem.

In the meantime I've rolled back to 227b1 and the problem goes away.

Any ideas please?

Kind Regards,

Hedley
Wed, Aug 8 2018 12:35 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Hedley,

<< I've updated my app from EDB 227b1 to 228b5 and am now randomly receiving the following error :-

ElevateDB Error #1100 A connection to the server at 'localhost' cannot be established
Only one usage of each socket address (protocol/network address/port) is normally permitted >>

How "random" are we talking here ?  Does it happen often enough that you could send me an example ?

Does it ever occur *outside* of a thread ?

Tim Young
Elevate Software
www.elevatesoft.com
Wed, Aug 8 2018 1:52 PMPermanent Link

Hedley Muscroft

>> How "random" are we talking here?
>> Does it happen often enough that you could send me an example ?

In general use of our application, it will happen once every 5-10 minutes.

>> Does it ever occur *outside* of a thread ?

Hard to say because of the level of abstraction in my DB layer (we support multiple backend databases).

Actually, I've just reviewed my code and remembered that the way it works is that I in my EDB layer is that I maintain a cache of EDBConnection objects depending on what THREAD ID the operation is being performed on. I think I did this because (some years ago) I was experiencing problems with EDB when using the same EDBConnection object in multiple threads.

So basically, there is one persistent EDBConnection object for each "System.Threading.Thread.CurrentThread.ManagedThreadId" in the application. The connections are reference counted and disposed of when they're not in use.

I should say that this is old (solid) code that's been there for literally years. As soon as I roll back to 227b1 the problem is solved and it all works perfectly.

Could there be anything in 228b5 which would cause the problem: "Only one usage of each socket address (protocol/network address/port) is normally permitted"?
Thu, Aug 9 2018 4:21 AMPermanent Link

Matthew Jones

Hedley Muscroft wrote:

> "Only one usage of each socket address (protocol/network address/port) is normally permitted"

I'd certainly be interested to know what this actually comes from and means. It sounds like a server side thing, but obviously isn't.

However I will chip in with something that happened to me, as I was trying to be clever with threads and caches, and it bit me. Given .Net and async await, it may be relevant.

I decided that it made sense to have a connection to the database linked to the thread, as you have, to save opening and closing, and this appeared to work well. But I had forgotten that a web service has a number of threads and they serve a lot of different clients. So one thread might serve client A, connect to the database, do an operation, and then return. Client B comes in and the same database is used again. I forget the problem but it turned out that when I came back with another client A request, it assumed that the database was still in the same state, and fell over. In the end I restored reliability by just creating connections as needed. Obviously not directly relevant, but maybe might trigger a thought in someone.

--

Matthew Jones
Thu, Aug 9 2018 3:14 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Hedley,

<< Could there be anything in 228b5 which would cause the problem: "Only one usage of each socket address (protocol/network address/port) is normally permitted"? >>

Not really.  As Matthew indicates, this is typically a *server* error message that occurs when a socket tries to *listen* on a port that is already in use.

I'll do a source compare to see if anything in particular stands out, but it's also possible that *other* changes in EDB 2.28 changed the timing enough to expose a race condition in your code.

In the meantime, anything that you can get me that shows the issue would be very helpful. If I have that, then I can very easily determine what is going on.

Tim Young
Elevate Software
www.elevatesoft.com
Fri, Aug 10 2018 2:09 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Hedley,

Okay, I did a source compare and there were very little changes to the threading, client sockets, or remote session handling.  The only things that changed were some renames due to some shuffling of the way that OS calls are made (in preparation for the various OS ports), and some renames due to a renaming of the spin locks that are used for internal locking.  There were also two calls added to the remote sessions for handling clearing cached statements and procedures in 2.28.

IOW, I don't see anything "interesting" that could be responsible for what you're seeing.  The majority of the changes in 2.28 were specific to the I/O buffering (edbfilemgr and edbosfilemgr units) and statement/procedure caching (edblocal unit).  None of these units have anything to do with socket handling.

I actually did some more investigating into this issue, and it appears that this error can also occur when you have port exhaustion on the client machine.  More information:

https://support.socketlabs.com/index.php?/Knowledgebase/Article/View/61

Tim Young
Elevate Software
www.elevatesoft.com
Mon, Aug 13 2018 7:02 AMPermanent Link

Hedley Muscroft

OK - thanks for your help Tim (and Matthew),

I've updated our EDB database layer so that we're explicitly creating and destroying EDBConnections each time we need them (rather than holding a cache based on the thread ID) i.e...

using (EDBConnection con = getCon())
{
 // do something
}

This seems to have resolved the issue.

I've been using EDB for *many* years and I think the reason I originally had this caching code was either :-

(a) because we used to give users the option of using direct file-based access (rather than via EDBSRVR) and continually creating and opening EDBConnections hit performance; or
(b) because the EDBDataAdapter constructor didn't used to accept a ConnectionString and we had to pass in ready made EDBConnection objects manually.

It was a *long* time ago though, and I really don't remember why I wrote all the connection caching code to be honest, I just remember it was a necessity at the time.

Anyway, we seem to be working correctly now - thanks again for your help! Smile

Kind Regards,

Hedley
Image