migesok commented on code in PR #2027:
URL: https://github.com/apache/pekko/pull/2027#discussion_r2272743628
##########
persistence/src/main/scala/org/apache/pekko/persistence/journal/AsyncWriteJournal.scala:
##########
@@ -67,9 +67,21 @@ trait AsyncWriteJournal extends Actor with WriteJournalBase
with AsyncRecovery {
final val receiveWriteJournal: Actor.Receive = {
// cannot be a val in the trait due to binary compatibility
val replayDebugEnabled: Boolean = config.getBoolean("replay-filter.debug")
+ val enableGlobalWriteResponseOrder: Boolean =
config.getBoolean("write-response-global-order")
+
val eventStream = context.system.eventStream // used from Future callbacks
implicit val ec: ExecutionContext = context.dispatcher
+ // should be a private method in the trait, but it needs the
enableGlobalWriteResponseOrder field which can't be
+ // moved to the trait level because adding any fields there breaks
bincompat
+ def sendWriteResponse(msg: Any, snr: Long, target: ActorRef, sender:
ActorRef): Unit = {
Review Comment:
Unfortunately, no amount of annotations would save me from runtime class
errors here.
This method needs access to the "memoized" config option, which has to be a
val/var/lazy val - enableGlobalWriteResponseOrder. Which I currently put under
` final val receiveWriteJournal: Actor.Receive = {...}` scope. My first version
had the field on the trait level as a private val - right under here:
https://github.com/apache/pekko/blob/e7e71a3adffdd8b19d800b22843780b54f56d4b8/persistence/src/main/scala/org/apache/pekko/persistence/journal/AsyncWriteJournal.scala#L60
Then it lead to runtime issues:
- you have a concrete plugin class extending AsyncWriteJournal built against
the old version, without the new private val
- you try to run it against the new AsyncWriteJournal version
- adding a new private/packag-private/private[this] val to trait results in
new abstract methods in the generated interface
- classloading of the plugin class fails in runtime because an interface it
implements has new abstract methods which the concrete class does not implement
It seems I was not the first one to hit this issue in this trait:
```
final val receiveWriteJournal: Actor.Receive = {
// cannot be a val in the trait due to binary compatibility
val replayDebugEnabled: Boolean =
config.getBoolean("replay-filter.debug")
```
TBH before this ordeal I wasn't aware that adding private fields to a trait
breaks bincompat but I was able to confirm it on small examples:
https://gist.github.com/migesok/71c5e5feb1ba4fff8c6515f42922df11
Please let me know if there is a better way to structure it without breaking
bincompat.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]