Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
02-06-2020 08:07 AM
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();
}
02-10-2020 08:20 AM
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
02-10-2020 09:15 AM
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
02-10-2020 09:22 AM
emailed you a bit more info
All the sessions of the conference are now available online