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

Opentelemetry instrumentation for graphql-batch #457

Closed
toneymathews opened this issue May 9, 2023 · 5 comments
Closed

Opentelemetry instrumentation for graphql-batch #457

toneymathews opened this issue May 9, 2023 · 5 comments
Labels
stale Marks an issue/PR stale

Comments

@toneymathews
Copy link

TL;DR GraphQL Batch is a query batching executor for the GraphQL Ruby gem. It’s used to solve n+1 query problems. As maintainers of GraphQL Batch, we would like to implement tracing so that a shared implementation may be available within open-telemetry/opentelemtry-ruby-contrib.

Defining the problem space and how the gem solves this problem

By default, every field in a GraphQL query is resolved individually on each object, in total isolation. Consider the following GraphQL query, assuming a SQL based data source with pagination omitted for simplicity:

{
  orders(first: 50) {
    customer {
	name
    }
  }
}

On this query, first the orders field is resolved, which generates a SQL query for 50 orders from the database. Then for each individual order, the customer field is resolved, which generates an additional SQL query to load the customer for that order. In total, 51 SQL queries are executed (one to load the orders, and one per order to load the customer). This is an extremely costly way to resolve this data.

GraphQL Batch exposes a GraphQL::Batch::Loader interface. It exposes a #perform method that is used by a custom batch loader such as the CustomerLoader that aggregates the orders and performs a single SQL query.

class CustomerLoader < GraphQL::Batch::Loader
  def perform(orders)
    customer_ids = orders.map(&:customer_id)
    # Query to fetch all customers.
    customers_by_id = Customers.where(id: customer_ids).index_by(&:id)

    orders.each do |order| 
      customer = customers_by_id[order.customer_id]
      fulfill(order, customer)  # For every order, fan out the corresponding customer.
    end
  end
end

Loaders based on GraphQL::Batch::Loader may be generic such as RecordLoader and AssociationLoader or a custom one such as the CustomerLoader above, for a specific purpose.

What we propose

Add a batch loader within open-telemetry/opentelemtry-ruby-contrib that is traced so that a shared implementation is available. The perform method holds code that makes calls to remote data sources. We want to add tracing for the perform method to visualize and measure performance of a batch loader.

If it makes sense to do so, we can add a pull request to add instrumentation for graphql-batch as the next step for further feedback.

@arielvalentin
Copy link
Collaborator

Speaking for myself, adding instrumentation for graphql-batch would be a welcome addition to this repo.

I am looking forward to your contribution!

@github-actions
Copy link
Contributor

github-actions bot commented Jun 9, 2023

👋 This issue has been marked as stale because it has been open with no activity. You can: comment on the issue or remove the stale label to hold stale off for a while, add the keep label to hold stale off permanently, or do nothing. If you do nothing this issue will be closed eventually by the stale bot.

@github-actions github-actions bot added the stale Marks an issue/PR stale label Jun 9, 2023
@arielvalentin
Copy link
Collaborator

@toneymathews Any chance you may have time to work on this?

@github-actions github-actions bot removed the stale Marks an issue/PR stale label Jun 10, 2023
@toneymathews
Copy link
Author

Apologies, I have to prioritize work in other areas and hence will not be able to focus on this piece of work soon.

@github-actions
Copy link
Contributor

👋 This issue has been marked as stale because it has been open with no activity. You can: comment on the issue or remove the stale label to hold stale off for a while, add the keep label to hold stale off permanently, or do nothing. If you do nothing this issue will be closed eventually by the stale bot.

@github-actions github-actions bot added the stale Marks an issue/PR stale label Jul 13, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Dec 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale Marks an issue/PR stale
Projects
None yet
Development

No branches or pull requests

2 participants