cancel
Showing results for 
Search instead for 
Did you mean: 

Join the community at Nodes 2022, our free virtual event on November 16 - 17.

Issue with invalid session using V4 Driver against Neo Database V3.5.14

SimonWren
Node

Hi

We are seeing a recurring issue using V4 Bolt driver to connect to talk to V3.5.14 Community Edition database.

Under constant low load, about 10% of transactions fail with.

"Neo4j.Driver: Cannot access records on this result any more as the result has already been consumed or the query runner where the result is created has already been closed."

The exception is thrown by GetListOfRecordsAsync

Reverting to an earlier version of the Driver seems to remove this behavior.

I've also been able to recreate this connecting to a Desktop edition V3.5.9

Any advice would be greatly appreciated.

See below for code snippet.

Many thanks
S

public IDriver CreateDriver(string uri, IAuthToken authToken, Neo4jLoggingHelper log)
        {
            return GraphDatabase.Driver(uri, authToken,
                o => o.WithMaxConnectionLifetime(TimeSpan.FromMinutes(30))
                    .WithMaxConnectionPoolSize(50)
                    .WithConnectionAcquisitionTimeout(TimeSpan.FromMinutes(2))
                    .WithLogger(log));
        }

        public async Task<object> ExecuteCypherQueryInNeo4JAsync(string query, IDictionary<string, object> statementParameters, Neo4jLoggingHelper log)
        {
            if (_neo4JDriver == null)
            {
               // _log4j = new DriverLogger(log);
                log.Info("Making initial bolt connection");
                _neo4JDriver = CreateDriver(_neo4JUrl, _authToken, log);
            }

            
            Object result = null;
           
IAsyncSession session = _neo4JDriver.AsyncSession();

                try
                {
                    result = await session.ReadTransactionAsync(async tx =>
                    {
                        _resultCursor = await tx.RunAsync(query, statementParameters);
                        var records = await GetListOfRecordsAsync();
                        var summary = await _resultCursor.ConsumeAsync();
                        log.resultsReadyAfter = (long)summary.ResultAvailableAfter.TotalMilliseconds;
                        log.resultsConsumedAfter = (long)summary.ResultConsumedAfter.TotalMilliseconds;
                        log.resultsRetries = i;
                        return records;
                    });
                }
                catch (Exception e)
                {
                    log.Warn(e,"Failed at attempt {i} of 5: ");
                    fail = true;
                }
                finally
                {
                    await session.CloseAsync();
                }

3 REPLIES 3

charlotte_skard
Graph Buddy

Hi there,

Can you expand on what GetListOfRecordsAsync does? - and can you get this to happen on something like the Movies graph? Or give some indication of the query and statementParameters you're passing in?

I'm trying to replicate the code, but I'm having a bit of trouble with that bit.

Thanks!

Chris

SimonWren
Node

Hi Chris,

Thanks for your reply.

What I've discovered today... this appears to be about concurrent requests. Singularly it's fine, but as soon as there are concurrent requests hitting the code, the ConsumeAsync (not the GetRecordsAsync as I originally thought ) starts hitting problems. I've tried removing this line and found it works without issue.

We are passing in a read only query with a couple of params

        private async Task<object> GetListOfRecordsAsync()
        {
            var records =  await _resultCursor.ToListAsync();

            if (records == null || !records.Any())
                return null;

            var neoRecords = records.SelectMany(x => x.Values.Values);

            return neoRecords.FirstOrDefault();
        }

Kinds Regards,
Simon

emailed you a bit more info