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
[BEAM-10545] KernelModel and jest tests #12372
Conversation
yarn.lock is auto-generated by |
Run Python2_PVR_Flink PreCommit |
1. Added a KernelModel module that handles messaging between the frontend and the connected kernel. 2. Integrated jest test framework with typescript. 3. Advanced prettier to 1.19 so that it can parse typescript optional chaining syntax. 4. The tests can be executed with `jlpm jest`. Test details see README. 5. Changes made by jlpm are: jlpm add --dev jest @types/jest ts-jest identity-obj-proxy jlpm upgrade prettier@^1.19.0
Rebased to resolve merge conflicts. |
R: @prodonjs |
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.
No concerns just one small style nit.
}); | ||
} | ||
|
||
private _onIOPub = (msg: KernelMessage.IIOPubMessage): 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.
This is just a nit, but for consistency, I would keep the private method signature the same as the public methods (ie. private _onIOPub(msg: KernelMessage.IIOPubMessage) {...
) as opposed to this syntax which assigns the lambda function to the private data member.
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.
Thanks, Jason! I've made the change to the private field. Additionally, it requires a bind(this)
when assigning the function to the future
.
…ad of arrow function assignment. This requires binding `this` when assigning the function to the `future`.
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
Run Python2_PVR_Flink PreCommit |
R: @aaltay |
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. I do not believe I am a good typescript reviewer. It would be good if you can ask on dev@ and see if there could be better reviewers for future PRs.
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.
Retracting my LGTM, I have some questions.
And a high level question, what is the purpose of this module? (Could you add more details to what you wrote as part of the PR description?)
output_type: 'display_data', | ||
data: { | ||
'text/html': '<div></div>', | ||
'application/javascript': 'console.log(1);' |
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.
What does this console.log's do? Are they executed?
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.
It's a valid Javascript statement that logs to the console.
In the test, if it is executed, the result shows up in the terminal
.
This unit test doesn't do the execution though because it's just a data model not a UI component.
if (dataInPlainText) { | ||
try { | ||
// The slice removes trailing single quotes from the nbformat output. | ||
// The replace removes literal backslashes from the nbformat output. |
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.
it seems to replace a backslash and a quote? \\'
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.
It's removing characters in nbformat texts.
Kernel generates json.
When messaged to frontend by Jupyter in nbformat, the text becomes 'json_with_backslashes'.
This removes the "'" from both ends of the string.
Then removes all the backlashes.
The result text will be a valid json that is parsable.
} | ||
this.future = this._sessionContext.session?.kernel?.requestExecute({ | ||
code: KernelCode.COMMON_KERNEL_IMPORTS + code, | ||
silent: !expectReply, |
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.
If silent is the name of the underlying api, why do we use an oppositely behaving expectReply
flag?
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 problem with silent
is that it's confusing with the existence of store_history
.
Intuitively, if silent
, the kernel execution should not store history. However, it's not that case.
silent
only means if the execution should return a result. The history is stored. The side effects are obvious.
So you will see execution_count increased even when you set silent
to true.
Facading it with expectReply
makes it clear when using the model.
expect(kernelModel.displayData).toEqual([displayData]); | ||
}); | ||
|
||
it('handles display update from IOPub channel', () => { |
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.
what is the difference between display data and display update messages?
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.
Think of display data
as incrementally displaying contents while display update
as modifying contents already displayed.
An example,
- display data is [1, 2 ,3], you'll see 1 2 3 being displayed;
- display update is [1, 2, 3] for a same display_id, you'll see 1, then it becomes 2, then it becomes 3.
The purpose of this module is to allow the extension to execute code in the kernel silently to retrieve information of current interactive environment, then handles IOPub messages sent back from the kernel and allow other components to use this module as a data model. |
Thanks! For typescript review, Jason has agreed to take a look at my future PRs. He is the TL of CAIP notebooks and works on other extensions: https://github.com/GoogleCloudPlatform/jupyter-extensions. |
frontend and the connected kernel. The model silently executes code in the kernel and handles IOPub responses from the kernel for information of the current interactive environment. UI components and other data models can use this module as a data model to communicate with the kernel. When instantiated, this model does not have to be a singleton.
chaining syntax.
jlpm jest
. Test details see README.jlpm add --dev jest @types/jest ts-jest identity-obj-proxy
jlpm upgrade prettier@^1.19.0
Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:
R: @username
).[BEAM-XXX] Fixes bug in ApproximateQuantiles
, where you replaceBEAM-XXX
with the appropriate JIRA issue, if applicable. This will automatically link the pull request to the issue.CHANGES.md
with noteworthy changes.See the Contributor Guide for more tips on how to make review process smoother.
Post-Commit Tests Status (on master branch)
Pre-Commit Tests Status (on master branch)
See .test-infra/jenkins/README for trigger phrase, status and link of all Jenkins jobs.