layout | title | category | tags | order | |||
---|---|---|---|---|---|---|---|
developer-doc |
Enso Protocol Project Manager Message Specification |
language-server |
|
3 |
This document contains the specification of the Enso protocol messages that pertain to the project manager component. Please familiarise yourself with the common features of the protocol before reading this document.
For information on the design and architecture of the protocol, as well as its transport formats, please look here.
- Types
- Project Management Operations
- Action Progress Reporting
- Runtime Version Management
- Configuration Management
- Logging Service
- Language Server Management
- Errors
MissingComponentError
BrokenComponentError
ProjectManagerUpgradeRequired
ComponentInstallationError
ComponentUninstallationError
ComponentRepositoryUnavailable
ProjectNameValidationError
ProjectDataStoreError
ProjectExistsError
ProjectNotFoundError
ProjectOpenError
ProjectNotOpenError
ProjectOpenByOtherPeersError
CannotRemoveOpenProjectError
ProjectCloseError
LanguageServerError
GlobalConfigurationAccessError
ProjectCreateError
LoggingServiceUnavailable
There are a number of types that are used only within the project server's protocol messages. These are specified here.
This type represents information about a project.
interface ProjectMetadata {
/**
* The name of the project.
*/
name: String;
/**
* The namespace of the project.
*/
namespace: String;
/**
* The project id.
*/
id: UUID;
/**
* Enso Engine version to use for the project, represented by a semver version
* string.
*
* If the edition associated with the project could not be resolved, the
* engine version may be missing.
*/
engineVersion?: String;
/**
* The last opened datetime.
*/
lastOpened?: UTCDateTime;
}
This type specifies what action should be taken if a component required to complete an operation is missing.
Fail
will make the operation fail if any components are missing.Install
will try to install any missing components, unless they are marked as broken.ForceInstallBroken
will try to install all missing components, even if some of them are marked as broken.
type MissingComponentAction = Fail | Install | ForceInstallBroken;
This type specifies the unit of progress updates related to a task.
type ProgressUnit = Bytes | Other;
This type represents an installed or available engine version.
interface EngineVersion {
/** Semver string of engine version. */
version: String;
/** Specifies if that version is marked as broken. */
markedAsBroken: bool;
}
The primary responsibility of the project managers is to allow users to manage their projects.
This message requests that the project manager open a specified project. This operation also includes spawning an instance of the language server open on the specified project.
To open a project, an engine version that is specified in project settings needs
to be installed. If missingComponentAction
is set to Install
or
ForceInstallBroken
, this action will install any missing components,
otherwise, an error will be reported if a component is missing. A typical usage
scenario may consist of first trying to open the project without installing
missing components. If that fails with the MissingComponentError
, the client
can ask the user if they want to install the missing components and re-attempt
the action.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
{
projectId: UUID;
/**
* Specifies how to handle missing components.
*
* If not provided, defaults to `Fail`.
*/
missingComponentAction?: MissingComponentAction;
}
{
/**
* The version of the started language server represented by a semver version
* string.
*/
engineVersion: String;
/**
* The endpoint used for JSON-RPC protocol.
*/
languageServerJsonAddress: IPWithSocket;
/**
* The endpoint used for binary protocol.
*/
languageServerBinaryAddress: IPWithSocket;
// The name of the project as it is opened.
projectName: String;
// The namespace of the project.
projectNamespace: String;
}
ProjectNotFoundError
to signal that the project doesn't exist.ProjectDataStoreError
to signal problems with underlying data store.ProjectOpenError
to signal failures during server boot.MissingComponentError
to signal that the component required to open the project was missing (only in casemissingComponentAction
was set tofail
).BrokenComponentError
to signal that the component required to open the project was being installed but is marked as broken (only in casemissingComponentAction
was set toinstall
).ComponentInstallationError
to signal that the installation of a missing component has failed.ProjectManagerUpgradeRequired
to signal that the requested engine version requires a more recent project manager, so an upgrade has to be performed before continuing.
This message requests that the project manager close a specified project. This operation includes shutting down the language server gracefully so that it can persist state to disk as needed.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
interface ProjectCloseRequest {
projectId: UUID;
}
{
}
ProjectNotFoundError
to signal that the project doesn't exist.ProjectDataStoreError
to signal problems with underlying data store.ProjectCloseError
to signal failures that occurred during language server stoppage.ProjectNotOpenError
to signal cannot close a project that is not open.ProjectOpenByOtherPeersError
to signal that cannot close a project that is open by other clients.
This message requests that the project manager lists all user's projects. The list of projects is sorted by the open time.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
interface ProjectListRequest {
numberOfProjects?: Int;
}
interface ProjectListResponse {
projects: [ProjectMetadata];
}
ProjectDataStoreError
to signal problems with underlying data store.GlobalConfigurationAccessError
to signal that the global configuration file could not be accessed or parsed.
This message requests the creation of a new project.
To create a project, an engine version associated with it needs to be installed.
Depending on missingComponentAction
, any components required to complete the
operation are missing will be installed or a failure will be reported.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
interface ProjectCreateRequest {
/** Name of the project to create. */
name: String;
/** The name of the project template to create. */
projectTemplate?: String;
/**
* Enso Engine version to use for the project.
*
* Possible values are:
* - a semver version string identifying an Enso engine version,
* - `default` to use the current default.
*
* The field is optional - if it is missing, it is treated as `default`.
*/
version?: String;
/**
* Specifies how to handle missing components.
*
* If not provided, defaults to `Fail`.
*/
missingComponentAction?: MissingComponentAction;
}
interface ProjectCreateResponse {
projectId: UUID;
projectName: string;
}
ProjectNameValidationError
to signal validation failures.ProjectDataStoreError
to signal problems with underlying data store.ProjectExistsError
to signal that the project already exists.MissingComponentError
to signal that the component required to create the project was missing (only in casemissingComponentAction
was set tofail
).BrokenComponentError
to signal that the component required to create the project was being installed but is marked as broken (only in casemissingComponentAction
was set toinstall
).ComponentInstallationError
to signal that the installation of a missing component has failed.ProjectManagerUpgradeRequired
to signal that the requested engine version requires a more recent project manager, so an upgrade has to be performed before continuing.
This message requests the renaming of a project.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
interface ProjectRenameRequest {
projectId: UUID;
name: String;
}
null
ProjectNameValidationError
to signal validation failures.ProjectDataStoreError
to signal problems with underlying data store.ProjectExistsError
to signal that the project with the provided name already exists.ServiceError
to signal that the the operation timed out.LanguageServerError
to signal generic language server failures.
This message requests the deletion of a project.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
interface ProjectDeleteRequest {
projectId: UUID;
}
{
}
ProjectDataStoreError
to signal problems with underlying data store.ProjectNotFoundError
to signal that the project doesn't exist.CannotRemoveOpenProjectError
to signal that the project cannot be removed, because is open by at least one user.
This request lists the sample projects that are available to the user.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
interface ProjectListSampleRequest {
numProjects: Int;
}
interface ProjectListSampleResponse {
projects: [ProjectMetadata];
}
TBC
Some actions, especially those related to installation of new components may take a long time (for example because big packages need to be downloaded).
The protocol includes notifications tied to such actions that can be used to display progress bars.
Each task has a lifecycle of being initialized with a task/started
notification (which contains a UUID that identifies that task), being updated
with task/progress-update
and finalized with task/finished
. task/finished
may include an error (but please note that regardless of the task-related error,
the error will also be reported for the original request associated with the
task, for example as ComponentInstallationError
returned for the
project/open
request that triggered the installation).
Tasks are sent while an operation is being processed and a single operation may consist of several (sub)tasks.
For example, when opening a project the flow may be following:
project/open
request sent to the server- notification
task/started
(downloading the archive) - multiple notifications
task/progress-update
related to that task - notification
task/finished
- notification
task/started
(extracting the archive) - multiple notifications
task/progress-update
related to that task - notification
task/finished
- reply to the original
project/open
request
All task progress updates happen within the response/request flow (up to a possible reordering of messages).
Indicates that a long running task has been started.
Currently only used when components are being installed to show installation progress.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
interface TaskStartNotification {
/**
* Unique identifier of the task, used to correlate progress updates and the
* finished notification.
*/
taskId: UUID;
/**
* Name of the operation this task is related to, for example
* `project/open`.
*/
relatedOperation: String;
/** Unit in which progress of this task is measured. */
unit: ProgressUnit;
/**
* Indicates total expected progress.
*
* May be missing, as it is not always known, for example when downloading a
* file of unknown size or waiting on a lock.
*/
total?: Long;
}
Indicates a progress update for a specific task.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
interface TaskUpdateNotification {
taskId: UUID;
/** Optional message explaining current status of the task. */
message?: String;
/** Indicates amount of progress, for example: count of processed bytes. */
done: Long;
}
Indicates that a task has been finished, either successfully or with an error.
- Type: Notification
- Direction: Server -> Client
- Connection: Protocol
- Visibility: Public
interface TaskFinishedNotification {
taskId: UUID;
/** Optional message informing about task completion. */
message?: String;
/** Specifies if the task succeeded or failed. */
success: bool;
}
Lists engine versions currently installed.
Please note that the broken marks associated with each engine currently represent the state at the moment of installation. As of now, if the broken mark has been added later, it is not updated automatically.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
null;
interface EngineVersionListResponse {
/** List of installed engines. */
versions: [EngineVersion];
}
TBC
Queries the repository to list all engine versions that are available to be installed.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
null;
interface EngineVersionListResponse {
/** List of available engines. */
versions: [EngineVersion];
}
ComponentRepositoryUnavailable
to signal that the component repository could not be reached.
Requests to install the specified engine version. If that version is already installed, it has no effect.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
interface EngineInstallRequest {
/** Semver string of engine version that should be installed. */
version: String;
/**
* Specifies whether the engine should be installed even if it is marked as
* broken.
*
* If not provided, defaults to `false`.
*/
forceInstallBroken?: bool;
}
null;
BrokenComponentError
to signal that the requested engine version is marked as broken (only in caseforceInstallBroken
was set tofalse
).ComponentInstallationError
to signal that the installation of a missing component has failed.ProjectManagerUpgradeRequired
to signal that the requested engine version requires a more recent project manager, so an upgrade has to be performed before continuing.
Requests to uninstall the specified engine version.
If that version was not installed, it has no effect.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
interface EngineUninstallRequest {
/** Semver string of engine version that should be uninstalled. */
version: String;
}
null;
ComponentUninstallationError
to signal that the component could not have been uninstalled.
Gets a value from the global config.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
interface GlobalConfigGetRequest {
key: String;
}
interface GlobalConfigGetResponse {
/**
* The value set in the config.
*
* The field may be missing if the requested value is not set in the config.
*/
value?: String;
}
GlobalConfigurationAccessError
to signal that the configuration file could not be accessed.
Sets a value in the global config.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
interface GlobalConfigSetRequest {
key: String;
value: String;
}
null;
GlobalConfigurationAccessError
to signal that the configuration file could not be accessed.
Deletes a value from the global config, or does nothing if it did not exist.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
interface GlobalConfigDeleteRequest {
key: String;
}
null;
GlobalConfigurationAccessError
to signal that the configuration file could not be accessed.
Requests the endpoint for connecting to the logging service.
- Type: Request
- Direction: Client -> Server
- Connection: Protocol
- Visibility: Public
null;
interface LoggingServiceEndpointResponse {
uri: String;
}
LoggingServiceUnavailable
to signal that the logging service is unavailable.
The project manager is also responsible for managing the language server. This means that it needs to be able to spawn the process, but also tell the process when to shut down.
A language server process is spawned within the project/open
call. That call
returns endpoints that the client can use to connect to the language server.
When project/close
is called, the language server is shutdown. Moreover,
between these two calls, the project manager sends heartbeat messages to the
language server to check if it is still running. In case that it has crashed, a
restart is attempted.
The project manager component has its own set of errors. This section is not a complete specification and will be updated as new errors are added.
Besides the required code
and message
fields, the errors may have a data
field which can store additional error-specific payload.
Signals that a component required to complete the action was missing, but the action did not ask for it to be automatically installed.
"error" : {
"code" : 4020,
"message" : "Engine 1.2.3 is required to complete the action but it is not installed."
}
Signals that a component that was being installed is marked as broken, but the option to forcibly install broken components was not set.
This error may handled by warning the user about the broken version or suggesting to upgrade the project and asking to confirm using the broken version. If the user wants to ignore the warning, the operation can be reattempted with the option to forcibly install broken components.
"error" : {
"code" : 4021,
"message" : "Engine 1.2.3 is marked as broken."
}
Signals that installation of a missing compoment has been attempted, but the required engine version requires a newer version of project manager than what is currently running.
This error type includes the optional data
field which is an object with a
field minimumRequiredVersion
that is a semver string of the project manager
version that is required to complete the related action.
"error" : {
"code" : 4022,
"message" : "Project manager 1.2.3 is required to install the requested engine. Please upgrade.",
"payload": {
"minimumRequiredVersion": "1.2.3"
}
}
Signals that installation of a missing component has been attempted but it has failed.
"error" : {
"code" : 4023,
"message" : "A problem occurred when trying to find the release: Cannot find release `enso-1.2.3-not-published`."
}
Signals that uninstallation of a component has failed.
"error" : {
"code" : 4024,
"message" : "The requested engine version is not installed."
}
Signals that the repository is unavailable and could not be queried (usually caused by lack of internet connection).
"error" : {
"code" : 4025,
"message" : "Could not connect to github.com"
}
Signals validation failures.
"error" : {
"code" : 4001,
"message" : "Cannot create project with empty name"
}
Signals problems with underlying data store.
"error" : {
"code" : 4002,
"message" : "Cannot load project index"
}
Signals that the project already exists.
"error" : {
"code" : 4003,
"message" : "Project with the provided name exists"
}
Signals that the project doesn't exist.
"error" : {
"code" : 4004,
"message" : "Project with the provided id does not exist"
}
Signals that the project cannot be open due to boot failures.
"error" : {
"code" : 4005,
"message" : "A boot failure."
}
Signals that cannot close project that is not open.
"error" : {
"code" : 4006,
"message" : "Cannot close project that is not open"
}
Signals that cannot close a project that is open by other clients.
"error" : {
"code" : 4007,
"message" : "Cannot close project because it is open by other peers"
}
Signals that cannot remove open project.
"error" : {
"code" : 4008,
"message" : "Cannot remove open project"
}
Signals failures during shutdown of a server.
"error" : {
"code" : 4009,
"message" : "A shutdown failure."
}
Signals generic language server errors.
"error" : {
"code" : 4010,
"message" : "The language server is unresponsive"
}
Signals that the global configuration file could not be accessed or parsed.
"error" : {
"code" : 4011,
"message" : "The global configuration file is malformed."
}
Signals that an error occurred when creating the project.
"error" : {
"code" : 4012,
"message" : "Could not create the project."
}
Signals that the logging service is not available.
"error" : {
"code" : 4013,
"message" : "The logging service has failed to boot."
}