Replies: 6 comments 9 replies
-
|
More of a +1 than an answer, but we ran into a similar issue at Twitter, primarily around the copy/map behavior over each instrument within a
The catch to this is that this only works for instrumentations that do no state management (i.e. return a It would be great to start a discussion around what would make sense from a graphql-java perspective. There would likely be some sort of breaking API change involved, but it would be great if we had the ability to differentiate between something that is side-effecting without state (i.e. update a metric) vs something that requires managed state via the Thanks, |
Beta Was this translation helpful? Give feedback.
-
|
I will get back to you on this idea of passing state direct (rather than via a copied "parameters" object later. But
graphql-java has a two mechanisms for presenting different fields to consumers. If you can pre categorize your consumers into static "sets" then you can use There is also a |
Beta Was this translation helpful? Give feedback.
-
|
Ok I looked into this more and its makes sense. The goal of the "new parameters with state" really so that the called instrumentation method could do But I can see how it makes sense to avoid object allocation for this at scale. Of course this is ONLY a problem at scale. Most systems would not notice this cost I think. To confirm the breaking API change would be
Perhaps an idea to lessen impact is to only change the methods that get called a lot (field ones versus singleton ones like The other object allocation (that might be much harder to avoid) is the This delegates to N underlying This is tricky to avoid because you need hold each different one so it can be invoked. Even if we had some "marker interface" say which said it a "simple" instrumentation call, you still need some allocation for ones that are not that. And allocating a list of 2 is about the same cost as any other list. |
Beta Was this translation helpful? Give feedback.
-
|
@treverj / @enbnt -for reference - who many instrumentations are you running here. That gives the factor Also what instrumentations from graphql-java do you use and what ones are custom? |
Beta Was this translation helpful? Give feedback.
-
|
I created a Spike PR (which is pretty much the PR that was submitted but tweaked) to show how we could make this change in a non API breaking way |
Beta Was this translation helpful? Give feedback.
-
|
I had this idea recently if we added new Instrumentation methods (and deprecated the old) re: from #2747 The new shape would be this default @Nulllable InstrumentationContext<Object> beginFieldFetch(InstrumentationFieldFetchParameters parameters, InstrumentationState state) {
// calls back to old behavior always
return beginFieldFetch(parameters.withNewState(state));
}That is the state gets passed in (and hence no object allocation for changing the "parameters" and the return So instrumentations that don't want any callback would return null, also avoiding an object allocation. They can still be called in a chain (which would be very much like your The impact on our code would be we need to "handle" null in all the places that call back but I think this would be ok. (We can do a trick like |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
First of all I want to thank you for a fantastic library which has made our move to providing a GraphQL based API immeasurably simpler.
We have been investigating some performance problems with our API, which we suspect to be at least in part down to
prodigious object allocation within graphql-java.
The graphql-java Instrumentation framework allocates a new instance of InstrumentationXXXParameters for each subject it
visits, and for each Instrumentation registered when using ChainedInstrumentation. When using the field-level
instrumentation, these allocations contribute to a significant amount of memory pressure on the application when it is
under load. In our specific case, these newly-allocated objects aren't used at all, so the allocation is completely
wasteful.
The reason for the new allocation in ChainedInstrumentation is to pass along the correct state to the new subject. As a
proof-of-concept, we altered the signature of the Instrumentation::beginField, Instrumentation::beginFieldFetch and
Instrumentation::instrumentDataFetcher methods to accept both a InstrumentationFieldParameters and an
InstrumentationState, and removed the InstrumentationState member from InstrumentationFieldParameters. Along with code
changes to pass the state object along appropriately, this enabled us to avoid these problematic allocations.
Without changes: 4.48 TB of total allocations during a performance test
After changes: 3.61 TB of total allocations during a performance test
More specifically:
We realise that this dramatic and incompatible change to a key API is most likely not the appropriate solution to this
problem. As non-experts in both the graphql-java codebase and its design, would appreciate some assistance with
deriving a more appropriate design that might have a chance of being accepted as a PR.
Example PR: #2742
It is also entirely possible that we are mis-using the Instrumentation API here. Our primary motivations for using it
are that we are a multi-tenanted e-commerce platform provider, with some clients having bespoke features that only apply to them, and others having a wide array of features not enabled for their site. To simplify the schema significantly, we have created a new set of directives and instrumentation called SchemaHidingInstrumentation to enabled and disable the fields we want to hide from the schema. For introspections queries, this wraps the data fetcher to hide/remove fields from the schema and for queries or mutations that attempt to use these fields, we return a fixed "Field not available error". We also use this to remove fields we are trialing through experiments or gradual roll outs.
If there's a more sensible way to achieve our goals here, we'd be happy to hear about it.
Thanks,
James
Beta Was this translation helpful? Give feedback.
All reactions