Giter Club home page Giter Club logo

Comments (12)

bman654 avatar bman654 commented on May 3, 2024 6

If you add this, I recommend not making it time-based, but instead make it signal-based. Something like:

// mimic current behavior
new DataLoader(batchLoadFn, { batchSignal: () => Promise.resolve() });

// time-based batch
new DataLoader(batchLoadFn, { batchSignal: () => Promise.delay(10) });

// signal-based
new DataLoader(batchLoadFn, { batchSignal: () => waitForSomeSignalToArrive() });

// only wait 10ms for the first batch.
// Subsequent batches wait just one tick (to prevent cascading delays)
const batchSignal = Promise.delay(10);
new DataLoader(batchLoadFn, { batchSignal: () => batchSignal });

Effectively this would make the batching strategy injectable.

from dataloader.

leebyron avatar leebyron commented on May 3, 2024 2

DataLoader intentionally does not support this because it introduces a floor of latency to all loads which can quickly and unintuitively add up to very slow performance on servers.

Apollo client uses a delayed approach because it is used in an environment where it is common for load operations to be spread across many frames in a short window of time and for ticks to occur very often (~60fps clients), and the data they are loading (graphql queries) are not interdependent thus don't add up latency.

In contrast DataLoader is used in environments (servers) where load operations happen in bursts, where ticks only occur when scheduled, and are very often dependent on other load operations which results in the adding up of latency.

The primary concern is that if you were to define a 10ms interval, that any request to the loader would have to wait 10ms before actually sending. If you have a request dependent on the data of another request dependent on the data of an initial request, then you add up those intervals.

from dataloader.

ericclemmons avatar ericclemmons commented on May 3, 2024

I can work on a PR if the behavior is OK. I just ran into a situation where this would be desirable as well.

from dataloader.

leebyron avatar leebyron commented on May 3, 2024

I would consider a PR which added this, but I think it definitely needs real numbers to prove that it would improve performance and not hurt performance, both to warrant adding the feature and as future guidance of how others should use it.

from dataloader.

ericclemmons avatar ericclemmons commented on May 3, 2024

@leebyron I have a query-heavy (hence DataLoader-heavy) part of my app I can try this on, but I could really use a hint as to where I can swap out the logic & come back with some real metrics.

from dataloader.

leebyron avatar leebyron commented on May 3, 2024

Sure. enqueuePostPromiseJob (https://github.com/facebook/dataloader/blob/master/src/index.js#L208) is what is responsible for scheduling work at the end of the promise queue for the current tick. If you replaced the Promise-queue mechanisms with something like setTimeout you would get the time-based rather than tick-based behavior.

from dataloader.

gajus avatar gajus commented on May 3, 2024

In contrast DataLoader is used in environments (servers) where load operations happen in bursts, where ticks only occur when scheduled

Any suggestions how to trace down whats forcing a tick to happen?

I have this query:

{
  movies(date: "2017-04-06", coordinates: {latitude: 57.149911, longitude: -2.078433}, first: 3) {
    edges {
      node {
        venues(first: 10) {
          edges {
            node {
              events {
                id
              }
            }
          }
        }
      }
    }
  }
}

I am expecting all event records to be fetched in the same query, though instead I am getting hundreds of queries fetching 1-10 events per query.

from dataloader.

leebyron avatar leebyron commented on May 3, 2024

I suggest logging when your upstream promises are being created and when they complete. Sounds like a missed opportunity to batch in a prior set of promises is resulting in those resolving on different ticks and creating separate batches.

from dataloader.

gajus avatar gajus commented on May 3, 2024

For others going the perilous ways of debugging a similar issue: if you are using console.log to debug the issue then you must pipe the program output in order to ensure that it is non-blocking operation. That caused me a bit of confusion.

from dataloader.

sibelius avatar sibelius commented on May 3, 2024

this https://github.com/calebmer/graphql-resolve-batch could help

from dataloader.

Kosta-Github avatar Kosta-Github commented on May 3, 2024

I like the idea of @bman654 here #58 (comment):

I am using a pool of db connections and would like to collect batches as long as all db connections are busy, but as soon as a db connection gets released back into the pool the next batched query should/could start.

that should be doable by using the batchSignal: () => waitForSomeSignalToArrive() approach, right?

from dataloader.

leebyron avatar leebyron commented on May 3, 2024

Closing this issue since time-based intervals are counter to the goals of DataLoader (to reduce latency and load times), but I would definitely suggest building complimentary packages which have these more specific batching strategies. For example, DataLoader's batching function might itself call to an intermediate API that is more aware of the actual database connection state and able to perform its own delayed batching strategies that are optimized for its specific conditions.

from dataloader.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.