Skip to content

Instrumentation #27

@tmeasday

Description

@tmeasday

Following up from rmosolgo/graphql-ruby#354 (comment):

@dylanahsmith :

For graphql-batch I would just recommend using Promise.map_value to get the end of the field resolution:

class MyFieldInstrumentation
  def instrument(type, field)
    old_resolve_proc = field.resolve_proc
    new_resolve_proc = ->(obj, args, ctx) {
      Rails.logger.info("#{type.name}.#{field.name} START: #{Time.now.to_i}")
      result = old_resolve_proc.call(obj, args, ctx)
      Promise.map_value(result) do |value|
        Rails.logger.info("#{type.name}.#{field.name} END: #{Time.now.to_i}")
        value
      end
    }

    field.redefine do
      resolve(new_resolve_proc)
    end
  end
end

Actually the above does not work (or at least not in a particularly useful way). The problem is that the executor does not necessarily run the loader associated with the field immediately, instead it may wait for some other loaders (or fields I suppose) to execute first. So the "start time" logged above (when the field is added to the loader), is not really "correct", in terms of the work done to fetch the field.

As an example, if I run a query against our example GitHunt server that looks something like:

{
  entries {
     # this field goes to a batch loader that talks to github
     postedBy
     # this field goes to another github batch loader
     repository
     # this field goes to a simple SQL batch loader
     vote
  }
}

You end up seeing traces that look like:

screenshot 2016-10-28 08 54 09

Note in the above that the start time of all the fields is more or less the same (as the executor runs over the set of entries, and they are all added to the various loaders), and the total time is "cumulative". In actuality the vote loader is more or less instantaneous (running against a local sqlite db in this case), and a correct start time for those fields should really be at the end of the repository loader (so I guess 2.03ms in this SS).


This is why I think for proper instrumentation of the batch loader I think we need to know two things:

  1. What time a loader actually starts.
  2. Which fields the loader is running for.

The first part is trivial I suppose, but the second seems tricky.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions