Skip to content

Commit d431099

Browse files
authored
Merge branch 'master' into ci-coverage
2 parents d5da001 + 71c1cef commit d431099

File tree

86 files changed

+7228
-969
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+7228
-969
lines changed

.github/workflows/ci.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ on:
77
branches: [ master, feature/** ]
88

99
env:
10-
SBT_OPTS: -Dlerna.enable.discipline
10+
# classic timefactor doesn't affect classic default-timeout
11+
SBT_OPTS: >-
12+
-Dlerna.enable.discipline
13+
-Dakka.test.timefactor=3.0
14+
-Dakka.actor.testkit.typed.timefactor=3.0
15+
-Dakka.test.default-timeout=15s
16+
-Dakka.testconductor.barrier-timeout=90s
1117
1218
jobs:
1319
test:
@@ -51,7 +57,7 @@ jobs:
5157

5258
- name: Run integration tests
5359
continue-on-error: true # results are reported by action-junit-report
54-
run: sh ./scripts/run-multijvm-test.sh 6
60+
run: sh ./scripts/run-multijvm-test.sh 1
5561

5662
- name: Publish test report
5763
uses: mikepenz/action-junit-report@v2

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
## [Unreleased]
88
[Unreleased]: https://github.com/lerna-stack/akka-entity-replication/compare/v2.0.0...master
99

10+
### Added
11+
- Efficient recovery of commit log store, which is on the query side [#112](https://github.com/lerna-stack/akka-entity-replication/issues/112)
12+
13+
This change will improve the performance of the recovery on the query side.
14+
You should migrate settings described at [Migration Guide](docs/migration_guide.md#210-from-200).
15+
16+
- Raft actors start automatically after an initialization of `ClusterReplication` [#118](https://github.com/lerna-stack/akka-entity-replication/issues/118)
17+
18+
This feature is enabled only by using `typed.ClusterReplication`.
19+
It is highly recommended that you switch using the typed API since the classic API was deprecated.
20+
1021
### Changed
1122
- Bump up Akka version to 2.6.17 [PR#98](https://github.com/lerna-stack/akka-entity-replication/pull/98)
1223

@@ -15,6 +26,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1526

1627
### Fixed
1728
- TestKit throws "Shard received unexpected message" exception after the entity passivated [PR#100](https://github.com/lerna-stack/akka-entity-replication/pull/100)
29+
- `ReplicatedEntity` can produce illegal snapshot if compaction and receiving new event occur same time [#111](https://github.com/lerna-stack/akka-entity-replication/issues/111)
30+
- Starting a follower member later than leader completes a compaction may break ReplicatedLog of the follower [#105](https://github.com/lerna-stack/akka-entity-replication/issues/105)
31+
- The Raft leader uses the same previous `LogEntryIndex` and `Term` to all batched `AppendEntries` messages [#123](https://github.com/lerna-stack/akka-entity-replication/issues/123)
32+
- Raft Actors doesn't accept a `RequestVote(lastLogIndex < log.lastLogIndex, lastLogTerm > log.lastLogTerm)` message [#125](https://github.com/lerna-stack/akka-entity-replication/issues/125)
33+
- A new event is created even though all past events have not been applied [#130](https://github.com/lerna-stack/akka-entity-replication/issues/130)
34+
- `InstallSnapshot` can miss snapshots to copy [PR#128](https://github.com/lerna-stack/akka-entity-replication/pull/128)
35+
36+
⚠️ This change adds a new persistence event. This might don't allow downgrading after upgrading.
1837

1938
## [v2.0.0] - 2021-07-16
2039
[v2.0.0]: https://github.com/lerna-stack/akka-entity-replication/compare/v1.0.0...v2.0.0

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ For more information on how to implement an application using this library, plea
6060
- [Implementation Guide](docs/typed/implementation_guide.md)
6161
- [Testing Guide](docs/typed/testing_guide.md)
6262

63+
**NOTE**: It is highly recommended that you carefully do cluster operations.
64+
For more details, please refer to [Operation Guide](docs/operation_guide.md).
65+
6366
## For Contributors
6467

6568
[CONTRIBUTING](CONTRIBUTING.md) may help us.
@@ -74,6 +77,10 @@ You can see a sample application using this extension in the following project.
7477

7578
You can see all the notable changes in [CHANGELOG](CHANGELOG.md).
7679

80+
## Migration Guide
81+
82+
[Migration Guide](docs/migration_guide.md) describes how to migrate code and settings from previous versions.
83+
7784
## License
7885

7986
akka-entity-replication is released under the terms of the [Apache License Version 2.0](./LICENSE).

build.sbt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ lazy val lerna = (project in file("."))
3232
name := "akka-entity-replication",
3333
fork in Test := true,
3434
parallelExecution in Test := false,
35+
javaOptions in Test ++= sbtJavaOptions,
36+
jvmOptions in MultiJvm ++= sbtJavaOptions,
3537
libraryDependencies ++= Seq(
3638
"com.typesafe.akka" %% "akka-cluster-typed" % akkaVersion,
3739
"com.typesafe.akka" %% "akka-stream" % akkaVersion,
@@ -51,7 +53,9 @@ lazy val lerna = (project in file("."))
5153
"com.typesafe.akka" %% "akka-multi-node-testkit" % akkaVersion % Test,
5254
// akka-persistence-inmemory が 2.6.x 系に対応していない。
5355
// TODO 2.6.x 系に対応できる方法に変更する。
54-
"com.github.dnvriend" %% "akka-persistence-inmemory" % "2.5.15.2" % Test,
56+
"com.github.dnvriend" %% "akka-persistence-inmemory" % "2.5.15.2" % Test,
57+
"com.typesafe.akka" %% "akka-persistence-testkit" % akkaVersion % Test,
58+
"com.typesafe.akka" %% "akka-stream-testkit" % akkaVersion % Test,
5559
),
5660
inConfig(MultiJvm)(
5761
// multi-jvm ディレクトリをフォーマットするために必要
@@ -82,6 +86,20 @@ lazy val lerna = (project in file("."))
8286
mimaReportSignatureProblems := true, // check also generic parameters
8387
)
8488

89+
/**
90+
* This is used to pass specific system properties (mostly from CI environment variables)
91+
* to the forked process by sbt
92+
*/
93+
val sbtJavaOptions: Seq[String] = {
94+
// selects properties starting with the following
95+
val includes = Set(
96+
"akka.",
97+
)
98+
sys.props.collect {
99+
case (k, v) if includes.exists(k.startsWith) => s"-D$k=$v"
100+
}.toSeq
101+
}
102+
85103
addCommandAlias(
86104
"testCoverage",
87105
Seq(

docs/implementation_guide.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,13 @@ lerna.akka.entityreplication.raft.eventsourced {
375375
// Absolute path to the journal plugin configuration entry.
376376
// The journal stores Raft-committed events.
377377
journal.plugin = ""
378+
379+
// Absolute path to the snapshot-store plugin configuration entry.
380+
// The snapshot-store stores a state (snapshot) built from Raft-committed events.
381+
snapshot-store.plugin = ""
382+
383+
// Snapshot after this number of events.
384+
snapshot-every = 1000
378385
}
379386
}
380387
```
@@ -393,6 +400,7 @@ lerna.akka.entityreplication.raft.persistence {
393400
// Query side persistence plugin settings
394401
lerna.akka.entityreplication.raft.eventsourced.persistence {
395402
journal.plugin = ""
403+
snapshot-store.plugin = ""
396404
}
397405
```
398406

docs/migration_guide.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Migration Guide
2+
3+
## 2.1.0 from 2.0.0
4+
5+
### Configure a snapshot store on the query side
6+
*akka-entity-replication 2.1.0* introduces an efficient recovery on the query side.
7+
We've achieved this efficient recovery by using a snapshot feature of Akka persistence.
8+
This efficient recovery requires you to configure a snapshot store like the following:
9+
```hocon
10+
lerna.akka.entityreplication.raft.eventsourced.persistence {
11+
snapshot-store.plugin = "Specify your snapshot store plugin ID to use"
12+
}
13+
```
14+
Note that this snapshot store is mandatory.
15+
You have to configure the snapshot store.
16+
17+
This efficient recovery also introduces new settings named `lerna.akka.entityreplication.raft.eventsourced.persistence.snapshot-every`.
18+
*akka-entity-replication 2.1.0* saves a snapshot every `snapshot-every` events.
19+
The default value of `snapshot-every` is 1000.
20+
You can override this setting according to your requirements.

docs/operation_guide.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Operation Guide
2+
3+
**Principle: Don't terminate all Raft members at the same time.**
4+
5+
To achieve this principle, you carefully do cluster operations.
6+
This document supposes that you will use three `multi-raft-roles` (`replica-group-1`, `replica-group-2`, `replica-group-3`).
7+
8+
9+
## Start a new cluster
10+
The important point is to start only one node in at least one role.
11+
12+
A possible full cluster start operation is the following:
13+
* Start a node (or multiple nodes) with role `replica-group-1`.
14+
* Start a node (or multiple nodes) with role `replica-group-2`.
15+
* Start exactly one node with `replica-group-3`.
16+
17+
You can do the above operations simultaneously.
18+
You have to wait for all Raft members to be running
19+
before adding more nodes with `replica-group-3`.
20+
The waiting time depends on your settings, such as the following:
21+
* `lerna.akka.entityreplication.raft.election-timeout`
22+
* `lerna.akka.entityreplication.raft.heartbeat-interval`
23+
* `lerna.akka.entityreplication.raft.number-of-shards`
24+
* `lerna.akka.entityreplication.raft.raft-actor-auto-start`
25+
26+
27+
## Add nodes
28+
Don't add nodes with different roles at the same time.
29+
30+
Any of the following operations is possible:
31+
* Add a node (or multiple nodes) with `replica-group-1`.
32+
* Add a node (or multiple nodes) with `replica-group-2`.
33+
* Add a node (or multiple nodes) with `replica-group-3`.
34+
35+
You **should not** do the above operations simultaneously.
36+
You have to wait for all Raft members to be running
37+
before adding more nodes or removing nodes.
38+
The waiting time depends on your settings, such as the following:
39+
* `lerna.akka.entityreplication.raft.election-timeout`
40+
* `lerna.akka.entityreplication.raft.heartbeat-interval`
41+
42+
Any of the following operations is possible but **not recommended**.
43+
It is because you cannot ensure that any of nodes with untouched roles won't crash.
44+
* Add nodes with `replica-group-1` and nodes with `replica-group-2`.
45+
* Add nodes with `replica-group-2` and nodes with `replica-group-3`.
46+
* Add nodes with `replica-group-3` and nodes with `replica-group-1`.
47+
48+
49+
## Remove nodes
50+
Don't remove nodes with different roles at the same time.
51+
52+
Any of the following operations is possible:
53+
* Remove a node (or multiple nodes) with `replica-group-1`.
54+
* Remove a node (or multiple nodes) with `replica-group-2`.
55+
* Remove a node (or multiple nodes) with `replica-group-3`.
56+
57+
You **should not** do the above operations simultaneously.
58+
You have to wait for all Raft members to be running
59+
before adding nodes or removing more nodes.
60+
Waiting time depends on your settings, such as the following:
61+
* `lerna.akka.entityreplication.raft.election-timeout`
62+
* `lerna.akka.entityreplication.raft.heartbeat-interval`
63+
64+
Any of the following operations is possible but **not recommended**.
65+
It is because you cannot ensure that any of nodes with untouched roles won't crash.
66+
* Remove nodes with `replica-group-1` and nodes with `replica-group-2`.
67+
* Remove nodes with `replica-group-2` and nodes with `replica-group-3`.
68+
* Remove nodes with `replica-group-3` and nodes with `replica-group-1`.

docs/typed/implementation_guide.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,10 @@ lerna.akka.entityreplication.raft.persistence.journal.plugin = ""
327327
lerna.akka.entityreplication.raft.persistence.snapshot-store.plugin = ""
328328
lerna.akka.entityreplication.raft.persistence.query.plugin = ""
329329
lerna.akka.entityreplication.raft.eventsourced.persistence.journal.plugin = ""
330+
lerna.akka.entityreplication.raft.eventsourced.persistence.snapshot-store.plugin = ""
330331
```
331332

332-
You can override these settings by `withRaftJournalPluginId`, `withRaftSnapshotPluginId`, `withRaftQueryPluginId` and `withEventSourcedJournalPluginId`
333+
You can override these settings by `withRaftJournalPluginId`, `withRaftSnapshotPluginId`, `withRaftQueryPluginId`, `withEventSourcedJournalPluginId`, and `withEventSourcedSnapshotStorePluginId`
333334
of `ClusterReplicationSettings`.
334335

335336
```scala
@@ -346,6 +347,7 @@ val settings =
346347
.withRaftSnapshotPluginId("my.special.raft.snapshot-store")
347348
.withRaftQueryPluginId("my.special.raft.query")
348349
.withEventSourcedJournalPluginId("my.special.eventsourced.journal")
350+
.withEventSourcedSnapshotStorePluginId("my.special.eventsourced.snapshot-store")
349351

350352
val entity =
351353
ReplicatedEntity(BankAccountBehavior.TypeKey)(entityContext => BankAccountBehavior(entityContext))
@@ -596,6 +598,7 @@ lerna.akka.entityreplication.raft.persistence {
596598
// Query side persistence plugin settings
597599
lerna.akka.entityreplication.raft.eventsourced.persistence {
598600
journal.plugin = ""
601+
snapshot-store.plugin = ""
599602
}
600603
```
601604

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# ClusterReplicationSettings should not be extended by users
2+
ProblemFilters.exclude[ReversedMissingMethodProblem]("lerna.akka.entityreplication.ClusterReplicationSettings.withEventSourcedSnapshotStorePluginId")
3+
ProblemFilters.exclude[ReversedMissingMethodProblem]("lerna.akka.entityreplication.typed.ClusterReplicationSettings.withEventSourcedSnapshotStorePluginId")
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# It is safe to exclude the following since ClusterReplicationGuardian is package-private.
2+
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.akka.entityreplication.ClusterReplicationGuardian#Start.copy")
3+
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.akka.entityreplication.ClusterReplicationGuardian#Start.this")
4+
ProblemFilters.exclude[MissingTypesProblem]("lerna.akka.entityreplication.ClusterReplicationGuardian$Start$")
5+
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.akka.entityreplication.ClusterReplicationGuardian#Start.apply")
6+
ProblemFilters.exclude[IncompatibleSignatureProblem]("lerna.akka.entityreplication.ClusterReplicationGuardian#Start.unapply")

0 commit comments

Comments
 (0)