Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce point of integration for non-SQL (no IDbConnection) storage #8

Open
m-wilczynski opened this issue Aug 5, 2020 · 0 comments
Labels
area.outbox Resonance.Outbox library breaking change enhancement New feature or request

Comments

@m-wilczynski
Copy link
Owner

Problem

Currently both Inbound and Outbound implementation assumes there is:

  • IDbConnection
  • either explicit IDbTransaction or ambient TransactionScope

With such constraints there is no way to introduce other backing storage with NoSQL databases such as MongoDB, Neo4j, Redis etc..

Possible solution

Assuming we want to keep the flow of current Resonance.Outbox API, there should still be a way to:

using (var anyConnection = OpenConnection())
{
    using (var anyTransaction = BeginTransaction())
    {
        anyConnection.DoUserCode();
        outobox.Send(myEvent);
        anyTransaction.Commit();
    }
}

There should be:

  • generic type param for transaction, ie. ITransactionalOutbox<TTransaction> where TTransaction would be any implementation of database transaction, such as:
    • IDbTransaction for SQL Databases
    • AsyncTransaction for Neo4j
    • IClientSession for MongoDb
    • ITransaction for Redis
    • etc.
  • common contract to start connection and transaction and to commit/rollback transaction in IMessageRepository

Such change would change current implementation of these APIs:

ITransactionalOutbox:

public interface ITransactionalOutbox<TTransactionSource>
{
    Task Send<TMessage>(TMessage message, TTransactionSource transaction = null, DateTime? sendTime = null);
}

TransactionalOutbox:

public class SqlTransactionalOutbox : ITransactionalOutbox<IDbTransaction>

IMessageRepository:

public interface IMessageRepository<TTransactionSource>
{
    Task SaveMessage(SerializedMessage serializedMessage, TTransactionSource transaction = null);
    Task<ICollection<SerializedMessage>> GetMessagesAsMarkedSent(TTransactionSource transaction, uint? howManyMessages = null);
    Task<ICollection<SerializedMessage>> GetMessagesAsRemoved(TTransactionSource transaction, uint? howManyMessages = null);
}

SqlServerMessageRepository:

public class SqlServerMessageRepository : IMessageRepository<IDbTransaction>
{
    //(...)
}

and would also introduce extension of contract for IMessageRepository for managing transaction for Outbound part:

public interface IReadMessageRepository<TTransactionSource> : IMessageRepository<TTransactionSource>
{
    Task<TTransactionSource> BeginTransaction();
    Task CommitTransaction();
    Task RollbackTransaction();
}

Definition of done

  1. Implementation of example NoSQL integration; example: MongoDB, Neo4j.
  2. Previous SQL solution still works.

Points of further improvement

Perhaps there also should be a way to introduce transaction options as second generic type param, ie:

public interface IReadMessageRepository<TTransactionSource, TTransactionOptions> : IMessageRepository<TTransactionSource>
{
    Task<TTransactionSource> BeginTransaction(TTransactionOptions transactionOptions);
    //(...)
}
@m-wilczynski m-wilczynski added enhancement New feature or request area.outbox Resonance.Outbox library breaking change labels Aug 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area.outbox Resonance.Outbox library breaking change enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant