Skip to content

Commit

Permalink
Add support for profiling information in the protocol (#1407)
Browse files Browse the repository at this point in the history
  • Loading branch information
iamrecursion committed Feb 10, 2021
1 parent 35e60ed commit 13c6609
Show file tree
Hide file tree
Showing 15 changed files with 502 additions and 121 deletions.
45 changes: 38 additions & 7 deletions docs/language-server/protocol-language-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ transport formats, please look [here](./protocol-architecture).
- [`StackItem`](#stackitem)
- [`MethodPointer`](#methodpointer)
- [`ExpressionValueUpdate`](#expressionvalueupdate)
- [`ProfilingInfo`](#profilinginfo)
- [`VisualisationConfiguration`](#visualisationconfiguration)
- [`SuggestionEntryArgument`](#suggestionentryargument)
- [`SuggestionEntry`](#suggestionentry)
Expand Down Expand Up @@ -65,8 +66,8 @@ transport formats, please look [here](./protocol-architecture).
- [`executionContext/canModify`](#executioncontextcanmodify)
- [`executionContext/receivesUpdates`](#executioncontextreceivesupdates)
- [`search/receivesSuggestionsDatabaseUpdates`](#searchreceivessuggestionsdatabaseupdates)
- [Enables](#enables-4)
- [Disables](#disables-4)
- [Enables](#enables)
- [Disables](#disables)
- [File Management Operations](#file-management-operations)
- [`file/write`](#filewrite)
- [`file/read`](#fileread)
Expand Down Expand Up @@ -125,21 +126,21 @@ transport formats, please look [here](./protocol-architecture).
- [`search/suggestionsDatabaseUpdate`](#searchsuggestionsdatabaseupdate)
- [`search/completion`](#searchcompletion)
- [`search/import`](#searchimport)
- [Input/Output Operations](#input-output-operations)
- [`io/redirectStandardOutput`](#ioredirectstdardoutput)
- [`io/suppressStandardOutput`](#iosuppressstdardoutput)
- [Input/Output Operations](#inputoutput-operations)
- [`io/redirectStandardOutput`](#ioredirectstandardoutput)
- [`io/suppressStandardOutput`](#iosuppressstandardoutput)
- [`io/standardOutputAppended`](#iostandardoutputappended)
- [`io/redirectStandardError`](#ioredirectstandarderror)
- [`io/suppressStandardError`](#iosuppressstandarderror)
- [`io/standardErrorAppended`](#iostandarderrorappended)
- [`io/feedStandardInput`](#iofeedstandardinput)
- [`io/waitingForStandardInput`](#iowaitingforstandardinput)
- [Errors](#errors-57)
- [Errors](#errors)
- [`AccessDeniedError`](#accessdeniederror)
- [`FileSystemError`](#filesystemerror)
- [`ContentRootNotFoundError`](#contentrootnotfounderror)
- [`FileNotFound`](#filenotfound)
- [`FileExists`](#fileexists)
- [`FileExists`](#fileexists-1)
- [`OperationTimeoutError`](#operationtimeouterror)
- [`NotDirectory`](#notdirectory)
- [`StackItemNotFoundError`](#stackitemnotfounderror)
Expand All @@ -160,6 +161,7 @@ transport formats, please look [here](./protocol-architecture).
- [`SuggestionsDatabaseError`](#suggestionsdatabaseerror)
- [`ProjectNotFoundError`](#projectnotfounderror)
- [`ModuleNameNotResolvedError`](#modulenamenotresolvederror)
- [`SuggestionNotFoundError`](#suggestionnotfounderror)

<!-- /MarkdownTOC -->

Expand Down Expand Up @@ -229,6 +231,8 @@ interface MethodPointer {

### `ExpressionValueUpdate`

Metadata on an updated expression.

```typescript
interface ExpressionValueUpdate {
/** The id of updated expression */
Expand All @@ -239,6 +243,33 @@ interface ExpressionValueUpdate {

/** The updated pointer to the method call */
methodPointer?: SuggestionId;

/** Profiling information for the expression */
profilingInfo: ProfilingInfo[];

/** Whether the expression value came from the cache or not */
fromCache: bool;
}
```

Currently, the `profilingInfo` array is guaranteed to contain at least the
`ExecutionTime` information.

### `ProfilingInfo`

Profiling information on an executed expression. It is implemented as a union as
additional types of information will be added in the future.

```typescript
type ProfilingInfo = ExecutionTime;
```

Where:

```typescript
interface ExecutionTime {
/** The time elapsed during the expression's evaluation, in nanoseconds */
nanoTime: Number;
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,12 @@ final class ContextEventsListener(
log.error(s"Unable to find suggestion for $pointer")
None
}
}
},
update.profilingInfo.map {
case Api.ProfilingInfo.ExecutionTime(t) =>
ProfilingInfo.ExecutionTime(t)
},
update.fromCache
)
}
val payload =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ import org.enso.languageserver.runtime.ExecutionApi.ExpressionId
* @param expressionId the id of updated expression
* @param `type` the updated type of expression
* @param methodPointer the suggestion id of the updated method pointer
* @param profilingInfo profiling information about the expression
* @param fromCache whether or not the expression's value came from the cache
*/
case class ExpressionValueUpdate(
expressionId: ExpressionId,
`type`: Option[String],
methodPointer: Option[Long]
methodPointer: Option[Long],
profilingInfo: Vector[ProfilingInfo],
fromCache: Boolean
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.enso.languageserver.runtime

/** A trait to unify various types of profiling information about an executed
* expression.
*/
sealed trait ProfilingInfo
object ProfilingInfo {

/** The time spent executing the expression.
*
* @param nanoTime the time elapsed while executing the expression in
* nanoseconds
*/
case class ExecutionTime(nanoTime: Long) extends ProfilingInfo
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@ class ContextEventsListenerSpec
Api.MethodPointer(
Suggestions.method.module,
Suggestions.method.selfType,
Suggestions.method.name
Suggestions.method.name,
)
)
),
Vector(),
false
)
)
)
Expand All @@ -106,7 +108,9 @@ class ContextEventsListenerSpec
ExpressionValueUpdate(
Suggestions.method.externalId.get,
Some(Suggestions.method.returnType),
Some(suggestionIds(1).get)
Some(suggestionIds(1).get),
Vector(),
false
)
)
)
Expand Down Expand Up @@ -134,7 +138,9 @@ class ContextEventsListenerSpec
Api.ExpressionValueUpdate(
Suggestions.method.externalId.get,
None,
None
None,
Vector(),
false
)
)
)
Expand All @@ -145,7 +151,9 @@ class ContextEventsListenerSpec
Api.ExpressionValueUpdate(
Suggestions.local.externalId.get,
None,
None
None,
Vector(),
false
)
)
)
Expand All @@ -161,12 +169,16 @@ class ContextEventsListenerSpec
ExpressionValueUpdate(
Suggestions.method.externalId.get,
None,
None
None,
Vector(),
false
),
ExpressionValueUpdate(
Suggestions.local.externalId.get,
None,
None
None,
Vector(),
false
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package org.enso.polyglot.runtime
import java.io.File
import java.nio.ByteBuffer
import java.util.UUID

import com.fasterxml.jackson.annotation.{JsonSubTypes, JsonTypeInfo}
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.cbor.CBORFactory
Expand Down Expand Up @@ -192,6 +191,7 @@ object Runtime {
)
)
sealed trait Api
sealed trait ApiEnvelope extends Api
sealed trait ApiRequest extends Api
sealed trait ApiResponse extends Api
sealed trait ApiNotification extends ApiResponse
Expand Down Expand Up @@ -231,7 +231,6 @@ object Runtime {
)
)
sealed trait StackItem

object StackItem {

/** A call performed at the top of the stack, to initialize the context.
Expand All @@ -252,13 +251,41 @@ object Runtime {
* @param expressionId expression id.
* @param expressionType the type of expression.
* @param methodCall the pointer to a method definition.
* @param profilingInfo profiling information about the execution of this
* expression
* @param fromCache whether or not the value for this expression came from
* the cache
*/
case class ExpressionValueUpdate(
expressionId: ExpressionId,
expressionType: Option[String],
methodCall: Option[MethodPointer]
methodCall: Option[MethodPointer],
profilingInfo: Vector[ProfilingInfo],
fromCache: Boolean
)

/** An object representing profiling information about an executed
* expression.
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes(
Array(
new JsonSubTypes.Type(
value = classOf[ProfilingInfo.ExecutionTime],
name = "executionTime"
)
)
)
sealed trait ProfilingInfo
object ProfilingInfo {

/** A representation of the time elapsed during execution.
*
* @param nanoTime the time elapsed during execution in nanoseconds
*/
case class ExecutionTime(nanoTime: Long) extends ProfilingInfo
}

/** An object representing invalidated expressions selector.
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
Expand All @@ -275,7 +302,6 @@ object Runtime {
)
)
sealed trait InvalidatedExpressions

object InvalidatedExpressions {

/** An object representing invalidation of all expressions.
Expand Down Expand Up @@ -468,7 +494,6 @@ object Runtime {
)
sealed trait DiagnosticType
object DiagnosticType {

case class Error() extends DiagnosticType
case class Warning() extends DiagnosticType
}
Expand Down Expand Up @@ -638,6 +663,7 @@ object Runtime {
* @param payload the request payload.
*/
case class Request(requestId: Option[RequestId], payload: ApiRequest)
extends ApiEnvelope

object Request {

Expand Down Expand Up @@ -665,6 +691,7 @@ object Runtime {
* @param payload response
*/
case class Response(correlationId: Option[RequestId], payload: ApiResponse)
extends ApiEnvelope

object Response {

Expand Down
12 changes: 9 additions & 3 deletions engine/runtime/src/main/java/org/enso/interpreter/Language.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
IdentifiedTag.class
})
public final class Language extends TruffleLanguage<Context> {
private IdExecutionInstrument idExecutionInstrument;

/**
* Creates a new Enso context.
*
Expand All @@ -58,9 +60,8 @@ protected Context createContext(Env env) {
Context context = new Context(this, getLanguageHome(), env);
InstrumentInfo idValueListenerInstrument =
env.getInstruments().get(IdExecutionInstrument.INSTRUMENT_ID);
IdExecutionInstrument idExecutionInstrumentService =
env.lookup(idValueListenerInstrument, IdExecutionInstrument.class);
env.registerService(new ExecutionService(context, idExecutionInstrumentService));
idExecutionInstrument = env.lookup(idValueListenerInstrument, IdExecutionInstrument.class);
env.registerService(new ExecutionService(context, idExecutionInstrument));
return context;
}

Expand Down Expand Up @@ -114,4 +115,9 @@ protected OptionDescriptors getOptionDescriptors() {
protected Iterable<Scope> findTopScopes(Context context) {
return Collections.singleton(context.getTopScope().getScope());
}

/** @return a reference to the execution instrument */
public IdExecutionInstrument getIdExecutionInstrument() {
return idExecutionInstrument;
}
}
Loading

0 comments on commit 13c6609

Please sign in to comment.