Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
TEMPORAL_CLOUD_MTLS_TEST_CLIENT_KEY: ${{ secrets.TEMPORAL_CLIENT_KEY }}

# For API key tests
TEMPORAL_CLOUD_API_KEY_TEST_TARGET_HOST: us-west-2.aws.api.temporal.io:7233
TEMPORAL_CLOUD_API_KEY_TEST_TARGET_HOST: us-east-1.aws.api.temporal.io:7233
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, why was this needed?

TEMPORAL_CLOUD_API_KEY_TEST_NAMESPACE: ${{ vars.TEMPORAL_CLIENT_NAMESPACE }}
TEMPORAL_CLOUD_API_KEY_TEST_API_KEY: ${{ secrets.TEMPORAL_CLIENT_CLOUD_API_KEY }}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ def to_payload(value, hint: nil)

# Convert payload to Ruby value based on its +encoding+ metadata on the payload.
#
# @param payload [Api::Common::V1::Payload] Payload to convert.
# @param payload [Api::Common::V1::Payload, nil] Payload to convert.
# @param hint [Object, nil] Hint, if any, to assist conversion.
# @return [Object] Converted Ruby value.
# @return [Object, nil] Converted Ruby value.
# @raise [EncodingNotSet] If encoding not set on the metadata.
# @raise [ConverterNotFound] If no converter found for the encoding.
def from_payload(payload, hint: nil)
return nil unless payload

encoding = payload.metadata['encoding']
raise EncodingNotSet, 'Missing payload encoding' unless encoding

Expand Down
16 changes: 11 additions & 5 deletions temporalio/sig/temporalio/converters/data_converter.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,20 @@ module Temporalio
?payload_codec: PayloadCodec?
) -> void

def to_payload: (Object? value, ?hint: Object?) -> untyped
def to_payloads: (Array[Object?] values, ?hints: Array[Object]?) -> untyped
def to_payload: (Object? value, ?hint: Object?) -> Temporalio::Api::Common::V1::Payload
def to_payloads: (
Array[Object?] values,
?hints: Array[Object]?
) -> Temporalio::Api::Common::V1::Payloads

def from_payload: (untyped payload, ?hint: Object?) -> Object?
def from_payloads: (untyped payloads, ?hints: Array[Object]?) -> Array[Object?]
def from_payload: (Temporalio::Api::Common::V1::Payload payload, ?hint: Object?) -> Object?
def from_payloads: (
Temporalio::Api::Common::V1::Payloads payloads,
?hints: Array[Object]?
) -> Array[Object?]

def to_failure: (Exception error) -> untyped
def from_failure: (untyped failure) -> Exception
end
end
end
end
16 changes: 11 additions & 5 deletions temporalio/sig/temporalio/converters/payload_converter.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@ module Temporalio
?json_generate_options: Hash[Symbol, untyped]
) -> Composite

def to_payload: (Object? value, ?hint: Object?) -> untyped
def to_payloads: (Array[Object?] values, ?hints: Array[Object]?) -> untyped
def to_payload: (Object? value, ?hint: Object?) -> Temporalio::Api::Common::V1::Payload
def to_payloads: (
Array[Object?] values,
?hints: Array[Object]?
) -> Temporalio::Api::Common::V1::Payloads

def from_payload: (untyped payload, ?hint: Object?) -> Object?
def from_payloads: (untyped payloads, ?hints: Array[Object]?) -> Array[Object?]
def from_payload: (Temporalio::Api::Common::V1::Payload? payload, ?hint: Object?) -> Object?
def from_payloads: (
Temporalio::Api::Common::V1::Payloads payloads,
?hints: Array[Object]?
) -> Array[Object?]
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ module Temporalio
class Encoding
def encoding: -> String

def to_payload: (Object? value, ?hint: Object?) -> untyped?
def to_payload: (Object? value, ?hint: Object?) -> Temporalio::Api::Common::V1::Payload?

def from_payload: (untyped payload, ?hint: Object?) -> Object?
def from_payload: (Temporalio::Api::Common::V1::Payload payload, ?hint: Object?) -> Object?
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ module Temporalio
result_hint: Object?
) -> void

def _resolve: (untyped resolution) -> void
def _resolve: (
Temporalio::Internal::Bridge::Api::ChildWorkflow::ChildWorkflowResult resolution
) -> void
end
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ module Temporalio
end
end
end
end
end
4 changes: 4 additions & 0 deletions temporalio/test/converters/payload_converter_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ def test_default_converter
assert_equal 'temporal.api.common.v1.WorkflowExecution', payload.metadata['messageType']
end

def test_missing_payload_decodes_to_nil
assert_nil Temporalio::Converters::PayloadConverter.default.from_payload(nil)
end

