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

Storage promotion/demotion and legacy object unpinning for entity state API #700

Merged
merged 13 commits into from
Jul 17, 2023

Conversation

stalgiag
Copy link

@stalgiag stalgiag commented May 24, 2023

This PR adds support for file promotion/demotion & legacy object unpinning with the entity state API.

I am new to Elixir and Phoenix so apologies in advance if I am missing something about preferred patterns. I added two units tests. I believe that most of this behavior has coverage in the existing storage tests.

PR #6092 in the client repo is dependent on these changes.

Copy link
Contributor

@johnshaughnessy johnshaughnessy left a comment

Choose a reason for hiding this comment

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

delete_entity_state needs to deactivate the associated OwnedFile, if there is one. The way I proposed doing this in a comment in the PR for the client-side changes was for the client to provide the file_id to the call. This should work (and is how the current unpin behavior works), but upon further reflection it's suspicious that reticulum would need the client to provide this information at all, rather than it keeping track of the association on its own. In other words, maybe rows in the entity_state table should have a nullable foreign key into the OwnedFile table.

Comment on lines 1463 to 1465
defp handle_file_promotion(entity, %{file_id: nil} = _params, _account, socket) do
broadcast_entity_state(entity, socket)
end
Copy link
Contributor

Choose a reason for hiding this comment

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

My guess is that this pattern is not idiomatic elixir, because your intent is something like "If there's a file_id, try to promote/activate it (potentially returning an error), then broadcast. If there's not a file_id, just broadcast." And it feels strange to stick the "then broadcast" part inside handle_file_promotion.

But I don't know elixir well enough to know how experts tend to write this (common) case. No need to change it, but if you find a better way, please let me know because I'll be curious to learn it.

One idea is that maybe_promote_file returns :ok or {:error, reason}, and the file_id: nil case is just :ok. Then the calling code uses if or with.

@stalgiag stalgiag temporarily deployed to smoke June 1, 2023 14:55 — with GitHub Actions Inactive
Copy link
Contributor

@johnshaughnessy johnshaughnessy left a comment

Choose a reason for hiding this comment

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

edit: Approved by mistake -- still need to review latest commits

Copy link
Contributor

@johnshaughnessy johnshaughnessy left a comment

Choose a reason for hiding this comment

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

(Sorry to muddy the history. I approved by mistake. Will followup with a proper review.)

@stalgiag stalgiag temporarily deployed to smoke June 2, 2023 15:08 — with GitHub Actions Inactive
@stalgiag stalgiag temporarily deployed to smoke June 2, 2023 15:14 — with GitHub Actions Inactive
@stalgiag
Copy link
Author

stalgiag commented Jun 2, 2023

Ready for review again. I took your advice and went with a maybe_promote_file pattern which I like much better. Also added the code that handles unpinning of legacy objects and demotion (set inactive).

@stalgiag stalgiag changed the title Storage promotion handling for entity state API Storage promotion/demotion and legacy object unpinning for entity state API Jun 2, 2023
})

{:reply, :ok, socket}
end
Copy link
Contributor

@johnshaughnessy johnshaughnessy Jun 12, 2023

Choose a reason for hiding this comment

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

This handler (and the following one) looks suspicious.

If for some reason the delete_entity_state request does not result in the entity state being deleted (and the associated OwnedFile becoming inactive), this function should reply_error with a reason. The reasons we should catch are:

  • If the socket is unauthorized,
  • If delete_entity fails (e.g. the entity doesn't exist),
  • (Maybe?) If the OwnedFile doesn't exist

Also, I think we need to handle the RoomObject records slightly differently.

On the client, when we load the legacy room objects, we synthesize messages for them so that the client can act as if they are entity create/update messages. (See loadLegacyRoomObjects and messageForLegacyRoomObject in the client.)

We would like to add to this flow a step where a client, when it synthesizes this message, also calls save_entity_state so that that data is migrated to the new EntityState storage (non destructively).

Therefore, when reticulum receives an delete_entity_state directive, there are two (valid) states we should be concerned with:

  1. There is both an EntityState and a RoomObject for this nid. We need to delete both.
  2. There is only an EntityState for this nid. We only need to delete the entity state.

Deleting a non-existant RoomObject is probably no trouble, so trying to delete both each time is probably a fine strategy (knowing that many times, the RoomObject won't exist).

And, as you have done here -- if there is a file_id in the payload, we need to mark the associated OwnedFile as inactive. To avoid duplicating code, might consider having a single handle_in("delete_entity_state", %{"nid" => nid } = payload ... , and if payload has a file_id, call set_inactive. But that's more a matter of style, not correctness.

@stalgiag stalgiag temporarily deployed to smoke June 13, 2023 14:05 — with GitHub Actions Inactive
@stalgiag stalgiag temporarily deployed to smoke June 13, 2023 17:11 — with GitHub Actions Inactive
@johnshaughnessy johnshaughnessy temporarily deployed to smoke July 1, 2023 01:20 — with GitHub Actions Inactive
@johnshaughnessy johnshaughnessy merged commit 77e39ca into master Jul 17, 2023
10 of 11 checks passed
@johnshaughnessy johnshaughnessy deleted the promotion_entity_state_api branch July 17, 2023 20:32
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.

2 participants