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(); } } }
public async Task <EventPage> FetchNextPage(long lastEncountered) { var lastPossible = lastEncountered + _options.PageSize; var sql = $@" select max(seq_id) from mt_events where seq_id > :last and seq_id <= :limit; {_selector.ToSelectClause(null)} where seq_id > :last and seq_id <= :limit and type = ANY(:types) order by seq_id; "; var cmd = _conn.CreateCommand().Sql(sql) .With("last", lastEncountered) .With("limit", lastPossible) .With("types", _options.EventTypeNames, NpgsqlDbType.Array | NpgsqlDbType.Varchar); long furthestExtant; IList <IEvent> events = null; using (var reader = await cmd.ExecuteReaderAsync(Cancellation).ConfigureAwait(false)) { await reader.ReadAsync(Cancellation).ConfigureAwait(false); furthestExtant = await reader.GetFieldValueAsync <long>(0, Cancellation).ConfigureAwait(false); await reader.NextResultAsync(Cancellation).ConfigureAwait(false); events = await _selector.ReadAsync(reader, _map, Cancellation).ConfigureAwait(false); } var streams = events.GroupBy(x => x.StreamId).Select(group => { return(new EventStream(group.Key, group.OrderBy(x => x.Version).ToArray(), false)); }).ToArray(); return(new EventPage(lastEncountered, furthestExtant, streams)); }
public Fetcher(IDocumentStore store, DaemonSettings settings, AsyncOptions options, IDaemonLogger logger, IDaemonErrorHandler errorHandler, IEnumerable <Type> eventTypes) { _settings = settings; _options = options; _logger = logger; _errorHandler = errorHandler; State = FetcherState.Waiting; // TODO -- this will have to change _tenant = store.Tenancy.Default; _selector = new EventSelector(store.Events, store.Advanced.Serializer); _map = new NulloIdentityMap(store.Advanced.Serializer); EventTypeNames = eventTypes.Select(x => store.Events.EventMappingFor(x).Alias).ToArray(); _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", ""); }