Graphql schema probably not suited for parallel execution
See original GitHub issueThis is probably a minor issue as it occurs only on server startup.
I noticed that my django view (with heavy use of relay), when rendered right after django startup, tends to throw a variety of graphql errors. It came out only with relay (that is - when multiple graphql queries were sent one by one).
After diving into the code I think I more or less analyzed the issue. GraphQLView
reuses the same schema (graphene.core.schema.Schema
) for execution. That schema has self._types
dictionary, which is constructed only once.
- When more than one thread interfere during initial
_types
construction,Type {} already registered with other object type
errors are thrown insideregister
method.
That schema also creates graphql.core.type.schema.GraphqlSchema
. I’m not sure how this is possible, as every time schema is accessed, a new instance is created, but here again looks like
- thread interference leads to errors:
Schema must contain unique named types but contains multiple types named {}
intype_map_reducer
function.
Below an example of an error. I don’t paste all of them, but that is a good example, as many of them are related to automatically created Connection types, which, I guess, are created independently by separate threads traversing type tree and, so, are not the same types although they do have the same name (which I checked).
Internal Server Error: /graphql/api/
Traceback (most recent call last):
File "/home/isivi/.local/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/home/isivi/.local/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/isivi/.local/lib/python2.7/site-packages/django/views/generic/base.py", line 62, in view
self = cls(**initkwargs)
File "/home/isivi/.local/lib/python2.7/site-packages/graphene/contrib/django/views.py", line 10, in __init__
schema=schema.schema,
File "/home/isivi/.local/lib/python2.7/site-packages/graphene/core/schema.py", line 90, in schema
subscription=self.T(self.subscription))
File "/home/isivi/.local/lib/python2.7/site-packages/graphene/core/schema.py", line 22, in __init__
super(GraphQLSchema, self).__init__(*args, **kwargs)
File "/home/isivi/.local/lib/python2.7/site-packages/graphql/core/type/schema.py", line 40, in __init__
self._type_map = self._build_type_map()
File "/home/isivi/.local/lib/python2.7/site-packages/graphql/core/type/schema.py", line 89, in _build_type_map
type_map = type_map_reducer(type_map, type)
File "/home/isivi/.local/lib/python2.7/site-packages/graphql/core/type/schema.py", line 129, in type_map_reducer
reduced_map = type_map_reducer(reduced_map, getattr(field, 'type', None))
File "/home/isivi/.local/lib/python2.7/site-packages/graphql/core/type/schema.py", line 129, in type_map_reducer
reduced_map = type_map_reducer(reduced_map, getattr(field, 'type', None))
File "/home/isivi/.local/lib/python2.7/site-packages/graphql/core/type/schema.py", line 129, in type_map_reducer
reduced_map = type_map_reducer(reduced_map, getattr(field, 'type', None))
File "/home/isivi/.local/lib/python2.7/site-packages/graphql/core/type/schema.py", line 129, in type_map_reducer
reduced_map = type_map_reducer(reduced_map, getattr(field, 'type', None))
File "/home/isivi/.local/lib/python2.7/site-packages/graphql/core/type/schema.py", line 121, in type_map_reducer
field_map = type.get_fields()
File "/home/isivi/.local/lib/python2.7/site-packages/graphql/core/type/definition.py", line 194, in get_fields
self._field_map = define_field_map(self, self._fields)
File "/home/isivi/.local/lib/python2.7/site-packages/graphql/core/type/definition.py", line 207, in define_field_map
field_map = field_map()
File "/home/isivi/.local/lib/python2.7/site-packages/graphene/core/classtypes/base.py", line 131, in fields_internal_types
return schema.T(cls._meta.fields_group_type)
File "/home/isivi/.local/lib/python2.7/site-packages/graphene/core/schema.py", line 61, in T
internal_type = _type.internal_type(self)
File "/home/isivi/.local/lib/python2.7/site-packages/graphene/core/types/base.py", line 152, in internal_type
return OrderedDict(self.iter_types(schema))
File "/usr/lib/python2.7/collections.py", line 57, in __init__
self.__update(*args, **kwds)
File "/usr/lib/python2.7/_abcoll.py", line 568, in update
for key, value in other:
File "/home/isivi/.local/lib/python2.7/site-packages/graphene/core/types/field.py", line 182, in iter_types
yield self.get_named_type(schema, field)
File "/home/isivi/.local/lib/python2.7/site-packages/graphene/core/types/base.py", line 146, in get_named_type
return name, schema.T(type)
File "/home/isivi/.local/lib/python2.7/site-packages/graphene/core/schema.py", line 61, in T
internal_type = _type.internal_type(self)
File "/home/isivi/.local/lib/python2.7/site-packages/graphene/core/types/field.py", line 102, in internal_type
type = schema.T(self.get_type(schema))
File "/home/isivi/.local/lib/python2.7/site-packages/graphene/core/schema.py", line 64, in T
self.register(_type)
File "/home/isivi/.local/lib/python2.7/site-packages/graphene/core/schema.py", line 99, in register
type_name)
AssertionError: Type EmployerTypeTileNodeDefaultConnection already registered with other object type
Issue Analytics
- State:
- Created 7 years ago
- Comments:7 (6 by maintainers)
Top GitHub Comments
@ekampf This issue is hard to fix with the current architecture implementation. However I’m assuring that in
1.0
version no problems like that will happen. A testcase that replicates the issue could be very helpful too 😃This parallel execution issue should no longer exist with the current reimplementation (
master
branch,1.0.dev
version in PyPI).Please reopen the issue if the problem is not mitigated when using the dev version.