def test_binary_proto
# Make a new converter with all default converters except json proto so
# that binary proto takes precedent
Expand Down
11 changes: 11 additions & 0 deletions temporalio/test/golangworker/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"github.com/nexus-rpc/sdk-go/nexus"
"go.temporal.io/sdk/activity"
"go.temporal.io/sdk/client"
sdklog "go.temporal.io/sdk/log"
"go.temporal.io/sdk/temporal"
Expand Down Expand Up @@ -72,6 +73,14 @@ func NexusHandlerWorkflow(ctx workflow.Context, input NexusHandlerInput) (NexusH
}
}

func NoResultWorkflow(ctx workflow.Context) error {
return nil
}

func NoResultActivity(context.Context) error {
return nil
}

func main() {
if len(os.Args) != 4 {
log.Fatalf("expected endpoint, namespace, and task queue arg, found %v args", len(os.Args)-1)
Expand All @@ -97,6 +106,8 @@ func run(endpoint, namespace, taskQueue string) error {
w := worker.New(cl, taskQueue, worker.Options{})
w.RegisterWorkflowWithOptions(KitchenSinkWorkflow, workflow.RegisterOptions{Name: "kitchen_sink"})
w.RegisterWorkflowWithOptions(NexusHandlerWorkflow, workflow.RegisterOptions{Name: "nexus_handler"})
w.RegisterWorkflowWithOptions(NoResultWorkflow, workflow.RegisterOptions{Name: "no_result"})
w.RegisterActivityWithOptions(NoResultActivity, activity.RegisterOptions{Name: "no_result_activity"})

// Register Nexus service
nexusService := nexus.NewService("test-service")
Expand Down
6 changes: 6 additions & 0 deletions temporalio/test/sig/workflow_utils.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,10 @@ module WorkflowUtils
handle: Temporalio::Client::WorkflowHandle,
?message_contains: String?
) -> void

def assert_eventually_complete: (
handle: Temporalio::Client::WorkflowHandle,
?timeout: Float,
?interval: Float
) -> untyped
end
18 changes: 18 additions & 0 deletions temporalio/test/worker_workflow_activity_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,24 @@ def test_simple
execute_workflow(SimpleWorkflow, :local_string_name, activities: [SimpleActivity])
end

class GoNoResultActivityWorkflow < Temporalio::Workflow::Definition
def execute(activity_task_queue)
Temporalio::Workflow.execute_activity(
'no_result_activity',
task_queue: activity_task_queue,
start_to_close_timeout: 10
)
end
end

def test_activity_without_result_from_go_sdk
env.with_kitchen_sink_worker do |activity_task_queue|
execute_workflow(GoNoResultActivityWorkflow, activity_task_queue) do |handle|
assert_nil assert_eventually_complete(handle:)
end
end
end

class FailureActivity < Temporalio::Activity::Definition
def execute
raise Temporalio::Error::ApplicationError.new('Intentional error', 'detail1', 'detail2', non_retryable: true)
Expand Down
14 changes: 14 additions & 0 deletions temporalio/test/worker_workflow_child_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,20 @@ def test_search_attributes
assert_equal({ ATTR_KEY_TEXT.name => 'changed-text', ATTR_KEY_KEYWORD.name => 'some-keyword' }, results)
end

class GoNoResultParentWorkflow < Temporalio::Workflow::Definition
def execute(child_task_queue)
Temporalio::Workflow.execute_child_workflow('no_result', task_queue: child_task_queue)
end
end

def test_child_workflow_without_result_from_go_sdk
env.with_kitchen_sink_worker do |child_task_queue|
execute_workflow(GoNoResultParentWorkflow, child_task_queue) do |handle|
assert_nil assert_eventually_complete(handle:)
end
end
end

class ManyChildrenActivity < Temporalio::Activity::Definition
def execute(name)
"Hello #{name}"
Expand Down
21 changes: 21 additions & 0 deletions temporalio/test/workflow_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,25 @@ def assert_eventually_task_fail(handle:, message_contains: nil)
event
end
end

def assert_eventually_complete(handle:, timeout: 10, interval: 0.2)
start_time = Time.now
loop do
events = handle.fetch_history_events

task_fail_event = events.find(&:workflow_task_failed_event_attributes)
if task_fail_event
flunk(
'Workflow task failed instead of completing: ' \
"#{task_fail_event.workflow_task_failed_event_attributes.failure.message}"
)
end

return handle.result if events.any?(&:workflow_execution_completed_event_attributes)

flunk('Timed out waiting for workflow completion') if Time.now - start_time > timeout

sleep(interval)
end
end
end
Loading