Ejemplo n.º 1
0
        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="connection">TBD</param>
        /// <param name="cancellationToken">TBD</param>
        /// <param name="write">TBD</param>
        /// <returns>TBD</returns>
        public virtual async Task InsertBatchAsync(DbConnection connection, CancellationToken cancellationToken, WriteJournalBatch write)
        {
            using (var command = GetCommand(connection, InsertEventSql))
                using (var tx = connection.BeginTransaction())
                {
                    command.Transaction = tx;

                    foreach (var entry in write.EntryTags)
                    {
                        var evt  = entry.Key;
                        var tags = entry.Value;

                        WriteEvent(command, evt.WithTimestamp(DateTime.UtcNow.Ticks), tags);
                        await command.ExecuteScalarAsync(cancellationToken);

                        command.Parameters.Clear();
                    }

                    tx.Commit();
                }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Asynchronously writes all persistent <paramref name="messages"/> inside SQL Server database.
        /// 
        /// Specific table used for message persistence may be defined through configuration within 
        /// 'akka.persistence.journal.sql-server' scope with 'schema-name' and 'table-name' keys.
        /// </summary>
        protected override async Task<IImmutableList<Exception>> WriteMessagesAsync(IEnumerable<AtomicWrite> messages)
        {
            var persistenceIds = new HashSet<string>();
            var allTags = new HashSet<string>();

            var writeTasks = messages.Select(async message =>
            {
                using (var connection = CreateDbConnection())
                {
                    await connection.OpenAsync();

                    var eventToTags = new Dictionary<IPersistentRepresentation, IImmutableSet<string>>();
                    var persistentMessages = ((IImmutableList<IPersistentRepresentation>)message.Payload).ToArray();
                    for (int i = 0; i < persistentMessages.Length; i++)
                    {
                        var p = persistentMessages[i];
                        if (p.Payload is Tagged)
                        {
                            var tagged = (Tagged)p.Payload;
                            persistentMessages[i] = p = p.WithPayload(tagged.Payload);
                            if (tagged.Tags.Count != 0)
                            {
                                allTags.UnionWith(tagged.Tags);
                                eventToTags.Add(p, tagged.Tags);
                            }
                            else eventToTags.Add(p, ImmutableHashSet<string>.Empty);
                        }
                        else eventToTags.Add(p, ImmutableHashSet<string>.Empty);

                        if (IsTagId(p.PersistenceId))
                            throw new InvalidOperationException($"Persistence Id {p.PersistenceId} must not start with {QueryExecutor.Configuration.TagsColumnName}");

                        NotifyNewPersistenceIdAdded(p.PersistenceId);
                    }

                    var batch = new WriteJournalBatch(eventToTags);
                    await QueryExecutor.InsertBatchAsync(connection, _pendingRequestsCancellation.Token, batch);
                }
            });

            var result = await Task<IImmutableList<Exception>>
                .Factory
                .ContinueWhenAll(writeTasks.ToArray(),
                    tasks => tasks.Select(t => t.IsFaulted ? TryUnwrapException(t.Exception) : null).ToImmutableList());

            if (HasPersistenceIdSubscribers)
            {
                foreach (var persistenceId in persistenceIds)
                {
                    NotifyPersistenceIdChange(persistenceId);
                }
            }

            if (HasTagSubscribers && allTags.Count != 0)
            {
                foreach (var tag in allTags)
                {
                    NotifyTagChange(tag);
                }
            }

            return result;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Asynchronously writes all persistent <paramref name="messages"/> inside SQL Server database.
        ///
        /// Specific table used for message persistence may be defined through configuration within
        /// 'akka.persistence.journal.sql-server' scope with 'schema-name' and 'table-name' keys.
        /// </summary>
        /// <param name="messages">TBD</param>
        /// <exception cref="InvalidOperationException">TBD</exception>
        /// <returns>TBD</returns>
        protected override async Task <IImmutableList <Exception> > WriteMessagesAsync(IEnumerable <AtomicWrite> messages)
        {
            var persistenceIds = new HashSet <string>();
            var allTags        = new HashSet <string>();

            var writeTasks = messages.Select(async message =>
            {
                using (var connection = CreateDbConnection())
                {
                    await connection.OpenAsync();

                    var eventToTags        = new Dictionary <IPersistentRepresentation, IImmutableSet <string> >();
                    var persistentMessages = ((IImmutableList <IPersistentRepresentation>)message.Payload).ToArray();
                    for (int i = 0; i < persistentMessages.Length; i++)
                    {
                        var p = persistentMessages[i];
                        if (p.Payload is Tagged)
                        {
                            var tagged            = (Tagged)p.Payload;
                            persistentMessages[i] = p = p.WithPayload(tagged.Payload);
                            if (tagged.Tags.Count != 0)
                            {
                                allTags.UnionWith(tagged.Tags);
                                eventToTags.Add(p, tagged.Tags);
                            }
                            else
                            {
                                eventToTags.Add(p, ImmutableHashSet <string> .Empty);
                            }
                        }
                        else
                        {
                            eventToTags.Add(p, ImmutableHashSet <string> .Empty);
                        }

                        if (IsTagId(p.PersistenceId))
                        {
                            throw new InvalidOperationException($"Persistence Id {p.PersistenceId} must not start with {QueryExecutor.Configuration.TagsColumnName}");
                        }

                        NotifyNewPersistenceIdAdded(p.PersistenceId);
                    }

                    var batch = new WriteJournalBatch(eventToTags);
                    using (var cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(_pendingRequestsCancellation.Token))
                        await QueryExecutor.InsertBatchAsync(connection, cancellationToken.Token, batch);
                }
            }).ToArray();

            var result = await Task <IImmutableList <Exception> >
                         .Factory
                         .ContinueWhenAll(writeTasks,
                                          tasks => tasks.Select(t => t.IsFaulted ? TryUnwrapException(t.Exception) : null).ToImmutableList());

            if (HasPersistenceIdSubscribers)
            {
                foreach (var persistenceId in persistenceIds)
                {
                    NotifyPersistenceIdChange(persistenceId);
                }
            }

            if (HasTagSubscribers && allTags.Count != 0)
            {
                foreach (var tag in allTags)
                {
                    NotifyTagChange(tag);
                }
            }

            return(result);
        }
Ejemplo n.º 4
0
        public virtual async Task InsertBatchAsync(DbConnection connection, CancellationToken cancellationToken, WriteJournalBatch write)
        {
            using (var command = GetCommand(connection, InsertEventSql))
            using (var tx = connection.BeginTransaction())
            {
                command.Transaction = tx;

                foreach (var entry in write.EntryTags)
                {
                    var evt = entry.Key;
                    var tags = entry.Value;

                    WriteEvent(command, evt, tags);
                    await command.ExecuteScalarAsync(cancellationToken);
                    command.Parameters.Clear();
                }

                tx.Commit();
            }
        }