Skip to content
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

Merged
merged 19 commits into from
Apr 25, 2024

Conversation

pjfanning
Copy link
Contributor

@pjfanning pjfanning commented Mar 19, 2024

relates to #30

  • I have gone back to experimenting a bit - so this is not mergeable right now

@pjfanning pjfanning marked this pull request as draft March 19, 2024 13:27
@mdedetrich
Copy link
Contributor

Unfortunately I don't have much experience with this but I will look into it tomorrow.

@pjfanning pjfanning changed the title take revision value into account when deleting take revision value into account when deleting DurableState Mar 19, 2024
Copy link
Member

@Roiocam Roiocam left a 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.

@@ -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))
Copy link
Member

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]

Copy link
Contributor Author

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

Copy link
Contributor Author

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

Copy link
Contributor

@mdedetrich mdedetrich Mar 20, 2024

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

Copy link
Contributor Author

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

Copy link
Contributor Author

@pjfanning pjfanning Mar 24, 2024

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Member

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.

@pjfanning pjfanning marked this pull request as ready for review March 20, 2024 09:31
Copy link
Member

@He-Pin He-Pin left a 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.

@pjfanning pjfanning requested a review from He-Pin April 23, 2024 11:47
@pjfanning
Copy link
Contributor Author

I still need to double check the tests pass with Pekko 1.1 but the code is more or less ready (I think).
Would anyone have time to review the latest position?

@mdedetrich @He-Pin @Roiocam @nvollmar @samueleresca @raboof

Copy link
Member

@He-Pin He-Pin left a 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
Copy link
Member

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?

Copy link
Contributor Author

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()
Copy link
Member

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 =
Copy link
Member

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

Copy link
Contributor Author

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 =>
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use transformWith?

Copy link
Contributor Author

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
}
}
Copy link
Member

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

Copy link
Contributor Author

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]
}

Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

@Roiocam Roiocam left a 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.

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) {
Copy link
Member

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.

Copy link
Contributor Author

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

docs/src/main/paradox/configuration.md Outdated Show resolved Hide resolved
Copy link
Member

@Roiocam Roiocam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@pjfanning pjfanning marked this pull request as ready for review April 25, 2024 20:02
@pjfanning pjfanning merged commit 08db474 into apache:main Apr 25, 2024
20 checks passed
@pjfanning pjfanning deleted the delete-revision branch April 25, 2024 20:02
@pjfanning pjfanning added this to the 1.1.0-M1 milestone Apr 25, 2024
@pjfanning pjfanning modified the milestones: 1.1.0-M1-RC1, 1.1.0-M1 May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants