-
-
Notifications
You must be signed in to change notification settings - Fork 21
keep projections running #476
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
keep projections running #476
Conversation
14197db to
eae0245
Compare
|
I just ran into an idea to pass 'keepRunning' as a running option with false for default. Let me know your opinion. |
|
If the projection is synchronous, then after a successful projection run triggered by the event stream, its status should always transition to idle. For polling projections, the status should also be idle when there are no new events to process. In the case of projections handled asynchronously via a message queue (i.e., through asynchronous event handlers), it may be necessary to define an activity timeout — for example, if no relevant events are received within a given period (X), the projection status should also become idle. Additionally, it’s important to consider that a projection may be subscribed to a stream, but the incoming events might not modify the projection state — for instance, when the projection listens to multiple aggregates and the received events are unrelated. |
|
@lifinsky so asynchronous projections could be safely run with Although the problem is actually in the way Prooph runs projections and shows up when you reset or start new projection with existing stream with lower Ecotone runs projection with
I managed to prepare a PR in Prooph prooph/pdo-event-store#257 so the only change required may be to increase minimum version of |
If a gap occurs in a synchronous projection and it cannot be resolved within the retry window, the projection will lag behind the stream — in this case, the status should not be idle. |
|
@lifinsky I agree and that is the reason I've opened the PR in Prooph repo |
eae0245 to
259a736
Compare
|
@dgafka prooph projections will now run until the end of stream |
|
@unixslayer Hi. If the number of retries during gap detection has been exhausted, we should not wait for the end of the stream, and the projection status should remain running. |
|
@lifinsky projection will always try to reach the end of the stream. I'll check that tomorrow but you're right, GapDetection should stop projection with status Anyway, this is another issue to be addressed in Prooph. |
Thanks. This is critical for synchronous projection execution, especially within transactional blocks or during the processing of an HTTP request (when execution time is limited, it's especially important). On the other hand, it’s possible to periodically check synchronous projections stuck in the running status and trigger their update if no new events are present — similar to how pooling projections work. |
Can you elaborate more? |
|
@lifinsky
I'd suggest, if you are expecting gaps and projection is not running only once (like one-time reports), to configure |
@unixslayer I’m primarily concerned about ensuring that our synchronization waiting time does not exceed acceptable timeouts. If, despite retries, synchronous projections still periodically enter the running status (gap is not resolved by retries), it’s a clear indication that they should be transitioned to asynchronous execution. |
|
@lifinsky Some time ago my client insisted that all projections should be synchronous due users wants to see the results of their actions immediately. And we've faced that problem, when having multiple users accessing the same model, delays were causing timeouts due to GapDetection. IMO any projection, any read model should be considered eventually consistent by default. Therefore it is safer to make them asynchronous. |
|
@unixslayer Correct, if we do not have time to synchronize with the current GapDetection settings, then the projection should have the running status and lag behind, but not lead to a timeout or transaction rollbacks |
|
@lifinsky the case with projection status is that Projection won't be able to determine why gap occurred. You can read the comments in |
|
I’ve reviewed the Prooph code more carefully — and it’s actually much worse. Events will continue to play forward, and once the retry limit is exhausted, the event will effectively be skipped, causing the projection status to switch to idle. This is likely one of the key reasons why Prooph is unsuitable for both synchronous projections and event-sourced projections with more than one consumer in high-load systems. |
|
But I agree that there can be rollback scenarios where it clearly makes sense to define a maximum wait time, which is generally addressed by the gap detection period. Unfortunately, though, this doesn't solve the issue of intensive parallel inserts. In my opinion, falling behind is preferable to skipping events. However, if falling behind is acceptable, then it might actually be better to switch to a pooling projection implemented as a single worker per projection. I’d be really interested to hear your production experience on this. |
|
@lifinsky this is our default projection running configuration ProjectionRunningConfiguration::createEventDriven($projection)
->withOption(
PdoEventStoreReadModelProjector::OPTION_GAP_DETECTION,
new GapDetection(
retryConfig: [0, 5000, 5000, 5000, 5000, 5000, 5000, 30000, 30000, 30000],
detectionWindow: new GapDetection\DateInterval('PT2M'),
)
)with following assumptions:
I don't remember how many issues we've had reported from users in last 3 years regarding anything related to projections but I'm sure I could count them using single hand. The only issue we have, and this is 100% on our side, is that resetting projection can take more time than we'd like it to take but this has no impact on client. Projections are eventually consisted by design therefore, anything that results from them cannot be considered as business invariant. We are using them only for listings, reports, notifications, etc. However, just because above works for me it doesn't have to work for you. I don't know what kind of actual problems you're facing and how your architecture looks like. And what is the most important, how you model your domain. |
Why is this change proposed?
due Prooph may change database projections status to
idleafter first cycle when triggered withkeepRunning: false, non-polling asynchronous database projections should be triggered withkeepRunning: trueDescription of Changes
Issue occurs when resetting asynchronous projection. With
keepRunning: falseProoph will run it once for amount of events defined withload_countoption and change its status toidle. Ecotone checks projection status after first run and runs it again while status remains either asrebuildingorrunning.I made following assumptions:
Pull Request Contribution Terms