coinbase / temporal-ruby

Ruby SDK for Temporal
Apache License 2.0
213 stars 81 forks source link

Add missing arguments to Temporal.reset_workflow and add integration tests for Resets #256

Closed jazev-stripe closed 11 months ago

jazev-stripe commented 11 months ago

This PR adds two arguments present on the ResetWorkflowExecutionRequest Protobuf message to the Temporal.reset_workflow API:

This PR also adds integration tests for workflow resets, including tests for each of the above added arguments.

Note: backwards compatibility

I attempted to make the API changes backwards compatible. However, I'm not sure if the Temporal.reset_workflow is used much in production, anyways, because I believe it has been broken ever since Temporal Server v1.14.0 made the change that the request_id field must not be empty (in https://github.com/temporalio/temporal/pull/2141). Before my PR, temporal-ruby wasn't setting this field on the Protobuf object, causing it to use the zero value (empty string). This caused the Temporal Server to always respond with a gRPC "invalid argument" error.

I fixed this in this PR by falling back to a random UUID if the request_id is not specified. This is consistent with what the Go SDK does (source).

Reproduction of broken behavior

This can be reproduced by:

  1. Checking out any tag on https://github.com/temporalio/docker-compose after v1.14.0 (inclusive), and running docker-compose up

  2. Creating the example namespace ((cd examples && ./bin/register_namespace ruby-samples))

  3. Running the example worker ((cd examples && ./bin/worker)

  4. Running (cd examples && ./bin/trigger QueryWorkflow). Note the workflow_id for the workflow this starts:

    $ (cd examples && ./bin/trigger QueryWorkflow)                                                                                                                                                                                                    
    I, [2023-07-11T16:22:25.593108 #603]  INFO -- temporal_client: Started workflow {"workflow_id":"bd442477-7348-428e-b40f-89793471a071","run_id":"14b8f6f5-6e6b-4f8d-ba96-d6c449fdbb34"}
    
    # Store the workflow_id:
    $ workflow_id="bd442477-7348-428e-b40f-89793471a071"
  5. Running (cd examples && ./bin/reset ruby-samples "$workflow_id"):

    $ (cd examples && ./bin/reset ruby-samples "$workflow_id")
    Traceback (most recent call last):
        ...
    .../gems/grpc-1.56.0/src/ruby/lib/grpc/generic/active_call.rb:29:in `check_status': 3:RequestId is not set on request.. debug_error_string:{UNKNOWN:Error received from peer  {grpc_message:"RequestId is not set on request.", grpc_status:3, created_time:"2023-07-11T16:20:36.345632-07:00"}} (GRPC::InvalidArgument)