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

Cache load errors cause deadlock in write transaction #365

Closed

Conversation

ashiemke
Copy link
Contributor

@ashiemke ashiemke commented Sep 11, 2018

Reject batch loader loads if a loader fails to allow exceptions to cascade through promise chain. Previous behavior (run test without code) causes the load to never complete, and more importantly, causes the store to hold a read lock indefinitely, causing a deadlock when a write is attempted later. In practice, this is every time a fetch occurs with default cache policy.

The root of the issue is a non-normalized dictionary which is stored in the cache. In our schema, we have some JSON blobs that come from an external service which are represented as a JSON custom scalar. Storing these in the cache worked fine, but fetching these types caused attempts to read from cache to never return, and other strange behavior due to writes also failing.

Solution was pretty simple, just needed to pass the failures in the batch loader to the individual load promises so they can be picked up and forwarded on the chain. Since these are wrapped in a whenAll, only the first reject matters.

@ashiemke
Copy link
Contributor Author

One travis failure, which passes on my local. Unsure why it's breaking. Can someone kick it? I suspect it's a timing-related failure.

let query = HeroAndFriendsNamesQuery()
load(query: query) { (result, error) in
XCTAssertNil(result)
XCTAssertNotNil(error)

Choose a reason for hiding this comment

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

Updating this to

XCTAssertTrue(error is GraphQLResultError)
XCTAssertTrue((error as! GraphQLResultError).underlying is JSONDecodingError)

provides a bit more confidence about what is happening here.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd use guard let instead of force unwrapping because force unwrapping crashes the whole test suite instead of just failing the test, but I agree here

Copy link
Contributor

@designatednerd designatednerd left a comment

Choose a reason for hiding this comment

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

@ashiemke No idea why that one test failed, rerunning the whole suite. If you can rebase this on master so we can run it against Xcode 10, that'd be lovely - this seems like it could help.

@designatednerd
Copy link
Contributor

Yeah you'll definitely need to rebase since the project is now using Swift 5 - went from only one test failing to all of them failing 🤦‍♀️

@designatednerd
Copy link
Contributor

@ashiemke are you interested in continuing this PR?

@designatednerd
Copy link
Contributor

@ashiemke Since I haven't heard back from ya in a while, I'm going to take this over so we can try to get it merged.

@designatednerd
Copy link
Contributor

Closing this one out, please follow #763 for an attempted resolution here.

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.

3 participants