Closed ZvikaZ closed 2 weeks ago
When you use arg, it may trigger the async pipeline, hence your class method is called asyncronusly, after the sync one and the next tick of the event loop.
The code I wrote is a toy example. In my real world code, there are 50,000 instances of parent
.
I see in the logs 50K calls to f2
and f3
, which span over 3 seconds, and only then f1
starts.
However, f1
calculation takes 5 seconds, and is the bottleneck of the query, causing it to take ~8 seconds.
If f1
started together with f2
and f3
, I could have saved those 3 seconds, and the query would have taken only ~5 seconds.
Is there something that could be done to improve this situation?
Is it normal that it takes 3 seconds just to span all 50*2K FieldResolver
s? Or maybe it indicates that something is wrong with my code?
Yes, it is normal that processing large amount of data takes some time. If they are synchronous operations, you would have no benefit or processing the f1 before or at the same time.
Well, I've mentioned f1 calculation
, but it wasn't accurate term - it should have been f1 evaluation
. Most of these operations are accessing DBs.
Anyway, I've bypassed this by removing the args
from f1
(and hardcoding the desired values to f1
), and indeed, it helped. It's a workaround for now, but not very scalable...
It'd be great if you consider fixing this. (or at least, letting know if a PR is welcomed, if someone will want to address this).
I'm afraid that's how node.js works. If you have sync operations pending, async promise callback is not executed until the job is finished. TypeGraphQL have middlewares, auth guards, args validations, etc. so that's why it needs the async pipeline for field resolvers with args. Do you use args validation?
Maybe you can try to speed up scheduling db calls by wrapping the sync field resolvers with setImmediate
so it goes to the event loop queue and gives a chance to execute the f1 field resolver.
I'm not using args validation.
I will try using setImmediate
, thanks for the advice!
Regarding the time that it takes to spawn all the fieldresolvers, I've mentioned earlier that it takes 3 seconds.
Meanwhile, I've tried with other query, that added more fields that are resolved by the regular query
, before calling the fieldresolvers. The strange thing is that now spawning the same 3 fieldresolves for the same 50K instances takes about 6 seconds, twice than before.
Any suggestions how can I improve this?
Describe the Bug I have a
Resolver
with 3FieldResolver
s. In the query I call theResolver
twice. If all theFieldResolvers
are withoutargs
, I see the 3FieldResolver
s called one after other, and then again - which makes perfectly sense to me - let's finish with one query, with all its fields, and then the next query. However, if one of theFieldResolver
hasargs
, I see the other twoFieldResolvers
called, twice, and only then the lastFieldResolver
will be called at the end.To Reproduce
With the query:
Expected Behavior I expected to see in the logs execution of
f1
,f2
andf3
(maybe in some other order), and then again the three of them.Instead, we see
f2
andf3
, and then againf2
andf3
, and only thenf1
(twice)Logs Problem:
If I remove the
args
, I get the expected result:Environment (please complete the following information):
Additional Context I have checked it with pure GraphQL, without type-graphql, and I don't see this problem. It's interesting (even thought I'm not sure relevant), that it's a third behavior (
f1
is together withf2
andf3
, but secondparent
is only after all first query has finished).That's the pure GraphQL log:
Thanks.