@jupyterlab/services
Version:
Client APIs for the Jupyter services REST APIs
356 lines • 10.9 kB
JavaScript
"use strict";
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.SessionConnection = void 0;
const signaling_1 = require("@lumino/signaling");
const __1 = require("..");
const restapi_1 = require("./restapi");
const coreutils_1 = require("@lumino/coreutils");
/**
* Session object for accessing the session REST api. The session
* should be used to start kernels and then shut them down -- for
* all other kernel operations, the kernel object should be used.
*/
class SessionConnection {
/**
* Construct a new session.
*/
constructor(options) {
var _a, _b, _c, _d;
this._id = '';
this._path = '';
this._name = '';
this._type = '';
this._kernel = null;
this._isDisposed = false;
this._disposed = new signaling_1.Signal(this);
this._kernelChanged = new signaling_1.Signal(this);
this._statusChanged = new signaling_1.Signal(this);
this._connectionStatusChanged = new signaling_1.Signal(this);
this._pendingInput = new signaling_1.Signal(this);
this._iopubMessage = new signaling_1.Signal(this);
this._unhandledMessage = new signaling_1.Signal(this);
this._anyMessage = new signaling_1.Signal(this);
this._propertyChanged = new signaling_1.Signal(this);
this._id = options.model.id;
this._name = options.model.name;
this._path = options.model.path;
this._type = options.model.type;
this._username = (_a = options.username) !== null && _a !== void 0 ? _a : '';
this._clientId = (_b = options.clientId) !== null && _b !== void 0 ? _b : coreutils_1.UUID.uuid4();
this._connectToKernel = options.connectToKernel;
this._kernelConnectionOptions = (_c = options.kernelConnectionOptions) !== null && _c !== void 0 ? _c : {};
this.serverSettings =
(_d = options.serverSettings) !== null && _d !== void 0 ? _d : __1.ServerConnection.makeSettings();
this.setupKernel(options.model.kernel);
}
/**
* A signal emitted when the session is disposed.
*/
get disposed() {
return this._disposed;
}
/**
* A signal emitted when the kernel changes.
*/
get kernelChanged() {
return this._kernelChanged;
}
/**
* A signal proxied from the connection about the kernel status.
*/
get statusChanged() {
return this._statusChanged;
}
/**
* A signal proxied from the kernel about the connection status.
*/
get connectionStatusChanged() {
return this._connectionStatusChanged;
}
/**
* A signal proxied from the kernel pending input.
*/
get pendingInput() {
return this._pendingInput;
}
/**
* A signal proxied from the kernel about iopub kernel messages.
*/
get iopubMessage() {
return this._iopubMessage;
}
/**
* A signal proxied from the kernel for an unhandled kernel message.
*/
get unhandledMessage() {
return this._unhandledMessage;
}
/**
* A signal proxied from the kernel emitted for any kernel message.
*
* #### Notes
* The behavior is undefined if the message is modified during message
* handling. As such, it should be treated as read-only.
*/
get anyMessage() {
return this._anyMessage;
}
/**
* A signal emitted when a session property changes.
*/
get propertyChanged() {
return this._propertyChanged;
}
/**
* Get the session id.
*/
get id() {
return this._id;
}
/**
* Get the session kernel connection object.
*
* #### Notes
* This is a read-only property, and can be altered by [changeKernel].
*/
get kernel() {
return this._kernel;
}
/**
* Get the session path.
*/
get path() {
return this._path;
}
/**
* Get the session type.
*/
get type() {
return this._type;
}
/**
* Get the session name.
*/
get name() {
return this._name;
}
/**
* Get the model associated with the session.
*/
get model() {
return {
id: this.id,
kernel: this.kernel && { id: this.kernel.id, name: this.kernel.name },
path: this._path,
type: this._type,
name: this._name
};
}
/**
* Test whether the session has been disposed.
*/
get isDisposed() {
return this._isDisposed;
}
/**
* Update the session based on a session model from the server.
*
* #### Notes
* This only updates this session connection instance. Use `setPath`,
* `setName`, `setType`, and `changeKernel` to change the session values on
* the server.
*/
update(model) {
const oldModel = this.model;
this._path = model.path;
this._name = model.name;
this._type = model.type;
if ((this._kernel === null && model.kernel !== null) ||
(this._kernel !== null && model.kernel === null) ||
(this._kernel !== null &&
model.kernel !== null &&
this._kernel.id !== model.kernel.id)) {
if (this._kernel !== null) {
this._kernel.dispose();
}
const oldValue = this._kernel || null;
this.setupKernel(model.kernel);
const newValue = this._kernel || null;
this._kernelChanged.emit({ name: 'kernel', oldValue, newValue });
}
this._handleModelChange(oldModel);
}
/**
* Dispose of the resources held by the session.
*/
dispose() {
if (this.isDisposed) {
return;
}
this._isDisposed = true;
this._disposed.emit();
if (this._kernel) {
this._kernel.dispose();
const oldValue = this._kernel;
this._kernel = null;
const newValue = this._kernel;
this._kernelChanged.emit({ name: 'kernel', oldValue, newValue });
}
signaling_1.Signal.clearData(this);
}
/**
* Change the session path.
*
* @param path - The new session path.
*
* @returns A promise that resolves when the session has renamed.
*
* #### Notes
* This uses the Jupyter REST API, and the response is validated.
* The promise is fulfilled on a valid response and rejected otherwise.
*/
async setPath(path) {
if (this.isDisposed) {
throw new Error('Session is disposed');
}
await this._patch({ path });
}
/**
* Change the session name.
*/
async setName(name) {
if (this.isDisposed) {
throw new Error('Session is disposed');
}
await this._patch({ name });
}
/**
* Change the session type.
*/
async setType(type) {
if (this.isDisposed) {
throw new Error('Session is disposed');
}
await this._patch({ type });
}
/**
* Change the kernel.
*
* @param options - The name or id of the new kernel.
*
* #### Notes
* This shuts down the existing kernel and creates a new kernel,
* keeping the existing session ID and session path.
*/
async changeKernel(options) {
if (this.isDisposed) {
throw new Error('Session is disposed');
}
await this._patch({ kernel: options });
return this.kernel;
}
/**
* Kill the kernel and shutdown the session.
*
* @returns - The promise fulfilled on a valid response from the server.
*
* #### Notes
* Uses the [Jupyter Server API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/sessions), and validates the response.
* Disposes of the session and emits a [sessionDied] signal on success.
*/
async shutdown() {
if (this.isDisposed) {
throw new Error('Session is disposed');
}
await (0, restapi_1.shutdownSession)(this.id, this.serverSettings);
this.dispose();
}
/**
* Create a new kernel connection and connect to its signals.
*
* #### Notes
* This method is not meant to be subclassed.
*/
setupKernel(model) {
if (model === null) {
this._kernel = null;
return;
}
const kc = this._connectToKernel({
...this._kernelConnectionOptions,
model,
username: this._username,
clientId: this._clientId,
serverSettings: this.serverSettings
});
this._kernel = kc;
kc.statusChanged.connect(this.onKernelStatus, this);
kc.connectionStatusChanged.connect(this.onKernelConnectionStatus, this);
kc.pendingInput.connect(this.onPendingInput, this);
kc.unhandledMessage.connect(this.onUnhandledMessage, this);
kc.iopubMessage.connect(this.onIOPubMessage, this);
kc.anyMessage.connect(this.onAnyMessage, this);
}
/**
* Handle to changes in the Kernel status.
*/
onKernelStatus(sender, state) {
this._statusChanged.emit(state);
}
/**
* Handle to changes in the Kernel status.
*/
onKernelConnectionStatus(sender, state) {
this._connectionStatusChanged.emit(state);
}
/**
* Handle a change in the pendingInput.
*/
onPendingInput(sender, state) {
this._pendingInput.emit(state);
}
/**
* Handle iopub kernel messages.
*/
onIOPubMessage(sender, msg) {
this._iopubMessage.emit(msg);
}
/**
* Handle unhandled kernel messages.
*/
onUnhandledMessage(sender, msg) {
this._unhandledMessage.emit(msg);
}
/**
* Handle any kernel messages.
*/
onAnyMessage(sender, args) {
this._anyMessage.emit(args);
}
/**
* Send a PATCH to the server, updating the session path or the kernel.
*/
async _patch(body) {
const model = await (0, restapi_1.updateSession)({ ...body, id: this._id }, this.serverSettings);
this.update(model);
return model;
}
/**
* Handle a change to the model.
*/
_handleModelChange(oldModel) {
if (oldModel.name !== this._name) {
this._propertyChanged.emit('name');
}
if (oldModel.type !== this._type) {
this._propertyChanged.emit('type');
}
if (oldModel.path !== this._path) {
this._propertyChanged.emit('path');
}
}
}
exports.SessionConnection = SessionConnection;
//# sourceMappingURL=default.js.map