-
Notifications
You must be signed in to change notification settings - Fork 19
feat: ability to provide custom dispatch implementations #287
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
Open
stevensJourney
wants to merge
3
commits into
main
Choose a base branch
from
dispatching
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
common/src/commonMain/kotlin/com/powersync/DispatchStrategy.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| package com.powersync | ||
|
|
||
| import kotlinx.coroutines.CoroutineDispatcher | ||
| import kotlinx.coroutines.Dispatchers | ||
| import kotlinx.coroutines.IO | ||
| import kotlinx.coroutines.withContext | ||
|
|
||
| /** | ||
| * Function interface for dispatching database operations to a specific coroutine context. | ||
| * | ||
| * By default, operations are dispatched to [Dispatchers.IO]. Custom implementations | ||
| * can be provided to control the execution context of database operations. | ||
| * | ||
| * This interface supports the `operator invoke` syntax, allowing you to call it like: | ||
| * ``` | ||
| * dispatchFunction { /* your code */ } | ||
| * ``` | ||
| * | ||
| * **Design Note:** This must be an interface (not a function type) because Kotlin does not | ||
| * support function types with generic type parameters. Since the dispatch function needs to | ||
| * accept and return generic types `<R>`, an interface with an `operator invoke` method is | ||
| * the appropriate solution. This allows the same convenient syntax as function types while | ||
| * supporting generics. | ||
| * | ||
| * @see DispatchStrategy for dispatch strategy options | ||
| */ | ||
| public interface DispatchFunction { | ||
| /** | ||
| * Dispatches the given block to the appropriate coroutine context. | ||
| * | ||
| * @param block The suspend function to execute in the dispatch context. | ||
| * @return The result of executing the block. | ||
| */ | ||
| public suspend operator fun <R> invoke(block: suspend () -> R): R | ||
| } | ||
|
|
||
| /** | ||
| * Strategy for dispatching database operations to a specific coroutine context. | ||
| * | ||
| * This sealed class allows you to specify how database operations should be dispatched: | ||
| * - [Default]: Use the default dispatcher ([Dispatchers.IO]) | ||
| * - [Dispatcher]: Use a specific [CoroutineDispatcher] | ||
| * - [Custom]: Use a custom [DispatchFunction] for full control | ||
| * | ||
| * Each variant provides a [dispatchFunction] that implements the actual dispatching logic. | ||
| * | ||
| * Example usage: | ||
| * ``` | ||
| * // Use default (Dispatchers.IO) - this is the default if not specified | ||
| * PowerSyncDatabase(factory, schema) | ||
| * // or explicitly: | ||
| * PowerSyncDatabase(factory, schema, dispatchStrategy = DispatchStrategy.Default) | ||
| * | ||
| * // Use a specific dispatcher | ||
| * PowerSyncDatabase(factory, schema, dispatchStrategy = DispatchStrategy.Dispatcher(Dispatchers.Default)) | ||
| * | ||
| * // Use a custom function | ||
| * PowerSyncDatabase(factory, schema, dispatchStrategy = DispatchStrategy.Custom(myCustomFunction)) | ||
| * ``` | ||
| * | ||
| * @see DispatchFunction for the dispatch function interface | ||
| */ | ||
| public sealed class DispatchStrategy { | ||
| /** | ||
| * Returns the [DispatchFunction] that implements the dispatching logic for this strategy. | ||
| */ | ||
| public abstract val dispatchFunction: DispatchFunction | ||
|
|
||
| /** | ||
| * Use the default dispatcher ([Dispatchers.IO]) for database operations. | ||
| * | ||
| * This is the recommended default for most use cases, as it provides | ||
| * a dedicated thread pool for I/O-bound operations. | ||
| */ | ||
| public object Default : DispatchStrategy() { | ||
| override val dispatchFunction: DispatchFunction = | ||
| Dispatcher(Dispatchers.IO).dispatchFunction | ||
| } | ||
|
|
||
| /** | ||
| * Use a specific [CoroutineDispatcher] for database operations. | ||
| * | ||
| * This allows you to use any coroutine dispatcher, such as: | ||
| * - [Dispatchers.Default] for CPU-bound work | ||
| * - [Dispatchers.Main] for UI operations | ||
| * - A custom dispatcher for your specific needs | ||
| * | ||
| * @property dispatcher The coroutine dispatcher to use. | ||
| */ | ||
| public data class Dispatcher( | ||
| val dispatcher: CoroutineDispatcher, | ||
| ) : DispatchStrategy() { | ||
| override val dispatchFunction: DispatchFunction = | ||
| object : DispatchFunction { | ||
| override suspend fun <R> invoke(block: suspend () -> R): R = withContext(dispatcher) { block() } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Use a custom [DispatchFunction] for full control over dispatching. | ||
| * | ||
| * @property function The custom dispatch function to use. | ||
| */ | ||
| public data class Custom( | ||
| val function: DispatchFunction, | ||
| ) : DispatchStrategy() { | ||
| override val dispatchFunction: DispatchFunction = function | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we used
CoroutineContexthere, this could e.g. be anEmptyCoroutineContext.