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

Fix #341: Optimization: Callbacks invocation #1595

Merged
merged 80 commits into from
Sep 19, 2024
Merged

Conversation

jnpsk
Copy link
Collaborator

@jnpsk jnpsk commented Jul 15, 2024

Fix #341 by implementing the Outbox Pattern.

Instead of dealing with callback sending in the business logic, an CallbackUrlEvent is created and published for an event listener. The listener, implemented in CallbackUrlEventDispatcher.class, then processes the CallbackUrlEvent in a separate thread and transaction.

Copy link
Member

@banterCZ banterCZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job. Please update also the documentation. I have added several comments to consider.

Copy link
Member

@romanstrobl romanstrobl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job. I have several concerns, especially related to performance and data migration which should be handled or answered.

Copy link
Member

@banterCZ banterCZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, almost done. Let's polish it a little bit.

banterCZ
banterCZ previously approved these changes Jul 19, 2024
Copy link
Member

@banterCZ banterCZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. @korbelm @zcgandcomp May we do performance testing from this branch before merging?

zcgandcomp
zcgandcomp previously approved these changes Jul 19, 2024
Copy link
Member

@zcgandcomp zcgandcomp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks OK

@jnpsk jnpsk dismissed stale reviews from zcgandcomp and banterCZ via c4e6504 July 23, 2024 12:08
romanstrobl
romanstrobl previously approved these changes Jul 23, 2024
Copy link
Member

@romanstrobl romanstrobl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest we run load tests on this branch before merging. Otherwise I approve the changes.

@jnpsk jnpsk force-pushed the issues/341-callback-outbox branch 2 times, most recently from 5c6cdce to 7fa9064 Compare July 29, 2024 13:06
@jnpsk
Copy link
Collaborator Author

jnpsk commented Aug 2, 2024

Coming with a significant changes due to inability to use the used locking mechanism on MSSQL.

Now the approach works as follows:

  • States of a callback event are:
    • INSTANT -> {PENDING (on full Executor’s queue), PROCESSING (when dispatched), COMPLETED (on Callback’s maxAttempts <= 0)}
    • PENDING -> {PROCESSING (when dispatched), COMPLETED (on Callback’s maxAttempts <= 0)}
    • PROCESSING -> {FAILED, COMPLETED}
    • FAILED -> {PROCESSING (on retry)}
    • COMPLETED -> {}

On an activation or operation change a new CallbackUrlEventEntity (callback event) is created and initialised to state INSTANT during
the main business transaction TrB. Only after successful commit of the TrB, the callback event is enqueued to be dispatched by via a ThreadPoolExecutor. If the ThreadPoolExecutor is busy, it rejects to dispatch the callback event and so the callback event will be transitioned to the state PENDING in database. And so, after the queueing, the callback event is either stored in database in state PENDING, or is stored in database in state INSTANT and is, at the same time submitted, to ThreadPoolExecutor.

  • ThreadPoolExecutor and its queue is thread safe and so the callback event is processed once. There is no other consumer for INSTANT events.
  • PENDING events are processed by a scheduled job with distributed locks, and so only one job processes PENDING events in the same time. Similarly for FAILED events.

banterCZ
banterCZ previously approved these changes Aug 5, 2024
Copy link
Member

@banterCZ banterCZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, looks good. I have added several ideas to consider. Did it pass the performance tests? Let's wait for other reviews.

docs/sql/mssql/migration_1.7.0_1.8.0.sql Outdated Show resolved Hide resolved
docs/sql/oracle/migration_1.7.0_1.8.0.sql Outdated Show resolved Hide resolved
docs/sql/postgresql/migration_1.7.0_1.8.0.sql Outdated Show resolved Hide resolved
* @param error Exception describing the cause of failure.
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void handleFailure(final CallbackUrlEvent callbackUrlEvent, final Throwable error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I see Throwable, I am curious whether we are supposed to handle even Error. I suggest to avoid that.

*/
private RestClient getRestClient(final CallbackUrlEventConfiguration callbackUrlEventConfiguration) throws RestClientException {
final String cacheKey = getRestClientCacheKey(callbackUrlEventConfiguration);
synchronized (restClientCacheLock) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's run the Coverity scan after merging this. Last time, we overlooked something.

romanstrobl
romanstrobl previously approved these changes Aug 5, 2024
Copy link
Member

@romanstrobl romanstrobl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found several minor additional issues.

@jnpsk jnpsk dismissed stale reviews from romanstrobl and banterCZ via 29a131d August 22, 2024 12:37
@jnpsk jnpsk merged commit f2f3484 into develop Sep 19, 2024
2 checks passed
@jnpsk jnpsk deleted the issues/341-callback-outbox branch September 19, 2024 06:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants