reactjs - Apollo mutation debounce and race conditions -


(this follow https://github.com/apollographql/apollo-client/issues/1886)

i'm trying build text input update value user types.

first attempt

i first tried use optimisticresponse update local cache user types. works, except fires off mutation on every key stroke. aside flooding network requests, there problem of inconsistency of network. it's possible last mutation arrive first, , first mutation arrive last. results in server ending stale value. here example of race condition:

type: mutate request: type: b mutate request: ab arrives on server: ab arrives on server: 

now server has recorded "a" in graphql, incorrect.

adding debounce

to alleviate this, added debounce keypress event. although race conditions described above, doesn't solve it. it's still possible have race condition if network slower debounce threshold.

because we're debouncing text input, need introduce local state react component updates user types (as @jbaxleyiii suggested in github issue). our state lives in 2 place (the component state , apollo cache).

a big problem component won't update when receives new props. eg. when graphql gets updated , pushes client.

adding network queue

because debounce doesn't solve race condition, added network queue (in addition debounce) manage mutation requests make sure there ever 1 mutation in flight @ time. if receives mutation request while there 1 in flight, queue fired when first 1 comes back. if there mutation queued, discard , replace new 1 (there can ever 1 item in queue @ time). here's example:

type: send mutate request: type: b queues mutate request: ab     <<  wait send until "a" comes type: c replaces queued request: abc  << discard queued request "ab", it's old response server: send mutate request: abc      << send queued mutation , clear queue response server: abc 

this guarantees won't have race condition (at lease client...)

there problem approach though. optimisticresponse update when mutation goes out. if mutation in flight, need wait network return before update optimisicrespose gets applied. time long time on slow networks. so, in example above, can't use optimisticresponse update "abc" until "send mutate request: abc".

this isn't huge deal, delay, seems should able do.

attempt update cache user types

in docs, learned can use withapollo access client, , update cache user types via writequery. replaces need optimisticresponse. however, problem arises when when old response comes , updates cache out under us. here's example:

action                   | cache -------------------------+------------ type:                  | mutate request:        | type: b                  | ab queues request: ab       | ab response server:  |  << oh no! mutate request: ab       |  << we're not using optimisticresponse anymore ... network time ...     | response server: ab | ab 

i suppose can use client.writequery update cache user types and optimisticresponse update when mutate request fires, code getting pretty hard follow.

there might way deal in update function, haven't gone far.

help?

i'm pretty new apollo maybe i'm missing something. there better way handle many rapid mutations in apollo?

each mutation returns promise, know when out-of-order mutation arrives, keeping track of latest one.

since accept user types, means user's value canonical one, , don't need optimistic response. you're doing making sure server has same value do.

so i'd propose track input in redux , add store listener fires off mutation (with debounce).

if need keep track of server value, use counter see if mutation returned last 1 (store ++counter value @ mutation send, , compare value counter value on mutation return).


Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -