-
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
Update JSON-RPC #10265
Update JSON-RPC #10265
Conversation
938a78d
to
5d5613c
Compare
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.
Those changes go in the right direction, but I think we should rather look into replacing vscode-ws-jsonrpc
by a in-repo alternative that we can maintain. This should simplify our consumption of vscode-jsonrpc
at the same time. cc @eclipse-theia/core
I would tend toward in-sourcing this code: I believe the newest version of vscode-jsonrpc actually has support for sockets/ipc, etc. We would be better served maintaining the bit of glue code needed ourselves. |
058d32c
to
db3b907
Compare
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.
Code looks good, in general, but need to test.
I went ahead and pushed commits that replace occurrences of |
@paul-marechal, would you to / like me to see about removing some of the code copied from |
67c2e87
to
95f96b4
Compare
Rebased on master. I tried to untangle what I could with regards to our logical channels over websockets, as well as this weird IIUC From there, I simply made helper methods to get both I don't think I looked at everything @colin-grant-work touched, as I only focused on the core messaging systems. |
No longer depending on vscode-ws-jsonrpc
.
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 started testing this PR. Most of it looks good, however I can't seem to start a debug session with the vscode-js-debug
extension. The debug session does not start in the frontend and I get the following error:
Uncaught (in promise) SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse (<anonymous>)
at PluginDebugAdapterSession.write (/workspace/theia/packages/plugin-ext/lib/plugin/node/debug/plugin-debug-adapter-session.js:67:52)
ccf894b
to
f83c04a
Compare
@msujew good catch, this is now fixed. There is still an error being thrown when stopping the session but it already happens on master so that makes it out of scope for this PR. |
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 couldn't find any more regressions introduced by the changes. Besides the one remark the code looks good to me as well.
Anyway, I'll let others review/test this as well before actually approving.
55f7b0f
to
41f377c
Compare
@colin-grant-work @tsmaeder I rebased and finalized those changes. @tsmaeder looking at all this code made me conclude that something is off regarding the way messaging is handled with plugins... Mostly I don't really understand the use of theia/packages/plugin-ext/src/common/plugin-message.ts Lines 19 to 28 in 41f377c
theia/packages/plugin-ext/src/common/connection.ts Lines 66 to 76 in 41f377c
It really feels like we are shoehorning this custom protocol down the poor Please tell me if I misunderstood anything. |
79788be
to
8d67a60
Compare
@tsmaeder, it seems like there's some overlap between the work here and the work you've been doing on the debug system. Would you mind taking a look at this so we can merge if appropriate, and you can then use some of the new messaging equipment in your PR? |
// Extract the cancellation token if it is the last argument passed to the method to call over JSON-RPC. | ||
let token: CancellationToken | undefined; | ||
if (CancellationToken.is(args[args.length - 1])) { | ||
token = args.pop(); | ||
} | ||
// Convert the list of arguments into a structure that allows us to conserve undefined values. | ||
const params: any[] = this.createJsonRpcParameters(args); | ||
// Push back the token if there was one. | ||
// `vscode-jsonrpc` will remove the `CancellationToken` out of `params` when is is the last element. | ||
if (token) { | ||
params.push(token); | ||
} |
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.
We could get rid of this logic if we assumed nobody should design their APIs over RPC using undefined params.
The createJsonRpcParameters
method is a mechanism to properly propagate undefined
parameters over JSON-RPC, because undefined
values cannot be transmitted verbatim over JSON.
e.g. JSON.stringify(['a', undefined, 2])
returns '["a",null,2]'
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.
To me it's not really clear what the motivation for these here changes are: is this fixing a known bug? If yes, which one?
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.
Like I mentioned, undefined
values are transformed into null
without the type system knowing.
theia/packages/plugin-ext/src/main/common/plugin-paths-protocol.ts
Lines 24 to 25 in 8bf15dc
/** Returns storage path for given workspace */ | |
getHostStoragePath(workspaceUri: string | undefined, rootUris: string[]): Promise<string | undefined>; |
Here workspaceUri
is actually string | null
when used over RPC. We got "lucky" here as the only implementation checks for truthiness to detect the type rather than some workspaceUri === undefined
which would not work.
One solution would be for interfaces meant to be used over RPC to almost never use undefined
in their API.
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 really wish we could have done the changing of the imports to 'vscode-languageserver-protocol' in a separate PR: 88 files is very big when "real changes" are insterspersed with just changed imports.
The only real change I'm requesting is the renaming of TheiaMessagingConnection
: I just find the name very confusing. There are many things in this area of code that I disapprove of, but they were there before so 🤷 .
In the long run, I would like to get rid of jsonrpc anyway: we already have a remote proxy invocation framework in our code and I don't think we need two: the only thing I can see missing is the ability to read partial messages, but that could quite simply be retrofitted.
* This is close to `vscode_jsonrpc.MessageConnection` but without all the JSON-RPC | ||
* specific methods such as `sendRequest`, `sendNotification`, etc. | ||
*/ | ||
export interface TheiaMessageConnection extends Disposable { |
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.
The name of this interface suggests that it is a special kind of MessageConnection, which is simply not the case. This makes it hard to understand the related code.
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.
Why not just simply keep it as IConnection
? It's just as non-descriptive, but at least not misleading ;-)
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.
Since its job is to forward messages, how about RPCMessageRelay
?
// Extract the cancellation token if it is the last argument passed to the method to call over JSON-RPC. | ||
let token: CancellationToken | undefined; | ||
if (CancellationToken.is(args[args.length - 1])) { | ||
token = args.pop(); | ||
} | ||
// Convert the list of arguments into a structure that allows us to conserve undefined values. | ||
const params: any[] = this.createJsonRpcParameters(args); | ||
// Push back the token if there was one. | ||
// `vscode-jsonrpc` will remove the `CancellationToken` out of `params` when is is the last element. | ||
if (token) { | ||
params.push(token); | ||
} |
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.
To me it's not really clear what the motivation for these here changes are: is this fixing a known bug? If yes, which one?
* | ||
* @deprecated since 1.19.0 | ||
*/ | ||
export const PluginWebSocketChannel = PluginChannel; |
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 not sure we need a deprecation cycle here: it's not "official" API and I doubt someone actually used this implementation detai.
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 very fine with that, will remove.
*/ | ||
export class PluginWebSocketChannel implements IWebSocket { | ||
constructor(protected readonly connection: PluginConnection) { } | ||
export class PluginChannel implements Channel<string> { |
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.
We're wrapping a string channel around a json rcp connection which wraps a string channel. That does not really make sense, IMO. I got rid of that all in #10333. So I wouldn't sweat the small stuff here.
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 did what I must to get it to compile as before, I'd be more than happy to merge #10333 after this!
callback(params, connection); | ||
}); | ||
} | ||
|
||
forward(spec: string, callback: (params: MessagingService.PathParams, connection: IConnection) => void): void { | ||
forward(spec: string, callback: (params: MessagingService.PathParams, connection: TheiaMessageConnection) => void): void { |
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 this even ever used? I didn't find any usages.
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.
Not anymore but despite the amount of changes in this PR I tried to only touch what was broken/bad.
This method is not bothering anyone so I'd keep it for now :)
@colin-grant-work do we need more testing on this PR? |
@tsmaeder, more testing never hurts. It seems that @msujew was happy with his last run through, and I haven't noticed any problems, but you may be aware of use cases that we're not hitting. |
8d67a60
to
e179450
Compare
e179450
to
7bea6ab
Compare
Btw: does the new version help with #9514? |
@tsmaeder, I haven't checked, but it would surprise me if it had much effect on the performance - I don't think there was that much extraneous code running before, and I don't think there's much less now. We still have to JSON-ify everything and send it over the wire (short or long) to the other end. There's a little bit of argument processing on our side and in the package, and that certainly adds a little overhead, but I don't think that's changed much. Someone please bring in a performance tracer and correct me :-). |
7bea6ab
to
9ed38a1
Compare
@colin-grant-work @paul-marechal I assume a rebase is in order due to #10333. I would retest this afterwards and approve if possible. We'd have a few weeks after merging to find possible regressions before the next release. |
Updates to latest version of vscode-languageserver-protocol Removes vscode-monaco-jsonrpc dependency Replaces references to vscode-languageserver-types with references to vscode-languageserver-protocol Refactors existing code to match new interfaces Co-authored-by: Paul Maréchal <[email protected] Co-authored-by: Colin Grant <[email protected]>
5ab667d
to
96a7521
Compare
I'm going to close this for now, since it looks like there's more interest in rewriting our message layer than in updating this package. |
What it does
Fixes #10264 by switching to use a fork of
vscode-ws-jsonrpc
that has been updated to supportvscode-jsonrpc@6
.I could use some help, though, as I'm not very familiar with all of the details of the JSON RPC system. I'll make some comments pointing to the places where I'm uncertain of the right move.
How to test
Review checklist
Reminder for reviewers