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

Delete durable state #30446

Closed
ignasi35 opened this issue Jul 30, 2021 · 6 comments
Closed

Delete durable state #30446

ignasi35 opened this issue Jul 30, 2021 · 6 comments
Labels
1 - triaged Tickets that are safe to pick up for contributing in terms of likeliness of being accepted t:persistence
Milestone

Comments

@ignasi35
Copy link
Member

ignasi35 commented Jul 30, 2021

See #30277

Delete API wasn't included in the initial implementation. This is a feature request to support deletes.


If Durable State feature introduces def deleteObject we should also consider how that becomes visible in projections. The usual implementation on plugins for that operation is to physically delete the entity from the database (as a regular CRUD operation would do).

This hard delete has implications from a projections point of view. By storing multiple revisions of the same entity in-place and then deleting the following can happen:

...
entity123-rev7 <--- last value read when polling via changes(tag,offset)
entity123-rev8
entity123-rev9
(deleted row)

From a query point of view (e.g. changes(tag, offset)), imagine an iteration reads rev7, then rev8, rev9 and the deletion happens. In that case, the information on rev8, rev9 and the actual deletion are lost on the projection side.


For a CRUD-minded user point of view first arriving into CQRS-like (durable-state with akka-projections) the case above is likely to lead to corrupted projections.

A potential solution would be to require all implementations to implement deleteObject as a soft deletion and include a def hardDelete on the API. Another option would be to replace the payload on the database with a case object Tombstone. Still another option is to document this situation and recommend users to model deletion as a domain command that doesn't remove data from the database and warn about the implications of invoking deleteObject when using durable state in combination with projections.

@ignasi35
Copy link
Member Author

A similar thing happens when using Event Sourcing if a user deletes the events from the journal before they are consumed by the projections.

In event sourcing, though, hard deletion is more rare and, in general, users are more aware of the implications of deleting and the existence of projections since ES and CQRS go hand in hand very often.

@ignasi35 ignasi35 changed the title Durable state delete leading to data loss Durable state delete leading to data out of sync (projections) Jul 30, 2021
@ignasi35 ignasi35 changed the title Durable state delete leading to data out of sync (projections) Durable state delete leading to data out of sync projections Aug 2, 2021
@patriknw
Copy link
Member

There is no API for deletes yet, so I changed the title and some of the issue description.

@patriknw patriknw changed the title Durable state delete leading to data out of sync projections Delete durable state Aug 10, 2021
@patriknw patriknw added t:persistence 1 - triaged Tickets that are safe to pick up for contributing in terms of likeliness of being accepted labels Aug 10, 2021
@bdoyle0182
Copy link

We have always wanted built in deletes for akka persistence as our persistent actors only live for about a day at max, and would endlessly build up in the db if we didn't implement our own clean up mechanism. We're planning to migrate to durable state since we've never needed event history. I haven't looked at any design this issue proposes, but what would be very useful for us is that the delete of the state data does not have to occur by persistent actor itself.

Our use case:

  1. We have a persistent actor that watches another persistent actor.
  2. Child persistent actor lets the parent persistent actor know it's completed all of its tasks.
  3. Parent persistent actor updates its state to know the child has completed and dispatches the next unit of work. The parent then deletes the child actor persistence data as a side effect (our own custom delete directly to the persistence document in the db) of its state update marking the child as completed to keep the database in an optimally not ever growing state.

@octonato
Copy link
Member

@bdoyle0182, one we have the means to delete the state, I think you can implement your use case by letting the parent send a message to the child telling it that it can clean-up itself. The child would then call the delete effect and stop.

Managing the state from outside the actor child would only complicate things, IMO.

@bdoyle0182
Copy link

bdoyle0182 commented Oct 26, 2021

So long as the delete effect and stop can also send a reply to the actor that sent the message (acting as an ack) that resulted in the delete effect, I'm happy with that.

Edit: actually I don't think the ack back to the caller is necessary for us. Our delete of state data is a side effect after the parent has written to its state data that the child completed, so the delete of the child state data is best effort. We have expiries in our db for those edge cases that get missed.

@jausmann-wc
Copy link

We have implemented our own persistence plugin and could really make use of a delete Effect to delete an entity in the db. Is there any chance to give this issue higher priority?

jausmann-wc added a commit to jausmann-wc/akka that referenced this issue Jan 20, 2022
* Add reset effect to the state dsl.
* The effect calls deleteObject in the durable state store.
* The effect updates state to the empty state.
patriknw added a commit that referenced this issue Sep 2, 2022
* Add reset effect to the state dsl.
* The effect calls deleteObject in the durable state store.
* The effect updates state to the empty state.
* Implement DeletedDurableState for persistence query.
* Update PersistenceTestKitDurableStateStore so that deleteObject sets the Record payload to None, ie delete the payload.
* update documentation for delete effect
* increment the revision by one when deleting state
* Overload deleteObject with revision and deprecate deleteObject.
* add bin-comp exclude
patriknw added a commit that referenced this issue Sep 2, 2022
patriknw pushed a commit that referenced this issue Sep 2, 2022
* Add reset effect to the state dsl.
* The effect calls deleteObject in the durable state store.
* The effect updates state to the empty state.
* Implement DeletedDurableState for persistence query.
* Update PersistenceTestKitDurableStateStore so that deleteObject sets the Record payload to None, ie delete the payload.
* update documentation for delete effect
* increment the revision by one when deleting state
* Overload deleteObject with revision and deprecate deleteObject.
* add bin-comp exclude

(cherry picked from commit 34a621a)
@patriknw patriknw added this to the 2.6.20 milestone Sep 6, 2022
@patriknw patriknw closed this as completed Sep 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1 - triaged Tickets that are safe to pick up for contributing in terms of likeliness of being accepted t:persistence
Projects
None yet
Development

No branches or pull requests

5 participants