Skip to content

Commit

Permalink
User metadata on workflows/events for user interface usage (#371)
Browse files Browse the repository at this point in the history
  • Loading branch information
cretz authored May 17, 2024
1 parent d513a14 commit de9e005
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 7 deletions.
2 changes: 2 additions & 0 deletions buf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ breaking:
- WIRE_JSON
ignore:
- google
# Remove this after user metadata is merged
- temporal/api/sdk/v1/workflow_metadata.proto
lint:
use:
- DEFAULT
Expand Down
42 changes: 42 additions & 0 deletions openapi/openapiv2.json
Original file line number Diff line number Diff line change
Expand Up @@ -2970,6 +2970,10 @@
"skipGenerateWorkflowTask": {
"type": "boolean",
"description": "Indicates that a new workflow task should not be generated when this signal is received."
},
"userMetadata": {
"$ref": "#/definitions/v1UserMetadata",
"description": "Metadata on the workflow if it is started. This is carried over to the WorkflowExecutionInfo\nfor use by user interfaces to display the fixed as-of-start summary and details of the\nworkflow."
}
}
},
Expand Down Expand Up @@ -3132,6 +3136,10 @@
"$ref": "#/definitions/v1Callback"
},
"description": "Callbacks to be called by the server when this workflow reaches a terminal state.\nIf the workflow continues-as-new, these callbacks will be carried over to the new execution.\nCallback addresses must be whitelisted in the server's dynamic configuration."
},
"userMetadata": {
"$ref": "#/definitions/v1UserMetadata",
"description": "Metadata on the workflow if it is started. This is carried over to the WorkflowExecutionInfo\nfor use by user interfaces to display the fixed as-of-start summary and details of the\nworkflow."
}
}
},
Expand Down Expand Up @@ -4344,6 +4352,10 @@
"commandType": {
"$ref": "#/definitions/v1CommandType"
},
"userMetadata": {
"$ref": "#/definitions/v1UserMetadata",
"description": "Metadata on the command. This is sometimes carried over to the history event if one is\ncreated as a result of the command. Most commands won't have this information, and how this\ninformation is used is dependent upon the interface that reads it.\n\nCurrent well-known uses:\n * start_child_workflow_execution_command_attributes - populates\n temporal.api.workflow.v1.WorkflowExecutionInfo.user_metadata where the summary and details\n are used by user interfaces to show fixed as-of-start workflow summary and details.\n * start_timer_command_attributes - populates temporal.api.history.v1.HistoryEvent for timer\n started where the summary is used to identify the timer."
},
"scheduleActivityTaskCommandAttributes": {
"$ref": "#/definitions/v1ScheduleActivityTaskCommandAttributes"
},
Expand Down Expand Up @@ -5274,6 +5286,10 @@
"type": "boolean",
"description": "Set to true when the SDK may ignore the event as it does not impact workflow state or\ninformation in any way that the SDK need be concerned with. If an SDK encounters an event\ntype which it does not understand, it must error unless this is true. If it is true, it's\nacceptable for the event type and/or attributes to be uninterpretable."
},
"userMetadata": {
"$ref": "#/definitions/v1UserMetadata",
"description": "Metadata on the event. This is often carried over from commands and client calls. Most events\nwon't have this information, and how this information is used is dependent upon the interface\nthat reads it.\n\nCurrent well-known uses:\n * workflow_execution_started_event_attributes - summary and details from start workflow.\n * timer_started_event_attributes - summary represents an identifier for the timer for use by\n user interfaces."
},
"workflowExecutionStartedEventAttributes": {
"$ref": "#/definitions/v1WorkflowExecutionStartedEventAttributes"
},
Expand Down Expand Up @@ -5964,6 +5980,10 @@
},
"header": {
"$ref": "#/definitions/v1Header"
},
"userMetadata": {
"$ref": "#/definitions/v1UserMetadata",
"description": "Metadata on the workflow if it is started. This is carried over to the WorkflowExecutionConfig\nfor use by user interfaces to display the fixed as-of-start summary and details of the\nworkflow."
}
},
"description": "NewWorkflowExecutionInfo is a shared message that encapsulates all the\nrequired arguments to starting a workflow in different contexts."
Expand Down Expand Up @@ -8103,6 +8123,10 @@
"$ref": "#/definitions/v1Callback"
},
"description": "Callbacks to be called by the server when this workflow reaches a terminal state.\nIf the workflow continues-as-new, these callbacks will be carried over to the new execution.\nCallback addresses must be whitelisted in the server's dynamic configuration."
},
"userMetadata": {
"$ref": "#/definitions/v1UserMetadata",
"description": "Metadata on the workflow if it is started. This is carried over to the WorkflowExecutionInfo\nfor use by user interfaces to display the fixed as-of-start summary and details of the\nworkflow."
}
}
},
Expand Down Expand Up @@ -8692,6 +8716,20 @@
}
}
},
"v1UserMetadata": {
"type": "object",
"properties": {
"summary": {
"$ref": "#/definitions/v1Payload",
"description": "Short-form text that provides a summary. This payload should be a \"json/plain\"-encoded payload\nthat is a single JSON string for use in user interfaces. User interface formatting may not\napply to this text when used in \"title\" situations. The payload data section is limited to 400\nbytes by default."
},
"details": {
"$ref": "#/definitions/v1Payload",
"description": "Long-form text that provides details. This payload should be a \"json/plain\"-encoded payload\nthat is a single JSON string for use in user interfaces. User interface formatting may apply to\nthis text in common use. The payload data section is limited to 20000 bytes by default."
}
},
"description": "Information a user can set, often for use by user interfaces."
},
"v1VersionInfo": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -8834,6 +8872,10 @@
},
"defaultWorkflowTaskTimeout": {
"type": "string"
},
"userMetadata": {
"$ref": "#/definitions/v1UserMetadata",
"description": "User metadata provided on start workflow."
}
}
},
Expand Down
56 changes: 56 additions & 0 deletions openapi/openapiv3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3576,6 +3576,18 @@ components:
information in any way that the SDK need be concerned with. If an SDK encounters an event
type which it does not understand, it must error unless this is true. If it is true, it's
acceptable for the event type and/or attributes to be uninterpretable.
userMetadata:
allOf:
- $ref: '#/components/schemas/UserMetadata'
description: |-
Metadata on the event. This is often carried over from commands and client calls. Most events
won't have this information, and how this information is used is dependent upon the interface
that reads it.
Current well-known uses:
* workflow_execution_started_event_attributes - summary and details from start workflow.
* timer_started_event_attributes - summary represents an identifier for the timer for use by
user interfaces.
workflowExecutionStartedEventAttributes:
$ref: '#/components/schemas/WorkflowExecutionStartedEventAttributes'
workflowExecutionCompletedEventAttributes:
Expand Down Expand Up @@ -4051,6 +4063,13 @@ components:
$ref: '#/components/schemas/SearchAttributes'
header:
$ref: '#/components/schemas/Header'
userMetadata:
allOf:
- $ref: '#/components/schemas/UserMetadata'
description: |-
Metadata on the workflow if it is started. This is carried over to the WorkflowExecutionConfig
for use by user interfaces to display the fixed as-of-start summary and details of the
workflow.
description: |-
NewWorkflowExecutionInfo is a shared message that encapsulates all the
required arguments to starting a workflow in different contexts.
Expand Down Expand Up @@ -5642,6 +5661,13 @@ components:
skipGenerateWorkflowTask:
type: boolean
description: Indicates that a new workflow task should not be generated when this signal is received.
userMetadata:
allOf:
- $ref: '#/components/schemas/UserMetadata'
description: |-
Metadata on the workflow if it is started. This is carried over to the WorkflowExecutionInfo
for use by user interfaces to display the fixed as-of-start summary and details of the
workflow.
SignalWithStartWorkflowExecutionResponse:
type: object
properties:
Expand Down Expand Up @@ -5939,6 +5965,13 @@ components:
Callbacks to be called by the server when this workflow reaches a terminal state.
If the workflow continues-as-new, these callbacks will be carried over to the new execution.
Callback addresses must be whitelisted in the server's dynamic configuration.
userMetadata:
allOf:
- $ref: '#/components/schemas/UserMetadata'
description: |-
Metadata on the workflow if it is started. This is carried over to the WorkflowExecutionInfo
for use by user interfaces to display the fixed as-of-start summary and details of the
workflow.
StartWorkflowExecutionResponse:
type: object
properties:
Expand Down Expand Up @@ -6444,6 +6477,25 @@ components:
description: The `WORKFLOW_TASK_COMPLETED` event which this command was reported with
searchAttributes:
$ref: '#/components/schemas/SearchAttributes'
UserMetadata:
type: object
properties:
summary:
allOf:
- $ref: '#/components/schemas/Payload'
description: |-
Short-form text that provides a summary. This payload should be a "json/plain"-encoded payload
that is a single JSON string for use in user interfaces. User interface formatting may not
apply to this text when used in "title" situations. The payload data section is limited to 400
bytes by default.
details:
allOf:
- $ref: '#/components/schemas/Payload'
description: |-
Long-form text that provides details. This payload should be a "json/plain"-encoded payload
that is a single JSON string for use in user interfaces. User interface formatting may apply to
this text in common use. The payload data section is limited to 20000 bytes by default.
description: Information a user can set, often for use by user interfaces.
VersionInfo:
type: object
properties:
Expand Down Expand Up @@ -6569,6 +6621,10 @@ components:
defaultWorkflowTaskTimeout:
pattern: ^-?(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,9})?s$
type: string
userMetadata:
allOf:
- $ref: '#/components/schemas/UserMetadata'
description: User metadata provided on start workflow.
WorkflowExecutionContinuedAsNewEventAttributes:
type: object
properties:
Expand Down
13 changes: 13 additions & 0 deletions temporal/api/command/v1/message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import "temporal/api/enums/v1/command_type.proto";
import "temporal/api/common/v1/message.proto";
import "temporal/api/failure/v1/message.proto";
import "temporal/api/taskqueue/v1/message.proto";
import "temporal/api/sdk/v1/user_metadata.proto";

