You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/building-a-provider/polling.md
+14-1Lines changed: 14 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,7 @@ outline: deep
7
7
To implement a polling provider, there are three main things you need to do:
8
8
9
9
- implement the `IBatchFetcher` and `IBatchContext` interfaces
10
+
- implement the `IBatchCompleteRetrier` interface, so that OutboxKit can retry completing already produced messages in case of failures
10
11
- implement the `IOutboxCleaner` interface (assuming you want to support the update processed messages feature)
11
12
- implement OutboxKit setup, which includes collecting any configuration you require, and calling core's `WithPolling` method
12
13
@@ -26,6 +27,18 @@ Additionally, `IBatchContext` implements the `IAsyncDisposable` interface, which
26
27
27
28
In terms of lifetime, `IBatchFetcher` is created once per outbox, so should be registered in the DI container as a keyed singleton (more on the keyed part later). `IBatchContext` isn't fetched from the DI container, so it's up to you how you manage the lifetime. Normally, a new instance of `IBatchContext` would be created each time `FetchAndHoldAsync` is called, but if you have some good reasons, you could have a pool of `IBatchContext` instances, or even reuse the same instance. Just make sure there's no issues with reusing it across different fetches and outboxes.
28
29
30
+
## Implementing `IBatchCompleteRetrier`
31
+
32
+
`IBatchCompleteRetrier` is an interface that allows OutboxKit to retry completing messages that were produced successfully, in case of failures when completing them. The goal is to minimize the amount of duplicate messages produced.
33
+
34
+
This interface has a single method, `RetryAsync`, which takes the messages that were produced but have potentially failed to complete (no way to be sure, as an exception could occur immediately after the completion was persisted to the database). The implementation is likely similar to `IBatchContext.CompleteAsync`, though a bit of extra care has to be taken, to account for the fact that since the failure happened, the messages might have been completed by another running process.
35
+
36
+
You don't need to implement any retry logic, just let exceptions bubble up or throw your own to signal completion fail. The core library will handle the exception and keep calling `RetryAsync` until it returns successfully.
37
+
38
+
Note that OutboxKit keeps the potentially failed to complete messages in memory, so this is a best effort approach to minimize duplicates. This means that if either the process restarts or another instance of the process is running, the messages will be produced again.
39
+
40
+
In terms of lifetime, `IBatchCompleteRetrier`, like `IBatchFetcher`, is created once per outbox, so should be registered in the DI container as a keyed singleton.
41
+
29
42
## Implementing `IOutboxCleaner`
30
43
31
44
`IOutboxCleaner` is a rather simple interface, with a single method, `CleanAsync`, which returns the amount of messages that were cleaned, with no arguments (other than the typical `CancellationToken`).
@@ -40,6 +53,6 @@ To provide a simple way for library users to configure OutboxKit, your setup cod
40
53
41
54
After you collect all the required configuration, calling `WithPolling` should include the aforementioned key, and something that implements `IPollingOutboxKitConfigurator`. This interface exposes a couple of methods: `ConfigureServices` and `GetCoreSettings`.
42
55
43
-
`ConfigureServices` is invoked when the core library is setting up services, and it's where you should register your `IBatchFetcher` and `IOutboxCleaner` implementations, plus any other services you require. You get the `OutboxKey` as an argument, and you should use that at least when registering `IBatchFetcher` and `IOutboxCleaner` (you could use it for any other services you require, of course).
56
+
`ConfigureServices` is invoked when the core library is setting up services, and it's where you should register your `IBatchFetcher` and `IOutboxCleaner` implementations, plus any other services you require. You get the `OutboxKey` as an argument, and you should use that at least when registering `IBatchFetcher`, `IBatchCompleteRetrier` and `IOutboxCleaner` (you could use it for any other services you require, of course).
44
57
45
58
`GetCoreSettings` is invoked when the core library is setting stuff up, and requires the configuration you collected.
"Starting outbox polling background service for provider key \"{providerKey}\" and client key \"{clientKey}\", with polling interval {pollingInterval}")]
0 commit comments