func NewWorkflowShadower(
	service workflowserviceclient.Interface,
	domain string,
	shadowOptions ShadowOptions,
	replayOptions ReplayOptions,
	logger *zap.Logger,
) (*WorkflowShadower, error) {
	if len(domain) == 0 {
		return nil, errors.New("domain is not set")
	}
	if err := shadowOptions.validateAndPopulateFields(); err != nil {
		return nil, err
	}
	if shadowOptions.Concurrency > 1 {
		return nil, errors.New("local workflow shadower doesn't support concurrency > 1")
	}
	if logger == nil {
		logger = zap.NewNop()
	}
	return &WorkflowShadower{
		service:       service,
		domain:        domain,
		shadowOptions: shadowOptions,
		logger:        logger,
		replayer:      NewWorkflowReplayerWithOptions(replayOptions),
		status:     statusInitialized,
		shutdownCh: make(chan struct{}),
		clock: clock.New(),
	}, nil
}
NewWorkflowShadower creates an instance of the WorkflowShadower for testing
The logger is an optional parameter. Defaults to noop logger if not provided and will override the logger in WorkerOptions
package internal
import (
	"context"
	"errors"
	"fmt"
	"math"
	"math/rand"
	"sync"
	"sync/atomic"
	"time"
	"github.com/facebookgo/clock"
	"go.uber.org/cadence/.gen/go/cadence/workflowserviceclient"
	"go.uber.org/cadence/.gen/go/shadower"
	"go.uber.org/cadence/internal/common"
	"go.uber.org/cadence/internal/common/util"
	"go.uber.org/zap"
)
const (
	statusInitialized int32 = 0
	statusStarted     int32 = 1
	statusStopped     int32 = 2
)
const (
	defaultWaitDurationPerIteration = 5 * time.Minute
)
type (
	ShadowOptions struct {
		WorkflowQuery string
		WorkflowTypes []string
		WorkflowStatus []string
		WorkflowStartTimeFilter TimeFilter
		SamplingRate float64
		Mode ShadowMode
		ExitCondition ShadowExitCondition
		Concurrency int
	}
	TimeFilter struct {
		MinTimestamp time.Time
		MaxTimestamp time.Time
	}
	ShadowMode int
	ShadowExitCondition struct {
		ExpirationInterval time.Duration
		ShadowCount int
	}
	WorkflowShadower struct {
		service       workflowserviceclient.Interface
		domain        string
		shadowOptions ShadowOptions
		logger        *zap.Logger
		replayer      *WorkflowReplayer
		status     int32
		shutdownCh chan struct{}
		shutdownWG sync.WaitGroup
		clock clock.Clock
	}
)
const (
	ShadowModeNormal ShadowMode = iota
	ShadowModeContinuous
)