-
Notifications
You must be signed in to change notification settings - Fork 16
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
take revision value into account when deleting DurableState #156
Conversation
core/src/main/scala/org/apache/pekko/persistence/jdbc/state/DurableStateQueries.scala
Outdated
Show resolved
Hide resolved
core/src/test/scala/org/apache/pekko/persistence/jdbc/state/scaladsl/JdbcDurableStateSpec.scala
Show resolved
Hide resolved
Unfortunately I don't have much experience with this but I will look into it tomorrow. |
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.
LGTM until these have been fixed.
core/src/main/scala/org/apache/pekko/persistence/jdbc/state/DurableStateQueries.scala
Outdated
Show resolved
Hide resolved
.../src/main/scala/org/apache/pekko/persistence/jdbc/state/scaladsl/JdbcDurableStateStore.scala
Show resolved
Hide resolved
@@ -117,7 +117,7 @@ class JdbcDurableStateStore[A]( | |||
db.run(queries.deleteFromDb(persistenceId).map(_ => Done)) | |||
|
|||
def deleteObject(persistenceId: String, revision: Long): Future[Done] = | |||
db.run(queries.deleteFromDb(persistenceId).map(_ => Done)) | |||
db.run(queries.deleteBasedOnPersistenceIdAndRevision(persistenceId, revision).map(_ => Done)) |
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 the deletion operation is not allowed, there will be no warnings and exceptions. I think we should notify users in some way, such as returning Future[Boolean]
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.
changing a public API method/function signature is not allowed - we would need a new API
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.
this API overrides a super class functions so it can't change
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.
changing a public API method/function signature is not allowed - we would need a new API
We have already broken ABI because of Slick 3.5.0 and this project doesn't guarantee SemVer so its not a stretch to also break source compatibility however in this case it seems like we can avoid it
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.
this function is part of the shared Persistence API - ie it overrides a function in a super class
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.
I don't understand - the point is we have a common Persistence API - why would we hack in extra methods in just this implementation? Shouldn't we update the common Persistence API and uptake it in all the persistence implementations?
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.
I created apache/pekko#1232 - is 1232 worth delaying the 1.1.0-M1 release for? I don't think so, myself.
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 the deletion operation is not allowed, there will be no warnings and exceptions. I think we should notify users in some way, such as returning Future[Boolean]
Isn't a better way that doesn't break binary compatibility to just return a Future.failed
with some sealed exception trait so users can get more information?
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.
can this be done in another PR? - it does not just affect the function that I am working on - it affects a number of other functions
It also looks like a change that we would want to replicate across all our persistence implementations. Some of them might already have Future failure results for failures to delete but it's quite likely that they all quietly ignore the fact that delete call deleted nothing.
I really think this is a set of changes in behaviour that should be discussed publicly before we make them.
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 DAO doesn't delete anything, throwing an exception is reasonable for me.
core/src/main/scala/org/apache/pekko/persistence/jdbc/state/DurableStateQueries.scala
Show resolved
Hide resolved
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.
lgtm, just need update the doc.
88b2c66
to
25eeb7a
Compare
core/src/test/scala/org/apache/pekko/persistence/jdbc/state/scaladsl/JdbcDurableStateSpec.scala
Outdated
Show resolved
Hide resolved
add test add tests scalafmt update test Update DurableStateQueries.scala scalafmt
43d362f
to
15bda57
Compare
I still need to double check the tests pass with Pekko 1.1 but the code is more or less ready (I think). @mdedetrich @He-Pin @Roiocam @nvollmar @samueleresca @raboof |
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.
Overall lgtm, reviewed from my phone, sorry for not properly highlighted
private val methodHandleLookup = MethodHandles.publicLookup() | ||
|
||
private def exceptionClassOpt: Option[Class[_]] = | ||
Try(Class.forName(DeleteRevisionExceptionClass)).toOption |
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.
I think this private method is not needed, inline it to the lazy val?
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.
This is what hotspot compiler is for. I seriously wonder why we bother using Scala when reviewers expect assembly language like code.
private[scaladsl] object DurableStateExceptionSupport { | ||
val DeleteRevisionExceptionClass = | ||
"org.apache.pekko.persistence.state.exception.DeleteRevisionException" | ||
private val methodHandleLookup = MethodHandles.publicLookup() |
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.
Lookup is only be used once
* it is added in Pekko 1.1. | ||
*/ | ||
private[scaladsl] object DurableStateExceptionSupport { | ||
val DeleteRevisionExceptionClass = |
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.
I would suggest mark it private , this will be visible in Java, seems the only usage is in testing
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.
I don't see any massive benefit to making this private
db.run(queries.deleteFromDb(persistenceId).map(_ => Done)) | ||
override def deleteObject(persistenceId: String, revision: Long): Future[Done] = { | ||
db.run(queries.deleteBasedOnPersistenceIdAndRevision(persistenceId, revision)).map { count => | ||
{ |
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.
Use transformWith?
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.
transformWith lets you convert Try[T] to a new result? Why do I need to convert the failure case here?
} | ||
Done | ||
} | ||
} |
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.
Set the execution context to be samethread
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.
changed to use parasitic context
constructorOpt.map { constructor => | ||
constructor.invoke(message).asInstanceOf[Exception] | ||
} | ||
|
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.
I think we can just let this method returns Done, and if it's 1.1.x and count is 0,throw exception, this will be simpler and the compiler is happy too.
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.
I prefer the current style in my PR.
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.
LGTM overall, leave some slick
optmization suggest.
core/src/main/scala/org/apache/pekko/persistence/jdbc/state/DurableStateQueries.scala
Outdated
Show resolved
Hide resolved
core/src/main/scala/org/apache/pekko/persistence/jdbc/state/DurableStateQueries.scala
Outdated
Show resolved
Hide resolved
db.run(queries.deleteFromDb(persistenceId).map(_ => Done)) | ||
override def deleteObject(persistenceId: String, revision: Long): Future[Done] = | ||
db.run(queries.deleteBasedOnPersistenceIdAndRevision(persistenceId, revision)).map { count => | ||
if (count == 0) { |
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.
Maybe if (count != 1)
? we need to consider the case that we delete more than one.
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.
changed - I added logic to output a different message if the count > 1
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.
LGTM
relates to #30