-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Projection and offset store structure (#10)
* starting with atLeastOnceAsync * no real DynamoDB implementation in offset store yet
- Loading branch information
Showing
10 changed files
with
1,447 additions
and
3 deletions.
There are no files selected for viewing
This file contains 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 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 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 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,38 @@ | ||
# This defines the default configuration for akka-projection-dynamodb. | ||
# Make your edits/overrides in your application.conf. | ||
|
||
//#projection-config | ||
akka.projection.dynamodb { | ||
|
||
offset-store { | ||
# the DynamoDB table name for the offset store | ||
timestamp-offset-table = "timestamp_offset" | ||
|
||
# The offset store will keep track of persistence ids and sequence numbers | ||
# within this time window from latest offset. | ||
time-window = 5 minutes | ||
|
||
# Keep this number of entries. Don't evict old entries until this threshold | ||
# has been reached. | ||
keep-number-of-entries = 10000 | ||
|
||
# Remove old entries outside the time-window from the offset store memory | ||
# with this frequency. | ||
evict-interval = 10 seconds | ||
|
||
# Trying to batch insert offsets in batches of this size. | ||
offset-batch-size = 20 | ||
} | ||
|
||
# By default it shares DynamoDB client with akka-persistence-dynamodb (write side). | ||
# To use a separate client for projections this can be | ||
# set to another config path that defines the config based on | ||
# akka.persistence.dynamodb.client config. | ||
use-client = "akka.persistence.dynamodb.client" | ||
|
||
# Filtered events are not actually filtered but passed through the handling flow | ||
# for atLeastOnceFlow, in some applications this is fine, set to false to disable | ||
# the info logged when seeing such filtered events | ||
warn-about-filtered-events-in-flow = true | ||
} | ||
//#projection-config |
108 changes: 108 additions & 0 deletions
108
projection/src/main/scala/akka/projection/dynamodb/DynamoDBProjectionSettings.scala
This file contains 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,108 @@ | ||
/* | ||
* Copyright (C) 2024 Lightbend Inc. <https://www.lightbend.com> | ||
*/ | ||
|
||
package akka.projection.dynamodb | ||
|
||
import java.time.{ Duration => JDuration } | ||
|
||
import scala.concurrent.duration._ | ||
|
||
import akka.actor.typed.ActorSystem | ||
import akka.util.JavaDurationConverters._ | ||
import com.typesafe.config.Config | ||
|
||
object DynamoDBProjectionSettings { | ||
|
||
val DefaultConfigPath = "akka.projection.dynamodb" | ||
|
||
/** | ||
* Scala API: Load configuration from `akka.projection.dynamodb`. | ||
*/ | ||
def apply(system: ActorSystem[_]): DynamoDBProjectionSettings = | ||
apply(system.settings.config.getConfig(DefaultConfigPath)) | ||
|
||
/** | ||
* Java API: Load configuration from `akka.projection.dynamodb`. | ||
*/ | ||
def create(system: ActorSystem[_]): DynamoDBProjectionSettings = | ||
apply(system) | ||
|
||
/** | ||
* Scala API: From custom configuration corresponding to `akka.projection.dynamodb`. | ||
*/ | ||
def apply(config: Config): DynamoDBProjectionSettings = { | ||
new DynamoDBProjectionSettings( | ||
timestampOffsetTable = config.getString("offset-store.timestamp-offset-table"), | ||
useClient = config.getString("use-connection-factory"), | ||
timeWindow = config.getDuration("offset-store.time-window"), | ||
keepNumberOfEntries = config.getInt("offset-store.keep-number-of-entries"), | ||
evictInterval = config.getDuration("offset-store.evict-interval"), | ||
warnAboutFilteredEventsInFlow = config.getBoolean("warn-about-filtered-events-in-flow"), | ||
offsetBatchSize = config.getInt("offset-store.offset-batch-size")) | ||
} | ||
|
||
/** | ||
* Java API: From custom configuration corresponding to `akka.projection.dynamodb`. | ||
*/ | ||
def create(config: Config): DynamoDBProjectionSettings = | ||
apply(config) | ||
|
||
} | ||
|
||
final class DynamoDBProjectionSettings private ( | ||
val timestampOffsetTable: String, | ||
val useClient: String, | ||
val timeWindow: JDuration, | ||
val keepNumberOfEntries: Int, | ||
val evictInterval: JDuration, | ||
val warnAboutFilteredEventsInFlow: Boolean, | ||
val offsetBatchSize: Int) { | ||
|
||
def withTimestampOffsetTable(timestampOffsetTable: String): DynamoDBProjectionSettings = | ||
copy(timestampOffsetTable = timestampOffsetTable) | ||
|
||
def withUseClient(clientConfigPath: String): DynamoDBProjectionSettings = | ||
copy(useClient = clientConfigPath) | ||
|
||
def withTimeWindow(timeWindow: FiniteDuration): DynamoDBProjectionSettings = | ||
copy(timeWindow = timeWindow.asJava) | ||
|
||
def withTimeWindow(timeWindow: JDuration): DynamoDBProjectionSettings = | ||
copy(timeWindow = timeWindow) | ||
|
||
def withKeepNumberOfEntries(keepNumberOfEntries: Int): DynamoDBProjectionSettings = | ||
copy(keepNumberOfEntries = keepNumberOfEntries) | ||
|
||
def withEvictInterval(evictInterval: FiniteDuration): DynamoDBProjectionSettings = | ||
copy(evictInterval = evictInterval.asJava) | ||
|
||
def withEvictInterval(evictInterval: JDuration): DynamoDBProjectionSettings = | ||
copy(evictInterval = evictInterval) | ||
|
||
def withWarnAboutFilteredEventsInFlow(warnAboutFilteredEventsInFlow: Boolean): DynamoDBProjectionSettings = | ||
copy(warnAboutFilteredEventsInFlow = warnAboutFilteredEventsInFlow) | ||
|
||
def withOffsetBatchSize(offsetBatchSize: Int): DynamoDBProjectionSettings = | ||
copy(offsetBatchSize = offsetBatchSize) | ||
|
||
private def copy( | ||
timestampOffsetTable: String = timestampOffsetTable, | ||
useClient: String = useClient, | ||
timeWindow: JDuration = timeWindow, | ||
keepNumberOfEntries: Int = keepNumberOfEntries, | ||
evictInterval: JDuration = evictInterval, | ||
warnAboutFilteredEventsInFlow: Boolean = warnAboutFilteredEventsInFlow, | ||
offsetBatchSize: Int = offsetBatchSize) = | ||
new DynamoDBProjectionSettings( | ||
timestampOffsetTable, | ||
useClient, | ||
timeWindow, | ||
keepNumberOfEntries, | ||
evictInterval, | ||
warnAboutFilteredEventsInFlow, | ||
offsetBatchSize) | ||
|
||
override def toString = | ||
s"DynamoDBProjectionSettings($timestampOffsetTable, $useClient, $timeWindow, $keepNumberOfEntries, $evictInterval, $warnAboutFilteredEventsInFlow, $offsetBatchSize)" | ||
} |
Oops, something went wrong.