Skip to content

Commit

Permalink
Shift replayer to prefer io.Reader rather than filenames (#1234)
Browse files Browse the repository at this point in the history
This allows us to move to `//go:embed` or use hard-coded strings (or any other data-source).
Short-term plans are to use go:embed to read files once / not require runtime access to files, only build.
  • Loading branch information
Groxx authored Mar 20, 2023
1 parent 610f39f commit 6ad9a67
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 17 deletions.
51 changes: 34 additions & 17 deletions internal/workflow_replayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"math"
"os"

"github.com/golang/mock/gomock"
"github.com/opentracing/opentracing-go"
"github.com/pborman/uuid"
Expand All @@ -37,8 +41,6 @@ import (
"go.uber.org/cadence/internal/common/backoff"
"go.uber.org/cadence/internal/common/serializer"
"go.uber.org/zap"
"io/ioutil"
"math"
)

const (
Expand Down Expand Up @@ -133,19 +135,12 @@ func (r *WorkflowReplayer) ReplayWorkflowHistory(logger *zap.Logger, history *sh
return r.replayWorkflowHistory(logger, service, replayDomainName, nil, history, nil)
}

// ReplayWorkflowHistoryFromJSONFile executes a single decision task for the given json history file.
// Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
// The logger is an optional parameter. Defaults to the noop logger.
func (r *WorkflowReplayer) ReplayWorkflowHistoryFromJSONFile(logger *zap.Logger, jsonfileName string) error {
return r.ReplayPartialWorkflowHistoryFromJSONFile(logger, jsonfileName, 0)
func (r *WorkflowReplayer) ReplayWorkflowHistoryFromJSON(logger *zap.Logger, reader io.Reader) error {
return r.ReplayPartialWorkflowHistoryFromJSON(logger, reader, 0)
}

// ReplayPartialWorkflowHistoryFromJSONFile executes a single decision task for the given json history file up to provided
// lastEventID(inclusive).
// Use for testing backwards compatibility of code changes and troubleshooting workflows in a debugger.
// The logger is an optional parameter. Defaults to the noop logger.
func (r *WorkflowReplayer) ReplayPartialWorkflowHistoryFromJSONFile(logger *zap.Logger, jsonfileName string, lastEventID int64) error {
history, err := extractHistoryFromFile(jsonfileName, lastEventID)
func (r *WorkflowReplayer) ReplayPartialWorkflowHistoryFromJSON(logger *zap.Logger, reader io.Reader, lastEventID int64) error {
history, err := extractHistoryFromReader(reader, lastEventID)

if err != nil {
return err
Expand All @@ -162,6 +157,28 @@ func (r *WorkflowReplayer) ReplayPartialWorkflowHistoryFromJSONFile(logger *zap.
return r.replayWorkflowHistory(logger, service, replayDomainName, nil, history, nil)
}

// ReplayWorkflowHistoryFromJSONFile executes a single decision task for the given json history file.
// Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
// The logger is an optional parameter. Defaults to the noop logger.
func (r *WorkflowReplayer) ReplayWorkflowHistoryFromJSONFile(logger *zap.Logger, jsonfileName string) error {
return r.ReplayPartialWorkflowHistoryFromJSONFile(logger, jsonfileName, 0)
}

// ReplayPartialWorkflowHistoryFromJSONFile executes a single decision task for the given json history file up to provided
// lastEventID(inclusive).
// Use for testing backwards compatibility of code changes and troubleshooting workflows in a debugger.
// The logger is an optional parameter. Defaults to the noop logger.
func (r *WorkflowReplayer) ReplayPartialWorkflowHistoryFromJSONFile(logger *zap.Logger, jsonfileName string, lastEventID int64) error {
file, err := os.Open(jsonfileName)
if err != nil {
return fmt.Errorf("could not open file: %w", err)
}
defer func() {
_ = file.Close()
}()
return r.ReplayPartialWorkflowHistoryFromJSON(logger, file, lastEventID)
}

// ReplayWorkflowExecution replays workflow execution loading it from Cadence service.
// The logger is an optional parameter. Defaults to the noop logger.
func (r *WorkflowReplayer) ReplayWorkflowExecution(
Expand Down Expand Up @@ -336,17 +353,17 @@ func (r *WorkflowReplayer) replayWorkflowHistory(
return fmt.Errorf("replay workflow doesn't return the same result as the last event, resp: %v, last: %v", resp, last)
}

func extractHistoryFromFile(jsonfileName string, lastEventID int64) (*shared.History, error) {
raw, err := ioutil.ReadFile(jsonfileName)
func extractHistoryFromReader(r io.Reader, lastEventID int64) (*shared.History, error) {
raw, err := io.ReadAll(r)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to read data: %w", err)
}

var deserializedEvents []*shared.HistoryEvent
err = json.Unmarshal(raw, &deserializedEvents)

if err != nil {
return nil, err
return nil, fmt.Errorf("invalid json contents: %w", err)
}

if lastEventID <= 0 {
Expand Down
22 changes: 22 additions & 0 deletions worker/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ package worker

import (
"context"
"io"

"go.uber.org/cadence/.gen/go/cadence/workflowserviceclient"
"go.uber.org/cadence/.gen/go/shared"
Expand Down Expand Up @@ -151,6 +152,8 @@ type (
// See https://github.com/uber/cadence/blob/master/tools/cli/README.md for full documentation
// Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
// The logger is an optional parameter. Defaults to the noop logger.
//
// Deprecated: prefer ReplayWorkflowHistoryFromJSON
ReplayWorkflowHistoryFromJSONFile(logger *zap.Logger, jsonfileName string) error

// ReplayPartialWorkflowHistoryFromJSONFile executes a single decision task for the json history file upto provided
Expand All @@ -159,12 +162,31 @@ type (
// See https://github.com/uber/cadence/blob/master/tools/cli/README.md for full documentation
// Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
// The logger is an optional parameter. Defaults to the noop logger.
//
// Deprecated: prefer ReplayPartialWorkflowHistoryFromJSON
ReplayPartialWorkflowHistoryFromJSONFile(logger *zap.Logger, jsonfileName string, lastEventID int64) error

// ReplayWorkflowExecution loads a workflow execution history from the Cadence service and executes a single decision task for it.
// Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
// The logger is the only optional parameter. Defaults to the noop logger.
ReplayWorkflowExecution(ctx context.Context, service workflowserviceclient.Interface, logger *zap.Logger, domain string, execution workflow.Execution) error

// ReplayWorkflowHistoryFromJSON executes a single decision task for the json history file downloaded from the cli.
// To download the history file:
// cadence workflow showid <workflow_id> -of <output_filename>
// See https://github.com/uber/cadence/blob/master/tools/cli/README.md for full documentation
// Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
// The logger is an optional parameter. Defaults to the noop logger.
ReplayWorkflowHistoryFromJSON(logger *zap.Logger, reader io.Reader) error

// ReplayPartialWorkflowHistoryFromJSON executes a single decision task for the json history file upto provided
// lastEventID(inclusive), downloaded from the cli.
// To download the history file:
// cadence workflow showid <workflow_id> -of <output_filename>
// See https://github.com/uber/cadence/blob/master/tools/cli/README.md for full documentation
// Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
// The logger is an optional parameter. Defaults to the noop logger.
ReplayPartialWorkflowHistoryFromJSON(logger *zap.Logger, reader io.Reader, lastEventID int64) error
}

// WorkflowShadower retrieves and replays workflow history from Cadence service to determine if there's any nondeterministic changes in the workflow definition
Expand Down

0 comments on commit 6ad9a67

Please sign in to comment.