message ScheduleActivityTaskCommandAttributes {
string activity_id = 1;
Expand Down Expand Up @@ -267,6 +268,18 @@ message RequestCancelNexusOperationCommandAttributes {

message Command {
temporal.api.enums.v1.CommandType command_type = 1;
// Metadata on the command. This is sometimes carried over to the history event if one is
// created as a result of the command. Most commands won't have this information, and how this
// information is used is dependent upon the interface that reads it.
//
// Current well-known uses:
// * start_child_workflow_execution_command_attributes - populates
// temporal.api.workflow.v1.WorkflowExecutionInfo.user_metadata where the summary and details
// are used by user interfaces to show fixed as-of-start workflow summary and details.
// * start_timer_command_attributes - populates temporal.api.history.v1.HistoryEvent for timer
// started where the summary is used to identify the timer.
temporal.api.sdk.v1.UserMetadata user_metadata = 301;
// The command details. The type must match that in `command_type`.
oneof attributes {
ScheduleActivityTaskCommandAttributes schedule_activity_task_command_attributes = 2;
StartTimerCommandAttributes start_timer_command_attributes = 3;
Expand Down
10 changes: 10 additions & 0 deletions temporal/api/history/v1/message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import "temporal/api/taskqueue/v1/message.proto";
import "temporal/api/update/v1/message.proto";
import "temporal/api/workflow/v1/message.proto";
import "temporal/api/sdk/v1/task_complete_metadata.proto";
import "temporal/api/sdk/v1/user_metadata.proto";

// Always the first event in workflow history
message WorkflowExecutionStartedEventAttributes {
Expand Down Expand Up @@ -892,6 +893,15 @@ message HistoryEvent {
// type which it does not understand, it must error unless this is true. If it is true, it's
// acceptable for the event type and/or attributes to be uninterpretable.
bool worker_may_ignore = 300;
// Metadata on the event. This is often carried over from commands and client calls. Most events
// won't have this information, and how this information is used is dependent upon the interface
// that reads it.
//
// Current well-known uses:
// * workflow_execution_started_event_attributes - summary and details from start workflow.
// * timer_started_event_attributes - summary represents an identifier for the timer for use by
// user interfaces.
temporal.api.sdk.v1.UserMetadata user_metadata = 301;
// The event details. The type must match that in `event_type`.
oneof attributes {
WorkflowExecutionStartedEventAttributes workflow_execution_started_event_attributes = 6;
Expand Down
49 changes: 49 additions & 0 deletions temporal/api/sdk/v1/user_metadata.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// The MIT License
//
// Copyright (c) 2024 Temporal Technologies Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

syntax = "proto3";

package temporal.api.sdk.v1;

option go_package = "go.temporal.io/api/sdk/v1;sdk";
option java_package = "io.temporal.api.sdk.v1";
option java_multiple_files = true;
option java_outer_classname = "UserMetadataProto";
option ruby_package = "Temporalio::Api::Sdk::V1";
option csharp_namespace = "Temporalio.Api.Sdk.V1";


import "temporal/api/common/v1/message.proto";

// Information a user can set, often for use by user interfaces.
message UserMetadata {
// Short-form text that provides a summary. This payload should be a "json/plain"-encoded payload
// that is a single JSON string for use in user interfaces. User interface formatting may not
// apply to this text when used in "title" situations. The payload data section is limited to 400
// bytes by default.
temporal.api.common.v1.Payload summary = 1;

// Long-form text that provides details. This payload should be a "json/plain"-encoded payload
// that is a single JSON string for use in user interfaces. User interface formatting may apply to
// this text in common use. The payload data section is limited to 20000 bytes by default.
temporal.api.common.v1.Payload details = 2;
}
13 changes: 6 additions & 7 deletions temporal/api/sdk/v1/workflow_metadata.proto
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,19 @@ option csharp_namespace = "Temporalio.Api.Sdk.V1";
message WorkflowMetadata {
// Metadata provided at declaration or creation time.
WorkflowDefinition definition = 1;
// Current long-form details of the workflow's state. This is used by user interfaces to show
// long-form text. This text may be formatted by the user interface.
string current_details = 2;
}

// (-- api-linter: core::0203::optional=disabled --)
message WorkflowDefinition {
// A name scoped by the task queue that maps to this workflow definition.
// If missing, this workflow is a dynamic workflow.
string type = 1;
// An optional workflow description provided by the application.
// By convention, external tools may interpret its first part,
// i.e., ending with a line break, as a summary of the description.
string description = 2;
repeated WorkflowInteractionDefinition query_definitions = 3;
repeated WorkflowInteractionDefinition signal_definitions = 4;
repeated WorkflowInteractionDefinition update_definitions = 5;
repeated WorkflowInteractionDefinition query_definitions = 2;
repeated WorkflowInteractionDefinition signal_definitions = 3;
repeated WorkflowInteractionDefinition update_definitions = 4;
}

// (-- api-linter: core::0123::resource-annotation=disabled
Expand Down
7 changes: 7 additions & 0 deletions temporal/api/workflow/v1/message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import "temporal/api/enums/v1/workflow.proto";
import "temporal/api/common/v1/message.proto";
import "temporal/api/failure/v1/message.proto";
import "temporal/api/taskqueue/v1/message.proto";
import "temporal/api/sdk/v1/user_metadata.proto";

message WorkflowExecutionInfo {
temporal.api.common.v1.WorkflowExecution execution = 1;
Expand Down Expand Up @@ -97,6 +98,8 @@ message WorkflowExecutionConfig {
google.protobuf.Duration workflow_execution_timeout = 2;
google.protobuf.Duration workflow_run_timeout = 3;
google.protobuf.Duration default_workflow_task_timeout = 4;
// User metadata provided on start workflow.
temporal.api.sdk.v1.UserMetadata user_metadata = 5;
}

message PendingActivityInfo {
Expand Down Expand Up @@ -197,6 +200,10 @@ message NewWorkflowExecutionInfo {
temporal.api.common.v1.Memo memo = 11;
temporal.api.common.v1.SearchAttributes search_attributes = 12;
temporal.api.common.v1.Header header = 13;
// Metadata on the workflow if it is started. This is carried over to the WorkflowExecutionConfig
// for use by user interfaces to display the fixed as-of-start summary and details of the
// workflow.
temporal.api.sdk.v1.UserMetadata user_metadata = 14;
}

// CallbackInfo contains the state of an attached workflow callback.
Expand Down
Loading

0 comments on commit de9e005

Please sign in to comment.