Fixed async local storage

This commit is contained in:
Nick Lockwood 2015-06-23 14:17:31 -07:00
parent 47508566a0
commit 0624a0fe52
2 changed files with 30 additions and 17 deletions

View File

@ -54,6 +54,9 @@ function expectEqual(lhs, rhs, testname) {
}
function expectAsyncNoError(place, err) {
if (err instanceof Error) {
err = err.message;
}
expectTrue(err === null, 'Unexpected error in ' + place + ': ' + JSON.stringify(err));
}

View File

@ -17,9 +17,9 @@
#import "RCTLog.h"
#import "RCTUtils.h"
static NSString *const kStorageDir = @"RCTAsyncLocalStorage_V1";
static NSString *const kManifestFilename = @"manifest.json";
static const NSUInteger kInlineValueThreshold = 100;
static NSString *const RCTStorageDirectory = @"RCTAsyncLocalStorage_V1";
static NSString *const RCTManifestFileName = @"manifest.json";
static const NSUInteger RCTInlineValueThreshold = 100;
#pragma mark - Static helper functions
@ -61,11 +61,25 @@ static id RCTReadFile(NSString *filePath, NSString *key, NSDictionary **errorOut
return nil;
}
static NSString *RCTGetStorageDir()
static NSString *RCTGetStorageDirectory()
{
NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSURL *homeURL = [NSURL fileURLWithPath:documentDirectory isDirectory:YES];
return [[homeURL URLByAppendingPathComponent:kStorageDir isDirectory:YES] path];
static NSString *storageDirectory = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
storageDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
storageDirectory = [storageDirectory stringByAppendingPathComponent:RCTStorageDirectory];
});
return storageDirectory;
}
static NSString *RCTGetManifestFilePath()
{
static NSString *manifestFilePath = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manifestFilePath = [RCTGetStorageDirectory() stringByAppendingPathComponent:RCTManifestFileName];
});
return manifestFilePath;
}
// Only merges objects - all other types are just clobbered (including arrays)
@ -111,7 +125,7 @@ static BOOL RCTHasCreatedStorageDirectory = NO;
static NSError *RCTDeleteStorageDirectory()
{
NSError *error;
[[NSFileManager defaultManager] removeItemAtPath:RCTGetStorageDir() error:&error];
[[NSFileManager defaultManager] removeItemAtPath:RCTGetStorageDirectory() error:&error];
RCTHasCreatedStorageDirectory = NO;
return error;
}
@ -125,8 +139,6 @@ static NSError *RCTDeleteStorageDirectory()
// in separate files (as opposed to nil values which don't exist). The manifest is read off disk at startup, and
// written to disk after all mutations.
NSMutableDictionary *_manifest;
NSString *_manifestPath;
NSString *_storageDirectory;
}
RCT_EXPORT_MODULE()
@ -165,7 +177,7 @@ RCT_EXPORT_MODULE()
- (NSString *)_filePathForKey:(NSString *)key
{
NSString *safeFileName = RCTMD5Hash(key);
return [_storageDirectory stringByAppendingPathComponent:safeFileName];
return [RCTGetStorageDirectory() stringByAppendingPathComponent:safeFileName];
}
- (id)_ensureSetup
@ -174,8 +186,7 @@ RCT_EXPORT_MODULE()
NSError *error = nil;
if (!RCTHasCreatedStorageDirectory) {
_storageDirectory = RCTGetStorageDir();
[[NSFileManager defaultManager] createDirectoryAtPath:_storageDirectory
[[NSFileManager defaultManager] createDirectoryAtPath:RCTGetStorageDirectory()
withIntermediateDirectories:YES
attributes:nil
error:&error];
@ -185,9 +196,8 @@ RCT_EXPORT_MODULE()
RCTHasCreatedStorageDirectory = YES;
}
if (!_haveSetup) {
_manifestPath = [_storageDirectory stringByAppendingPathComponent:kManifestFilename];
NSDictionary *errorOut;
NSString *serialized = RCTReadFile(_manifestPath, nil, &errorOut);
NSString *serialized = RCTReadFile(RCTGetManifestFilePath(), nil, &errorOut);
_manifest = serialized ? [RCTJSONParse(serialized, &error) mutableCopy] : [[NSMutableDictionary alloc] init];
if (error) {
RCTLogWarn(@"Failed to parse manifest - creating new one.\n\n%@", error);
@ -202,7 +212,7 @@ RCT_EXPORT_MODULE()
{
NSError *error;
NSString *serialized = RCTJSONStringify(_manifest, &error);
[serialized writeToFile:_manifestPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
[serialized writeToFile:RCTGetManifestFilePath() atomically:YES encoding:NSUTF8StringEncoding error:&error];
id errorOut;
if (error) {
errorOut = RCTMakeError(@"Failed to write manifest file.", error, nil);
@ -248,7 +258,7 @@ RCT_EXPORT_MODULE()
NSString *value = entry[1];
NSString *filePath = [self _filePathForKey:key];
NSError *error;
if (value.length <= kInlineValueThreshold) {
if (value.length <= RCTInlineValueThreshold) {
if (_manifest[key] && _manifest[key] != (id)kCFNull) {
// If the value already existed but wasn't inlined, remove the old file.
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];