Skip to content

mixed concrete types with pointer receivers are unsupported.Β #323

@stevvooe

Description

@stevvooe

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:

  1. 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.
  2. 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 {
. It seems to make the assumption that a type can only have a method if it is a pointer type, when it should not care.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions