-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AER: include encodedTraces
only once to prevent duplicates
#2040
Conversation
When there are multiple instances of apollo-engine-reporting, the `Trace.encode` method gets wrapped each time to add the `encodedTraces`. In order to prevent them from being added to the protobuf multiple times, we remove the encodedTraces after adding them once
encodedTraces
only once to prevent duplicates
Great catch! Can you explain what you mean by multiple copies of apollo-engine-reporting? Like multiple versions loaded into the same app? I don't think this fix is quite right. Trace.encode shouldn't mutate its receiver — you should be able to call it multiple times and get the same answer. The fix is kind of like treating a symptom rather than a cause. The cause is that Trace.encode is getting wrapped multiple times. Let's prevent that directly instead of trying to work around the fact that it's happened. eg, we can set an "already wrapped" flag on Trace.encode and not re-wrap it if it's there. Or (depending on exactly why the issue occurs — as mentioned above I don't quite understand it) perhaps moving this hacky wrapper into apollo-engine-reporting-protobuf could help? (Or of course we could always move this functionality directly into protobufjs with a PR!) |
@glasser Great point! We should make this a solution to the problem rather than a treatment of symptoms. Yes we have multiple copies loaded into the app, one at the root and another as a dependency of This leads to a stack trace like, where the top is I'll take a look at adding this to |
To enable incrmental compilation of traces, we add a patch to the Trace.encode method generated by protobujs to accept and store encoded traces. Occassionally with multiple instances of apollo-engine-reporting that share the same version of the protobuf, the wrapper method gets applied more than once. In order to ensure that the wrapper only gets applied once, we patch the Trace.encode method inside of apollo-engine-protobuf. tsc hangs on the processing the generated protobuf.js files, so the tsconfig.json ignores the generated protobuf file. In order for the typescript index.ts file to compile the generated protobuf.js file is output to the src folder. To ensure the protobuf files are available to the production build, `npm run compile` copies the protobuf file manually from src to dist.
This is perhaps the wrong repo for this question, but is having three copies of AER (including an ancient one in |
@@ -0,0 +1,2 @@ | |||
protobuf.d.ts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't these files in src
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They're generated to be in src
when apollo-engine-reporting-protobuf
is npm prepare
d. I think it's better that the reports.proto
file is the source of truth and we exclude all protobuf.d.ts
. Are you suggesting that we should be excluding src/protobuf.d.ts
rather than all protobuf.d.ts
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think it would make sense to be more explicit about the specific file you're excluding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious why reports.proto
wouldn't move into this newly introduced src
directory?
As a general principle, I find it strange that protobuf.d.ts
(or anything) inside the src/
tree is Git ignored or generated. The previous implementation here didn't violate that expectation since everything was generated into dist/
.
return writer; | ||
}; | ||
|
||
export * from './protobuf'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that really how it works? A brand new reference to ./protobuf'
rather than the already imported protobuf
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -17,27 +17,6 @@ import { | |||
GraphQLServiceContext, | |||
} from 'apollo-server-core/dist/requestPipelineAPI'; | |||
|
|||
// Override the generated protobuf Traces.encode function so that it will look |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that there is a reference to this comment later where encodedTraces is written which should be updated to point to the other file.
`export * from './protobuf'` exports the unmodified reference
@glasser I don't think that having multiple copies is a huge issue. I believe with Ideally, I'd like to remove the |
The override now occurs inside of apollo-engine-reporting-protobuf due to the case of having multiple reporting challenges, so we need to update the comments to help indicate that
Re my concern about |
return writer; | ||
}; | ||
|
||
export = protobuf; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've seen this syntax before, but you are more familiar with modern TS/JS than me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the TypeScript way of expressing module.exports = protobuf
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This final approach is certainly superior to the monkey-patching we were doing before, so I'm very glad to see this getting in.
While I'll Approve this to move it along, I'm fairly curious what the temptation was to introduce TypeScript since the only TypeScript lingua being used is export =
— i.e. module.exports =
.
It seems that introduction may now be the reason that we now have a tsc
compilation step, a generated protobuf in src
(which is directly copied to dist
) and other exceptions which could just have been a thin .js
wrapper?
return writer; | ||
}; | ||
|
||
export = protobuf; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the TypeScript way of expressing module.exports = protobuf
.
@@ -0,0 +1,2 @@ | |||
protobuf.d.ts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious why reports.proto
wouldn't move into this newly introduced src
directory?
As a general principle, I find it strange that protobuf.d.ts
(or anything) inside the src/
tree is Git ignored or generated. The previous implementation here didn't violate that expectation since everything was generated into dist/
.
"outDir": "./dist" | ||
}, | ||
"include": ["src/**/*"], | ||
"exclude": ["src/protobuf.d.ts", "src/protobuf.js"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this is wishful thinking on my part, but this exclude
line is now a unique exception within this entire monorepo since with one other exception — which we're trying to get away from in order to align them all. I'd somewhat rather we not have exclude
be a new type of exception.
In order to simplify the generation of this library, we move the change the index.ts file into index.js and remove the typescript build step. Since the type safety is created by the protobufjs generation, this seems acceptable. In general this portion of the code should remain relatively stable, so generating and copying the code with `prepare` remains reasonable.
I'm gonna let Jesse take the reins for shepherding this one out — he's much more in tune with how we write code in this repo than me! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks for working on this!
This has been released in |
When there are multiple instances of apollo-engine-reporting, the
Trace.encode
method gets wrapped each time to add theencodedTraces
. In order to prevent them from being added to theprotobuf multiple times, we remove the
encodedTraces
after adding themonce.
Ran into this during Engine dogfooding 🌮:dog: 🎉
TODO: