-
Notifications
You must be signed in to change notification settings - Fork 490
Description
I have a resolver returning a list of resolvers like this:
type resolver struct {}
func (r *resolver) Foos() ([]fooResolver, error) {
// ... implementation
}
type fooResolver struct{}
func (r *fooResolver) ID() graphql.ID
When I try to query with the schema above, I get an error like this:
parsing scheme: resolver.projectResolver does not resolve "Foo": missing method for field "id" (hint: the method exists on the pointer type)
returned by (*resolver.resolver).Foos
The code mapping these types shouldn't care whether or not there is a pointer when validating if a type implements an interface. Since my resolvers are shallow types, leaving them concrete in the struct will reduce pointer lookups. However, I'd like to use a pointer receiver on these methods to avoid the copy for each method.
To make this code work with a pointer receiver, I'd have to return a slice of pointers, which doesn't really make a whole lot of sense, unless there is expense to copying the type or they are shared in some way.
There are two points of inefficiency:
- When creating a slice of pointers, we now have an allocation for each member of the slice, as well as the slice allocation. There should only be a single allocation for a shallow resolver type when creating a slice.
- Additional cache pressure on the unnecessary layer of pointer lookups.
While these seem like small issues, they can contribute to performance problems by generating additional allocations and slow performance on cache line misses.
It looks like the issue is
| if findMethod(reflect.PtrTo(resolverType), f.Name) != -1 { |