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

Store limited Brew History in Local Storage #3711

Merged

Conversation

G-Ambatte
Copy link
Collaborator

@G-Ambatte G-Ambatte commented Sep 5, 2024

This experimental PR saves a limited brew history in local storage, under the key HOMEBREWERY-HISTORY-{shareId}-{n}, where n is in the range 1-5.

This will resolve #3070.

Delay between history updates is controlled by the following array:

const HISTORY_SAVE_DELAYS = [
	1,			// 1 minute
	30,			// 30 minutes
	60,			// 60 minutes
	24 * 60,		// 24 hours
	5 * 24 * 60		// 5 days
];

Every time the Edit Page autosave function runs, the following takes place:

  • If the key does not exist, the brew's title, text, style, and the current time are combined into an object, JSON.stringified, and saved in the key.
  • If the key does exist, the encoded object is parsed and the current time is checked against the savedAt value + the relevant delay value. If the delay has expired, the stored key is updated with the current values.

To Dos

  • UI interface
    • view stored data
    • overwrite current values with stored data
  • garbage collection/expiry
  • consider adding a minimum version differential, instead of or in conjunction with time

@G-Ambatte G-Ambatte self-assigned this Sep 5, 2024
@G-Ambatte
Copy link
Collaborator Author

Because it seemed like a good idea, I have also added a version differential requirement to the update function. In the previous iteration, returning to the document that you were working on yesterday could immediately wipe out 80% of all stored data. By adding a minimum number of version changes as well, the stored data will not update unless the version has also changed by a minimum number, so returning to edit yesterday's document will only overwrite the historical versions once the user actually starts making changes.

@G-Ambatte
Copy link
Collaborator Author

Sample Local Storage keys:
image

@calculuschild
Copy link
Member

calculuschild commented Sep 5, 2024

returning to the document that you were working on yesterday could immediately wipe out 80% of all stored data.

Ideally, if the check finds that any entries are expired, only the oldest expired entry will be cleared, and all others will move up to the next time delay slot so only one entry expires at a time. Then, each entry will refresh its current time.

So in your example, if you return a full day later, item in slot 4 (24 hours) would expire, but slot 3 would take its place, starting a brand new 24 hour timer on that entry. Slot 2 would take the 1-hour slot, and slot 1 would take the 30-minute slot. Finally, the current brew contents would be stored in a new entry #1. I.e. you would still have 3 entries from the previous day.

This also should mean you don't have to check version history numbers, which could work against a person saving manually who works for several hours then makes one save. All that work would count as one version, which might not qualify for a backup, when they probably need the backup more than anyone.

I would reference issue #3070 where I have broken the logic down.

@G-Ambatte
Copy link
Collaborator Author

G-Ambatte commented Sep 6, 2024

Walking through the functionality as it currently stands:

  • generate local storage keys based on the brew's unique ShareID
  • read local storage values from generated keys
    • if no data present, use values from current brew with an expired timestamp
  • walk keys in reverse order
  • if not expired, continue loop
  • if expired, stop the loop
    • move data from all lower keys up by one, resetting expiry timestamps
      • on completion, store current brew data in first key

@G-Ambatte
Copy link
Collaborator Author

I have added a garbage collection function; when the function is called and a set period of time has passed without the data in local storage being updated, the history data will be removed.

@calculuschild
Copy link
Member

If you can't tell, I'm very excited about this one.

Copy link
Member

@calculuschild calculuschild left a comment

Choose a reason for hiding this comment

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

Seems functional. Just few small formatting/display things.

Co-authored-by: Trevor Buckner <calculuschild@gmail.com>
@G-Ambatte
Copy link
Collaborator Author

G-Ambatte commented Sep 16, 2024

I have changed the functionality slightly: during updating, when an empty slot is found, instead of using the current brew values, the function instead skips the update for that slot, still cycling through the remaining slots.

So the functionality is now thus:

  1. On first run, slot 1 gets filled (because it always gets filled with current data), so the menu would only show slot 1, version 1 data (current).
  2. On second run, slot 2 is filled with slot 1's old data. Slots 3-5 remain unfilled. So slot 1, v2 data (current); slot 2, v1 data
  3. Third run, slot 2 data progresses to 3, 1 to 2. So slot 1, v3 data (current); slot 2, v2 data; slot 3, v1 data.

...and so on until slot 1 has v5 data and slot 5 has v1 data.

As there will never be a point where multiple slots have the same data, it will (or at least, should) be clearer to the casual observer which slots contain the oldest data.

367676704-b96c056c-8439-414d-bc96-2790fc480bac

@calculuschild calculuschild added 🔍 R4 - Reviewed - Fixed! Awaiting final review⭐ PR review comments addressed and removed 🔍 R0 - Needs first review 👀 PR ready but has not been reviewed labels Sep 16, 2024
@G-Ambatte G-Ambatte temporarily deployed to homebrewery-pr-3711 September 16, 2024 19:42 Inactive
@calculuschild
Copy link
Member

calculuschild commented Sep 16, 2024

Before merging I just want to double-check the behavior. Just testing from the deployment I'm not sure the slots are expiring as I expect:

Slot 3 is over 3 hours old, but it's not expiring when I make a new save (should expire when 1 hour old); it just overwrites slot 1. Similarly slot 2 is over 40 minutes old but it's also not expiring (should expire after 10).

image

When home I will double-check with custom config values to make sure I'm not seeing things.

Edit: Ah, I think I see what it is. I come back 40 minutes later and save, and it does expire slot 2. Slot 1 takes its place and gets a new expiry time, but is going to show 40 minutes old because it was sitting in slot 1 for 40 minutes before it graduated. I was looking at the newly-graduated slot wondering why its time was so old but forgot it had only just arrived in its new position. All good. I was just overthinking it.

@G-Ambatte
Copy link
Collaborator Author

Before merging I just want to double-check the behavior. Just testing from the deployment I'm not sure the slots are expiring as I expect:

Slot 3 is over 3 hours old, but it's not expiring when I make a new save (should expire when 1 hour old); it just overwrites slot 1. Similarly slot 2 is over 40 minutes old but it's also not expiring (should expire after 10).

image

When home I will double-check with custom config values to make sure I'm not seeing things.

Expiry is set from the moment that the slot is updated, while the saved time is always the time that the data was first saved. Also, the update function only runs when the save function is called; if the document is not being updated, then the function is not being called, so infrequent document updates may cause the data to persist much longer in it's slot than otherwise expected.

As a debugging feature, we could add the slot expiry time to the UI, so we can see exactly when the slot will expire and ensure it matches expectations.

@calculuschild
Copy link
Member

Ok, my concerns have been assuaged. Merging now.

Thanks @G-Ambatte ! 💯 ⭐ 🎉

@calculuschild calculuschild merged commit f7aa934 into naturalcrit:master Sep 16, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

LocalStorage backups of brews
3 participants