private async Task<EventPage> fetchNextPage(long lastEncountered)
{
using (var conn = _connectionFactory.Create())
{
try
{
await conn.OpenAsync(_token).ConfigureAwait(false);
var lastPossible = lastEncountered + _options.PageSize;
var sql =
$@"
select seq_id from {_selector.Events.DatabaseSchemaName}.mt_events where seq_id > :last and seq_id <= :limit and age(transaction_timestamp(), {_selector.Events.DatabaseSchemaName}.mt_events.timestamp) >= :buffer order by seq_id;
{_selector.ToSelectClause(null)} where seq_id > :last and seq_id <= :limit and type = ANY(:types) and age(transaction_timestamp(), {_selector.Events.DatabaseSchemaName}.mt_events.timestamp) >= :buffer order by seq_id;
select min(seq_id) from {_selector.Events.DatabaseSchemaName}.mt_events where seq_id > :limit and type = ANY(:types) and age(transaction_timestamp(), {_selector.Events.DatabaseSchemaName}.mt_events.timestamp) >= :buffer;
select max(seq_id) from {_selector.Events.DatabaseSchemaName}.mt_events where seq_id >= :limit and age(transaction_timestamp(), {_selector.Events.DatabaseSchemaName}.mt_events.timestamp) >= :buffer
".Replace(" as d", "");
var cmd = conn.CreateCommand(sql)
.With("last", lastEncountered)
.With("limit", lastPossible)
.With("buffer", _settings.LeadingEdgeBuffer)
.With("types", EventTypeNames, NpgsqlDbType.Array | NpgsqlDbType.Varchar);
var page = await buildEventPage(lastEncountered, cmd).ConfigureAwait(false);
if (page.Count == 0 || page.IsSequential())
{
return page;
}
var starting = page;
await Task.Delay(250, _token).ConfigureAwait(false);
page = await buildEventPage(lastEncountered, cmd).ConfigureAwait(false);
while (!page.CanContinueProcessing(starting.Sequences))
{
starting = page;
page = await buildEventPage(lastEncountered, cmd).ConfigureAwait(false);
}
return page;
}
finally
{
conn.Close();
}
}
}