Skip to content

iOS clean migration from RNCAsyncStorage_V1 to RTCAsyncStorage_V1 #64

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

Merged
merged 12 commits into from
Apr 11, 2019

Conversation

reilem
Copy link
Contributor

@reilem reilem commented Apr 9, 2019

Summary:

See: #55

Test Plan:

The only type of tests I have already run is:

  1. Hardcode set the variable RCTStorageDirectory to RNCAsyncStorage_V1
  2. Run the app & set some values to cache
  3. Close the app
  4. Reset RCTStorageDirectory to RCTAsyncStorage_V1
  5. Run the app and see that cached values have been migrated

I have performed these tests with and without a pre-existing storage directory and they work in both cases.

My only concerns are the way I am currently handling errors. If something goes wrong an NSException is thrown which will trigger a SIGABRT shutdown of the app since it is never caught. I am not extremely experienced with error handling in Objective-C so perhaps someone has some better ideas.

@krizzu krizzu added enhancement New feature or request platform: iOS This is iOS specific labels Apr 9, 2019
@krizzu
Copy link
Member

krizzu commented Apr 9, 2019

Hey @reilem, thanks for your work!
Code looks fine to me, so let me just test this on my end and let's merge it afterwards.

if (!newStorageDirectoryExists) {
// If new storage direction doesn't exist, copy old storage directory to new location
if (![[NSFileManager defaultManager] copyItemAtPath:RCTCreateStorageDirectoryPath(OldStorageDirectory) toPath:RCTGetStorageDirectory() error:&error]) {
@throw RCTStorageDirectionMigrationException(@"Failed to copy old storage directory to new storage directory", error);
Copy link
Member

Choose a reason for hiding this comment

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

We probably shouldn't take down the whole app if we fail to migrate. I think in the rare cases where IO might fail, maybe it's probably fine to just say that we "lost" the data?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I am not a big fan of crashing the app either, but I'm not a fan of leaving errors unused either. I guess in this case it would be just fine to ignore the errors? Cause I don't think adding NSLogs will be of much use either.

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 there's also a real risk of going into a crash loop. I think we should ignore it, and use RCTLogWarn or RCTLogError to log errors. What do you think, @krizzu?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah cool, didn't know these existed. Errors would also cause app crashes so I guess we could go with the Warnings to be safe. Right now I've replaced everything with NSLogs for now, so let me know what you guys think is best.

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 I prefer RCTLogWarn because they will at least be visible during debug as a yellow box, in addition to being logged to the console.

@krizzu
Copy link
Member

krizzu commented Apr 9, 2019

@tido64 Thanks for having a look. @reilem Thank you for your work 💪

On a second though, simply deleting RCT folder first would lead to some data loss as well.

Say, someone used pre-1.2.2 AS, then upgrades to 1.2.3/4 (RCT used here, meaning "fresh start"). Now, upgrading to next version (with this feature included), will again end with overriding with stuff from RNC.

I like the approach that @tido64 suggested, to check when each of the files (from RNC and RTC) were accessed and based on that proceed with migration.

Something like that:

if(RNC_DIR.exists){
    if(RCT_DIR.exists){
        if(RNC_DIR.accessTime > RCT_DIR.accessTime){
            // RNC being used, pre 1.2.2
            rm RCT_DIR;
            mv RNC_DIR RCT_DIR;
        else {
            // RCT in use, so ditch RNC
            rm RNC_DIR;
        }
    else {
        // RCT does not exists, so move RNC
        mv RNC_DIR RCT_DIR;
    }
} 

Let me know what you think!

@reilem
Copy link
Contributor Author

reilem commented Apr 9, 2019

I've made the requested changes however I have encountered a strange issue during testing. While the NSFileManager displays that old storage directories have been successfully removed and no longer exist (explicitly checked) I still somehow manage to get the actual old data displayed in my app. I'm guessing that my form of testing really isn't robust enough since it seems like some sort of cached data is being accessed.

Aside from the above issue, I have debugged the flow of the migration in the four cases and they seem to be working:

  1. Old data not exists --> do nothing
  2. Old data exists --> New data not exists --> copy --> remove old
  3. Old data exists --> New data exists --> New data is newer --> remove old
  4. Old data exists --> New data exists --> Old data is newer --> remove new --> copy --> remove old

@krizzu
Copy link
Member

krizzu commented Apr 10, 2019

@reilem Hey,

This strange behavior might come from the regression we had on iOS in version 1.2.3 and 1.2.4. Please rebase with latest master and check if it works for you and let me know.

@reilem
Copy link
Contributor Author

reilem commented Apr 10, 2019

I think I discovered my issue, during refactoring I made the manifest file path using stringByAppendingString instead of stringByAppendingPathComponent.

@reilem
Copy link
Contributor Author

reilem commented Apr 10, 2019

I have rebased on the latest PR merge, fixed the manifest issue and now use RCTLogWarn. All my "manual" tests are working now without issue. I thought about automating the tests, but I don't know of any accurate way to automate app restarts and I couldn't find anything about mocking const values in objective-c. Unless you guys have any ideas? 😄

@krizzu
Copy link
Member

krizzu commented Apr 10, 2019

Looking good! Going to test it manually later today to confirm it from my side.

thanks.

tido64
tido64 previously approved these changes Apr 11, 2019
Copy link
Member

@tido64 tido64 left a comment

Choose a reason for hiding this comment

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

Thanks for the good work! Code looks good to me. Just one little nitpick 😛

I haven't tested it yet. Maybe I have some time later today if @krizzu hasn't done it already 👍

Copy link
Member

@krizzu krizzu left a comment

Choose a reason for hiding this comment

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

I've checked every scenario locally and I can confirm it works as expected! Outstanding work @reilem 👏

Let's wait for #71 to be merged, so we could get a new release.

@tido64 tido64 merged commit 8d275ad into react-native-async-storage:master Apr 11, 2019
@krizzu
Copy link
Member

krizzu commented Apr 11, 2019

@reilem @tido64 Thanks guys! 🥇

krizzu pushed a commit that referenced this pull request Apr 12, 2019
## [1.3.1](v1.3.0...v1.3.1) (2019-04-12)

### Bug Fixes

* iOS clean migration from RNCAsyncStorage_V1 to RTCAsyncStorage_V1 ([#64](#64)) ([8d275ad](8d275ad))
@krizzu
Copy link
Member

krizzu commented Apr 12, 2019

🎉 This PR is included in version 1.3.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Corey-Peyton added a commit to Corey-Peyton/async-storage that referenced this pull request Jul 14, 2021
## [1.3.1](react-native-async-storage/async-storage@v1.3.0...v1.3.1) (2019-04-12)

### Bug Fixes

* iOS clean migration from RNCAsyncStorage_V1 to RTCAsyncStorage_V1 ([#64](react-native-async-storage/async-storage#64)) ([8d275ad](react-native-async-storage/async-storage@8d275ad))
DenisSolution pushed a commit to DenisSolution/React-native-async-storage that referenced this pull request Aug 27, 2022
## [1.3.1](react-native-async-storage/async-storage@v1.3.0...v1.3.1) (2019-04-12)

### Bug Fixes

* iOS clean migration from RNCAsyncStorage_V1 to RTCAsyncStorage_V1 ([#64](react-native-async-storage/async-storage#64)) ([8d275ad](react-native-async-storage/async-storage@8d275ad))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request platform: iOS This is iOS specific
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants