Carbon-Farm-Network / app-carbon-farm-network

GNU Affero General Public License v3.0
1 stars 0 forks source link

use .subscribe({ fetchPolicy: 'cache-only' }) #20

Open pospi opened 1 year ago

pospi commented 1 year ago

In other work the easiest way of managing this has been via DOM events.

Unfortunately there is not a lot in the way of documentation on managing cache updates in GraphQL mutations, but once understood it is quite a powerful optimisation measure.

  1. Use any mutation callback's update option to specify custom handling to manage the query cache
    • note that unless complete results are sent to the cache in full, you will get errors from the GraphQL runtime and the values will not be inserted.
  2. Trigger a DOM event in the component immediately after it has finished the mutation() call.
  3. In a related (parent) component which needs to sync with the update from the (nested) child component, listen for this event. In the handler, call .subscribe({ fetchPolicy: 'cache-only' }) on any affected query instances managed by the component.
    • Note that you can expose such ReadableQuery objects (generated from query()) in child components so that a parent 'controller' component can manage linked updates across non-nested children (as per the linked example).
    • Note also that if the fetchPolicy: 'cache-only' is omitted, the data may will be re-queried from Holochain instead of the updated browser cache.
pospi commented 1 year ago

@LeosPrograms let me know how you go with this one once all other work on Facets & whatever user requirements are outstanding is completed. Not terribly urgent an issue but should result in more immediate updates throughout the application, and resolve any situations where screens are not updated as expected. Hopefully the code in the linked examples is enough to follow the principles along, even though it's a Lit app rather than a Svelte one (and all the event binding conveniences of Svelte should make it much simpler to implement in this app).

fosterlynn commented 1 year ago

Is this the cause of a problem I'm having: I updated something in an Offer, and when it went back to the Offer List page, it didn't show the updated data. If so, then this seems like a bug, not an enhancement to me, but discussion is welcome.

Curious: Is it that slow that we need to use any kind of caching?

[EDIT: If this is causing the list not to update, then it probably needs to go in the release milestone...]

pospi commented 1 year ago

Yep, that sounds like a culprit. If it's causing issues I will add it to the higher priority list.

We don't have to use the cache, really refetching from Holochain should be almost as quick. So if we are feeling pressured for time we could skip point 1 in the original issue and implement 3 without the fetchPolicy: 'cache-only' as that will fetch it from Holochain instead.

pospi commented 1 year ago

@LeosPrograms please feel free to move this issue to the "later..." milestone after the quick fix for the Offers page is completed, and change the title to something like "Leverage GraphQL cache for related component updates" since that will be the only remaining work thereafter.

pospi commented 1 year ago

I notice there are also some dirty workarounds using polling in some components. For example in routes/+page.svelte:

      setInterval(function(){
        fetchAgents()
      }, 20000)

These measures should be removed and instead the update coordinated as needed via DOM events as above.

LeosPrograms commented 1 year ago

When I attempt to use subscribe, I get

Argument of type '{ fetchPolicy: string; }' is not assignable to parameter of type 'Subscriber<Result>'. Object literal may only specify known properties, and 'fetchPolicy' does not exist in type 'Subscriber<Result>'.ts(2345)

pospi commented 1 year ago

I think that's fine for now? If you did not yet implement the update callback in mutations to refresh the cache (doesn't seem so?) then it wouldn't have any effect anyway. So simply calling .subscribe() without arguments is fine to trigger an update in a parent component; and the optimisation is only a minor one since the data will be re-pulled from Holochain's caches anyway.

Will leave this issue open, but set it to a low priority cleanup milestone.