-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Application freeze at startup with many errors in RPC system #11249
Comments
Likely a symptom of similar issues:
console.log('SENTINEL FOR SETTING THE CURRENT SESSION', current);
|
@tortmayr, any plans to tackle this one? It seems that logging almost any non-primitive object produces the |
@colin-grant-work I'm looking into this right now. At first glance it looks like we have to tackle two issues here:
|
About the circular structures: we should be able to just keep a stack of objects being serialized (IMO). Max depth would be the depth of the object tree. Am I correct to assume that circular structures were rejected as an error even before? |
Partly. I did some testing on 53a272e. When trying to sent a non-serializable object over the wire (e.g. ciruclar structure) JSON.stringify inside the WebSocketMessageWriter throws an error which is catched immediately. This means the log RPC call is never sent to the "other" side (i.e. the backend) but the promise is not rejected either. It just remains unresolved. Since the console.log API is synchronous anyways nobody is awaiting promise resolution and it doesn't matter that these promises remain unresolved. So to sum up, frontend console.log calls with non-serializable arguments had the following behavior with the old protocol (53a272e):
Whereas with the new protocol
IMO the if the log RPC call fails the promise should definitely. We could implemented some rejection handling to achieve the same behavior as before. However, this also raises the question why we sent log calls as requests in the first place. Would it make more sense to send log RPC calls as plain notifications? This would also reduce the overall load on the websocket connection because we don't have to send back unnecessary void request responses.
I'm not sure if I follow. Could you elaborate on this? How would one be able to identify the depth of the object tree in a circular structure? |
Might we be able to borrow from Node's object serialization routine? The Node REPL and > const a = {};
undefined
> const b = {};
undefined
> a.b = b;
{}
> b.a = a;
<ref *1> { b: { a: [Circular *1] } }
> b
<ref *1> { a: { b: [Circular *1] } } I think the ref identification is relatively new; older versions just had const a = {};
// --> undefined
const b = {};
// --> undefined
b.a = a;
// --> {}
a.b = b;
// --> {a : {…}}
const c = new Set();
// --> undefined
const replacer = (key, value) => {
if (c.has(value)) { return '[Circular]'; }
if (typeof value === 'object' && value) {
c.add(value);
}
return value;
}
// --> undefined
JSON.stringify(a, replacer);
// --> '{"b":{"a":"[Circular]"}}' |
There are really only two cases: either the graph of object references we serialize has a loop or it does not. If it does no, everything is "fine": even if we use the same object twice in the graph being serialized, we can successfully compute serialized version. We will just end up with multiple copies of the object. |
@colin-grant-work it would be nice to be able to serialize circular structures. I would suggest, however, that we do this as a follow-up improvement. My thinking is that we're trying to restore the behavior as it was before moving to the new serialization as soon as possible. |
I see. Thanks for the explanation.
I agree, we should aim at restoring the original behavior as soon as possible and handle potential serialization of circular structures in a follow up PR. Maybe we can do this as part of #11159. Part of this task is also to evaluate whether we can/should replace the custom binary codec with a third party library (https://msgpack.org/index.html). Some msgpack implementations are also able to fully serialize ciruclar structures. I have recently played around with msgpackr. Here the author claims that enabling the support for circular structrures will decrease the overall performance by 25-30 %. So I'd exepct that we will encounter similar performance degrations if we implement circular reference support in our custom binary codec. |
@tortmayr I would be greatly in favor of this. I'm not too sure whether theia/dev-packages/request/src/common-request-service.ts Lines 89 to 106 in fb13143
|
@msujew not quite sure how the issues are related: whether we need to string-encode buffers depends on how we interpret request data (binary or text), not on the particulars of the encoding engine. What am I missing? |
@tsmaeder Well, yes and no. Even when encoding the buffer in binary, we usually lose the type information, which leaves the Also, why reinvent the wheel if there already is a perfectly usable lib for our usecase? |
I still don't get it: by "typing" you mean whether it's a |
@tsmaeder You're probably right, using a custom encoder would be the right approach for this. |
- Refactor `RPCMessageEncoder` to enable detection of circular object structures. Circular structures can not be serialized. The detection enables us to fail early instead of indirectly failing once the maximum stack frame limit is reached. - Add a custom encoder for functions. This ensures that direct function entries in arrays can be serialized. - Add custom encoder for common collection types (maps, sets). Enables direct use of collection types as rpc call arguments (e.g. logging statements) - Restore behavior of the old protocol if a log RPC call can not be sent to the backend due to an encoding error - Add custom `EncodingError` type to explicitly catch these errors - Refactor `loggerFrontendModule` to catch encoding errors and continue execution normally. i.e. log call is just logged in frontend console and not sent to backend Fixes eclipse-theia#11249 Contributed on behalf of STMicroelectronics
- Refactor `RPCMessageEncoder` to enable detection of circular object structures. Circular structures can not be serialized. The detection enables us to fail early instead of indirectly failing once the maximum stack frame limit is reached. - Add a custom encoder for functions. This ensures that direct function entries in arrays can be serialized. - Add custom encoder for common collection types (maps, sets). Enables direct use of collection types as rpc call arguments (e.g. logging statements) - Restore behavior of the old protocol if a log RPC call can not be sent to the backend due to an encoding error - Add custom `EncodingError` type to explicitly catch these errors - Refactor `loggerFrontendModule` to catch encoding errors and continue execution normally. i.e. log call is just logged in frontend console and not sent to backend Fixes eclipse-theia#11249 Contributed on behalf of STMicroelectronics
- Refactor `RPCMessageEncoder` to enable detection of circular object structures. Circular structures can not be serialized. The detection enables us to fail early instead of indirectly failing once the maximum stack frame limit is reached. - Add a custom encoder for functions. This ensures that direct function entries in arrays can be serialized. - Add custom encoder for common collection types (maps, sets). Enables direct use of collection types as rpc call arguments (e.g. logging statements) - Restore behavior of the old protocol if a log RPC call can not be sent to the backend due to an encoding error - Add custom `EncodingError` type to explicitly catch these errors - Refactor `loggerFrontendModule` to catch encoding errors and continue execution normally. i.e. log call is just logged in frontend console and not sent to backend Fixes eclipse-theia#11249 Contributed on behalf of STMicroelectronics
- Refactor `RPCMessageEncoder` to enable detection of circular object structures. Circular structures can not be serialized. The detection enables us to fail early instead of indirectly failing once the maximum stack frame limit is reached. - Add a custom encoder for functions. This ensures that direct function entries in arrays can be serialized. - Add custom encoder for common collection types (maps, sets). Enables direct use of collection types as rpc call arguments (e.g. logging statements) - Restore behavior of the old protocol if a log RPC call can not be sent to the backend due to an encoding error - Add custom `EncodingError` type to explicitly catch these errors - Refactor `loggerFrontendModule` to catch encoding errors and continue execution normally. i.e. log call is just logged in frontend console and not sent to backend Fixes eclipse-theia#11249 Contributed on behalf of STMicroelectronics
I have opened a PR that should fix the issue and restores the behavior of the "old" protocol in regards to logging circular structures. As discussed any other improvements i.e. the ability to fully serialized circular structures will be tackled in a follow-up as part of #11159. |
* Improve RPC message encoding - Refactor `RPCMessageEncoder` to enable detection of circular object structures. Circular structures can not be serialized. The detection enables us to fail early instead of indirectly failing once the maximum stack frame limit is reached. - Add a custom encoder for functions. This ensures that direct function entries in arrays can be serialized. - Add custom encoder for common collection types (maps, sets). Enables direct use of collection types as rpc call arguments (e.g. logging statements) - Restore behavior of the old protocol if a log RPC call can not be sent to the backend due to an encoding error - Add custom `EncodingError` type to explicitly catch these errors - Refactor `loggerFrontendModule` to catch encoding errors and continue execution normally. i.e. log call is just logged in frontend console and not sent to backend Fixes #11249 Contributed on behalf of STMicroelectronics * Address review feedback - Remove default value for `visitedObjects` parameter - Move circular reference check from the `object` value encoder into `wirteTypeValue` to ensure that all the ciruclar reference check is applied on all object references
Bug Description:
Starting the application in the browser, I got stuck at the loading screen for 2-3 minutes with numerous errors logged in various parts of the new IPC system. (@tortmayr, @JonasHelming)
Steps to Reproduce:
console.log
that produces numerous rapid logs (ca. 100 or so in a tick), possibly involving non-stringifiable types (Map
, e.g.).Additional Information
The text was updated successfully, but these errors were encountered: