Neo4jClient: ObjectDisposedException: Cannot open a new session on a driver that is already disposed. Object name: 'Driver'. or Object name: 'ConnectionPool'.
Describe the bug Having lots of issues related to connection. Cannot open a new session on a driver that is already disposed.
Versions:
- Neo4jClient 4.1.5
- Bolt or Http BoltGraphClient
- .NET Version 5 (ASP.Net / Blazor server-side)
- Server Version neo4j Community 4.1.6
- Using
neo4j+s://
protocol
To Reproduce
I have a static IGraphClient c;
that is instantiated to a BoltGraphClient
After some seconds I instantiate a new BoltGraphClient and assign to c
“Randomly” (Thread related?) I get this error when trying to use this connection :
An unhandled exception occurred while processing the request.
ObjectDisposedException: Failed to acquire a new connection as the driver has already been disposed.
Object name: 'ConnectionPool'.
ObjectDisposedException: Failed to acquire a new connection as the driver has already been disposed. Object name: 'ConnectionPool'.
ObjectDisposedException: Cannot open a new session on a driver that is already disposed.
Object name: 'Driver'.
Neo4j.Driver.Internal.Driver.ThrowDriverClosedException()
Neo4j.Driver.Internal.Driver.Session(Action<SessionConfigBuilder> action, bool reactive)
Neo4j.Driver.Internal.Driver.AsyncSession(Action<SessionConfigBuilder> action)
Neo4jClient.BoltGraphClient.Neo4jClient.IRawGraphClient.ExecuteGetCypherResultsAsync<TResult>(CypherQuery query)
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 22 (12 by maintainers)
awesome!
Definitely reopen if you need more work on it!
Hey @TonyHenrique
How is this going?
Chris
There is only one point in the client where the
Driver
is disposed - here - so if your code is callingDispose
on your client instance, that is the only point where theNeo4jClient
code is calling it.Obviously you can call
Dispose
on the.Driver
property directly which would also elicit this error message. I would strongly recommend you remove any code that is doing this, you do not need to manage theDriver
, and it’ll make debugging a lot easier if we only have one thing to worry about. If that is the case then we’re in a good place.In terms of debugging this - you’ll probably find that a log message when you create/dispose of the client will show some race conditions. Are you using the client within a
using
anywhere? In theory if you’re using the DI from the framework - you don’t need to care about the disposal at all - that’ll handle it all.Another thought could be that the testing framework might be terminating a request early, and due to async-ness the session is ended whilst another thread is starting up a query.
As a side note - instead of tearing down the whole client / driver yourself, you can also call
ConnectAsync
again - which will redo theDriver
for you.NB. It’s not because it’s
static
per se, but because it’sstatic
in a web scenario, where your sessions will tidy themselves upBut you’re still storing it in a
static
variable - that’s the problem - if you’re injecting it - you shouldn’t be doing that.This: https://github.com/DotNet4Neo4j/MoviesMvcCore/blob/49f8630e523a5a8ba815bcd1031b05ee538a20bd/src/MoviesMvcCore/Startup.cs#L25
shows how I did it for a .NET core app
Ok, does the Blazor app have a
startup.cs
file? I’m not sure of the standard layout - but most of these default things from MS have IOC/DI things built in - and I really think that’s where this is coming from.Static members in a web app are super scary as they are shared by all the sessions - and that means the whole lifecycle, and it’s possible that one session is finishing as another starts, disposes and causes this.
I think you’re going to need to provide some sort of working example of this, I’ve tried the code below, but I don’t get the error - but that’s not necessarily unexpected. If you can do it in LinqPad - the attached file will give you a template with Neo4jClient ready to go.
Empty-Neo4jClient.zip