public async Task Add(DispatchStreamJob job, CancellationToken token)
        {
            var table = await _table.GetOrCreate();

            var entity = new DispatchStreamRecoveryJobTableEntity
            {
                PartitionKey = "StreamsToDispatchOnRecovery",
                RowKey       = $"R^{job.StreamId.Value}^{job.SessionId.Value}",
                StreamId     = job.StreamId.Value
            };
            var operation = TableOperation.Insert(entity);
            await table.ExecuteAsync(operation, token);
        }
        public async Task <CurrentPageIndexTableEntity> Get(CancellationToken token)
        {
            var table = await _table.GetOrCreate();

            var query = table.CreateQuery <CurrentPageIndexTableEntity>()
                        .Where(x => x.PartitionKey == "Indexes")
                        .Where(x => x.RowKey == "CurrentPageIndex")
                        .Take(1)
                        .AsTableQuery();

            CurrentPageIndexTableEntity entity;

            do
            {
                token.ThrowIfCancellationRequested();
                var segment = await table.ExecuteQuerySegmentedAsync(query, null, token);

                entity = segment.SingleOrDefault() ?? await Create(table, token);
            } while (entity == null);
            return(entity);
        }
示例#3
0
        public async Task Dispatch(List <EventToDispatchRecordTableEntity> events, CancellationToken token)
        {
            var table = await _table.GetOrCreate();

            CurrentPageIndexTableEntity   pageIndex;
            EventStorePageInfoTableEntity pageInfo;

            var eventsCount = events.Count;
            var eventIndex  = 0L;

            do
            {
                token.ThrowIfCancellationRequested();

                pageIndex = await _provideCurrentPageIndexes.Get(token);

                var partitionKey = $"P^{pageIndex.Index:x16}";

                var queryCurrentPageInfo = table.CreateQuery <EventStorePageInfoTableEntity>()
                                           .Where(x => x.PartitionKey == partitionKey)
                                           .Where(x => x.RowKey == PageInfoRowKey)
                                           .Take(1)
                                           .AsTableQuery();

                var result = await table.ExecuteQuerySegmentedAsync(queryCurrentPageInfo, null, token);

                pageInfo = result.SingleOrDefault();

                if (pageInfo == null)
                {
                    eventIndex = 0;
                    pageInfo   = new EventStorePageInfoTableEntity
                    {
                        PartitionKey  = partitionKey,
                        RowKey        = PageInfoRowKey,
                        NextIndex     = eventsCount,
                        NextPageIndex = 0
                    };
                    if (pageInfo.NextIndex > _pageSize)
                    {
                        pageInfo.NextPageIndex = pageIndex.Index + 1;
                    }
                    var operation = TableOperation.Insert(pageInfo);
                    try
                    {
                        await table.ExecuteAsync(operation, token);
                    }
                    catch (StorageException e)
                    {
                        if (e.RequestInformation.HttpStatusCode != (int)HttpStatusCode.Conflict)
                        {
                            throw;
                        }
                        pageInfo = null;
                    }
                }
                else
                {
                    if (pageInfo.NextPageIndex == UndefinedNextPageIndex)
                    {
                        eventIndex          = pageInfo.NextIndex;
                        pageInfo.NextIndex += eventsCount;
                        if (pageInfo.NextIndex > _pageSize)
                        {
                            pageInfo.NextPageIndex = pageIndex.Index + 1;
                        }
                        var operation = TableOperation.Replace(pageInfo);
                        try
                        {
                            await table.ExecuteAsync(operation, token);
                        }
                        catch (StorageException e)
                        {
                            if (e.RequestInformation.HttpStatusCode != (int)HttpStatusCode.PreconditionFailed)
                            {
                                throw;
                            }
                            pageInfo = null;
                        }
                    }
                    else
                    {
                        pageIndex.Index = pageInfo.NextPageIndex;
                        await _updateCurrentPageIndexes.TryUpdate(pageIndex, token);

                        pageInfo = null;
                    }
                }
            } while (pageInfo == null);

            var batchOperation = new TableBatchOperation();

            foreach (var @event in events)
            {
                var record = new EventStoreRecordTableEntity
                {
                    PartitionKey  = $"P^{pageIndex.Index:x16}",
                    RowKey        = $"E^{eventIndex:x16}",
                    PageIndex     = pageIndex.Index,
                    RowIndex      = eventIndex,
                    AggregateType = @event.AggregateType,
                    BucketId      = @event.BucketId,
                    AggregateId   = @event.AggregateId,
                    SessionId     = @event.SessionId,
                    Version       = @event.Version,
                    Created       = @event.Created,
                    Type          = @event.Type,
                    Payload       = @event.Payload
                };
                eventIndex++;
                batchOperation.InsertOrReplace(record);
            }

            await table.ExecuteBatchAsync(batchOperation, token);
        }