-
-
Notifications
You must be signed in to change notification settings - Fork 454
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
Overhaul Command Execution Pipeline #2887
Comments
Goals
Changing Session Execution MechanicsThe execution of commands today is done with a combination of IConnectionLifetime that does very low level ADO.Net manipulations w/ a couple different flavors for Marten -owned transactions and ambient transactions among other options. Proposal:Replace the existing // Think of a better name maybe, but I'm proposing this for the
// next version
public interface ISessionExecutor
{
// These methods are on IQuerySession today. Not sure, but might be best to have these
// here.
// Wrap *ALL* transactional boundary stuff here. So it manages all transactional
// boundaries
Task ExecutePagesAsync(IReadOnlyList<OperationPage> pages, IMartenSessionLogger logger, CancellationToken token);
// And also overloads of these 4 for NpgsqlDbBatch
int Execute(NpgsqlCommand cmd);
Task<int> ExecuteAsync(NpgsqlCommand command, CancellationToken token = new());
DbDataReader ExecuteReader(NpgsqlCommand command);
Task<DbDataReader> ExecuteReaderAsync(NpgsqlCommand command, CancellationToken token = default);
} The big difference is that the implementations of this new As part of that change, the current methods in As for
Error HandlingThis interface has to go, no graceful public interface IRetryPolicy
{
void Execute(Action operation);
TResult Execute<TResult>(Func<TResult> operation);
Task ExecuteAsync(Func<Task> operation, CancellationToken cancellationToken);
Task<TResult> ExecuteAsync<TResult>(Func<Task<TResult>> operation, CancellationToken cancellationToken);
} We'll have to benchmark it to know for sure, but I'd guess that this is a relatively high drag on our performance because of
I was leery of using Polly before because it's a common diamond dependency problem because of its ubiquity. Honestly, I'd rather just bake it in and make sure it has a default exponential backoff policy for common transient issues. Makes our documentation effort much simpler. Necessary Spikes
|
Naive idea: always use tenant id, but if conjoined tenancy is disabled use the
I use the If outside of a session, then I just use the NpgsqlDataSource (from which I get the connection in Marten 6.x).
I'd use that only for event related operations, not for everything by default. IIRC too much preparation can hurt too, but here I might be wrong. |
@gfoidl The I agree with you about |
@jeremydmiller, dumb idea, what if we add tenant id to all tables? Is the issue with tenant id, that we need to have always conditional code to add it or not? Regarding the scope of changes, I'm definitely fine with replacing the homebrewed IRetryPolicy with Polly, especially after recent improvements and using it internally by MS. Regarding the other changes, I'm unsure as I'd need to understand the proposal in more detail. What I can tell is that creating a new connection is costly. Not sharing it can lead to performance degradation. Other thing to add is that we should be really careful in default retry policy about that. I saw a few times when wrong settings caused ripple effect when the database was down (even not allowing it to get up because of flooding it with the open connections). Definitely we should be more explicit to our users about Pooling and test how it behaves both for Npgsql pool and PgBouncer. I'd be happy to get rid of the CommandBuilder static methods in Weasel. Using static PostgreSQLProvider will bite us hard in the long term, so if this could help in that, I'd be more than happy. So I'm not against the proposal, I'd need to see more details. We'd need to spend time benchmarking it. I think that it'd be good to take some inspiration from EF on how they're dealing with it. I expect that they have that optimised. Also the other thing to consider (potentially out of scope) is to distinguish querying from update operations. I mean by that, that if we know that operations are read-only then it'd be great to be able to use read replicas or optimisation on the connection level. That can have significant performance improvements. Maybe we should also include that in the API? I'm also up to using prepared statements, they can increase performance. We'd need to have a good roundtrip of tests, as if they're wrongly cached it can create random issues. |
@oskardudycz, thanks for the review and the comments!
"Also the other thing to consider (potentially out of scope) is to distinguish querying from update operations. I mean by that, that if we know that operations are read-only then it'd be great to be able to use read replicas or optimisation on the connection level. That can have significant performance improvements. Maybe we should also include that in the API?" -- I'd just have to learn a bit more about what that would mean. Sounds good on the face of things |
Tasks on Just Batching / Positional Parameters (Jan. 8th)
|
Punchlist
|
See this draft PR: #2918 Hasn't been rebased on master yet. Punchlist up above yet to go. |
There are separate issues now for the docs and last couple tasks. Closing for now. |
I'm subsuming a couple older issues here about retry policies (#2265), Hot Chocolate integration (#2738), and more advanced Npgsql usage #2787.
The text was updated successfully, but these errors were encountered: