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

Issue #250: Implements Bidirectional RelationshipResolver #256

Merged
merged 43 commits into from
Jul 31, 2014

Conversation

jleandroperez
Copy link
Contributor

The goal of this PullRequest is to prevent any scenarios that could potentially cause relationships not-to-be-sync'ed, such as "Source Objects" being inserted after the "Target Objects".

The new mechanism will store a descriptor for each relationship, containing the following fields:

  • Source Object: Key, bucket and attribute
  • Target Object: Key + bucket**

Whenever any of the involved objects get inserted (Source/Target), the relationship resolver will check the pending descriptors containing the inserted object's key, and will attempt to establish the relationship. This will be performed for both, Source + Target objects. As a result, insertion order should not be an issue anymore.

Fixes Issue #250

- (NSInteger)countPendingRelationshipsWithSourceKey:(NSString *)sourceKey
andTargetKey:(NSString *)targetKey;

- (BOOL)verifyBidireccionalMappingBetweenKey:(NSString *)sourceKey
Copy link
Contributor

Choose a reason for hiding this comment

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

Small typo: "bidirectional"

NSDictionary *metadata = [storage metadata];

// If there's already nothing there, save some CPU by not writing anything
if ( self.pendingRelationships.count == 0 && metadata[SPRelationshipsPendingsNewKey] == nil ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Formatting consistency (spaces in the condition).

block();
} else {
dispatch_async(dispatch_get_main_queue(), block);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

As a potential consumer of this API, this pattern seems unexpected. Any way to make it clearer?

Is this method actually being called from both the main thread and other threads? If called from the main thread, does it have to be executed synchronously like that, or could it still be dispatched asynchronously?

If it can be changed to always execute asynchronously, the API could be changed to be more clear (e.g. by adding an optional completion handler and documenting it).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Save OP doesn't need to be synchronous. But access to the pendingRelationships map is performed, always, on the main thread. To make it super clear, we could move the dispatch_async call to the caller instead. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it tends to be clearer to do it that way (let the caller decide), or at least pick one way or the other and make it clear how it behaves in the method definition/documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mikejohnstn in that case, would it be okay with you if we move the 'Relationship Resolver' queue to SPBucket, right by 'processorQueue' property, for consistency sake?

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure that sounds reasonable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the feedback Mike, much appreciated!

// Verify
XCTAssert( [self.resolver countPendingRelationships] == SPTestIterations, @"Inconsistency found" );

for (NSInteger i = 0; ++i < SPTestIterations; ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be <= here?

For all the places where you're doing this, I think the more standard for (NSInteger i=0; i < SPTestIterations; ++i) is clearer (or i++).

@jleandroperez
Copy link
Contributor Author

@CapoChino may i ask you if you've been able to verify if the relationships bug is still present on this branch?.

Thanks!

@jleandroperez jleandroperez modified the milestones: v0.6.7, v0.6.6 Jul 18, 2014
- (id)defaultValue {
return nil;
}

- (id)simperiumKeyForObject:(id)value {
NSString *simperiumKey = [value simperiumKey];
return simperiumKey == nil ? @"" : simperiumKey;
return simperiumKey == nil ? @"" : simperiumKey;
}

- (SPManagedObject *)objectForKey:(NSString *)key context:(NSManagedObjectContext *)context {
// TODO: could possibly just request a fault?
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we ditch this TODO now as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Definitely, will nuke!

@CapoChino
Copy link

Hi Jorge,

The problem was still present last I checked, but that was a couple weeks
ago. Unfortunately, I had to move ahead and ship an update of my app
without Simperium support. I'm hoping this issue will get resolved and
I'll give Simperium another try for the next version.

Thanks,
Casey

On Tue, Jul 8, 2014 at 4:19 PM, Jorge Leandro Perez <
notifications@github.com> wrote:

@CapoChino https://github.com/CapoChino may i ask you if you've been
able to verify if the relationships bug is still present on this branch?.

Thanks!


Reply to this email directly or view it on GitHub
#256 (comment)
.

+ (NSArray *)parseFromLegacyDictionary:(NSDictionary *)rawLegacy;

+ (instancetype)relationshipFromObjectWithKey:(NSString *)sourceKey
andAttribute:(NSString *)sourceAttribute
Copy link
Contributor

Choose a reason for hiding this comment

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

I have mixed feelings about using and in Obj-C method names. How about you?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, sounds better without and's. Let's change that!

@jleandroperez
Copy link
Contributor Author

@CapoChino may i ask you if you checked against this PR? exact same scenario, nil relationships?

Thanks!

andAttribute:(NSString *)sourceAttribute
inBucket:(NSString *)sourceBucket
toObjectWithKey:(NSString *)targetKey
inBucket:(NSString *)targetBucket;
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar comment: instead of two inBucket names, could instead do sourceBucket and targetBucket. Less of an English sentence, but perhaps a bit clearer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch! let's update that signature as well.

jleandroperez added a commit that referenced this pull request Jul 31, 2014
Issue #250: Implements Bidirectional RelationshipResolver
@jleandroperez jleandroperez merged commit eb50041 into develop Jul 31, 2014
@jleandroperez jleandroperez deleted the issues/250-null-relationships branch July 31, 2014 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants