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

[Modern] cacheConfig.poll setting does not poll #2174

Open
BenBrostoff opened this Issue Oct 28, 2017 · 10 comments

Comments

Projects
None yet
6 participants
@BenBrostoff

BenBrostoff commented Oct 28, 2017

If passing cacheConfig to QueryRenderer with a poll interval set, the function passed to Network.create does not execute on each poll interval. I believe this is a regression from v1.1.0 and is related to the refactoring of RelayEnvironment to use observables.

Reproducing

To demonstrate this is a regression, I’ve created two branches on a forked version of relay-examples. In polling-1.1, polling works as expected and in not-polling-1.4, polling does not work. Additionally, I confirmed when upgrading to v1.2.0, polling stops working. The only changes in these examples are modifications of relay library versions and console.logs.

Potential Causes

From diffing v1.1.0 and v1.2.0, I think observables were introduced in 1.2. From a few attempts at debugging, it appears to me this may be related to ConvertToExecuteFunction.js. I am not that familiar with observables, but the poll function on the observable is not invoking the fetchFn passed to Network.create.

Thanks for a great open source library, and would love to help on this one if it seems like a good beginner issue.

@timobetina

This comment has been minimized.

timobetina commented Nov 22, 2017

Hi @BenBrostoff
Have you been able to figure out what is wrong in the polling mechanism or how should it be used in case nothing is wrong?
Thanks

@eliperkins

This comment has been minimized.

Contributor

eliperkins commented Jan 9, 2018

I just spent some time digging into this as well and found a couple of things.

Polling current polls from the previous RelayObservable state rather than using the network

After setting up one of my QueryRenders to include the prop cacheConfig={{ poll: 1000 }}, I could see in my RelayNetworkLogger that it looked like requests were happening and data was being returned. However, the requests always seemed to return the same data as the initial request, and subsequent polling requests returned in sub-millisecond time. Taking a look at my server logs, it was clear that Relay wasn't actually making the request, but rather just returning the initial response from the first network request.

I tried setting some breakpoints to see why this was happening, but I couldn't find a clear-cut place in Relay where the result of the previous result from execute was being returned. For context, my Network fetch function just returns a Promise from fetch.

Using Network.create to do Live Queries (aka polling)

Tangentially, in #1655, @leebyron mentioned that you can create your own "live query" ability using Network.create with a fetch function that returns an observable: #1655 (comment)

However, if we supply some value for cacheConfig to a QueryRenderer, like cacheConfig={{ poll: 1000 }}, our Network function will never receive this poll value, because we're hardcoding the cacheConfig parameter that is passed to our Network fetch function to always be { force: true }:

return observeFetch(request, variables, {force: true}).poll(pollInterval);

This seems a little bit related to this issue, but it seems as though we should pass through the cacheConfig prop including force: true to Network.execute rather than override cacheConfig when polling is set.

@timobetina

This comment has been minimized.

timobetina commented Jan 27, 2018

I also spent some time looking at why polling was not working for me. As @eliperkins mentioned, Relay is actually doing polling. It didn't work when fetch function returns a Promise. But it has been working with fetch function returning RelayObservable.

When your fetch function is a Promise, it is called only once and then RelayObservable is created from the result. So only the initial result it being polled.

On the other hand when fetch function returns RelayObservable, then its Source function is being polled as expected.

@Angry-Potato

This comment has been minimized.

Angry-Potato commented Mar 12, 2018

@timobetina @eliperkins @BenBrostoff just ran into this myself, tried returning RelayObservable from fetch but still doesn't work, could any of you paste a working, polling fetch for this simpleton, please :P ?

@timobetina

This comment has been minimized.

timobetina commented Mar 22, 2018

Hi @Angry-Potato
This is a simplified example of my relay environment:

import { graphql } from "graphql";
import { Environment, Network, RecordSource, Store, Observable } from "relay-runtime";
import Schema from "./Schema";

function createFetch(schema) {
  return function fetch(operation) {
    return new Observable(sink => {
      graphql(
        schema,
        operation.text,
      ).then((payload) => {
        if (payload.errors) {
          /* Handle errors */
          sink.error(payload.errors);
        } else {
          /* Handle payload */
          sink.next(payload);
          sink.complete();
        }
      });
    });
  }
}

function createEnvironment() {
  return new Environment({
    network: Network.create(createFetch(Schema)),
    store: new Store(new RecordSource()),
  });
}
@Angry-Potato

This comment has been minimized.

Angry-Potato commented Mar 23, 2018

Thanks, I ended up just using subscriptions instead :P

@alloy

This comment has been minimized.

Collaborator

alloy commented Mar 23, 2018

Is this issue still relevant? Should there be updates to documentation and, if so, could one of you make a PR for that?

@sibelius

This comment has been minimized.

Collaborator

sibelius commented Mar 23, 2018

I think we can provide an example of fetch for network using Observable, and explain that this is needed to make poll work

@sibelius

This comment has been minimized.

Collaborator

sibelius commented Jul 23, 2018

I've managed to implemented it

It's open source here: https://github.com/sibelius/relay-modern-network-deep-dive

There is also a medium post about it: https://medium.com/@sibelius/relay-modern-network-deep-dive-ec187629dfd3

now we need to improve Relay official docs

@alloy

This comment has been minimized.

Collaborator

alloy commented Jul 23, 2018

Great stuff @sibelius 👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment