Skip to content

Commit 138e16b

Browse files
authored
Merge pull request #193 from cschleiden/register-by-name
Allow registering workflows and activities by name
2 parents e5f0db5 + 9652bd5 commit 138e16b

File tree

4 files changed

+78
-14
lines changed

4 files changed

+78
-14
lines changed

internal/workflow/registry.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,7 @@ func (e *ErrInvalidActivity) Error() string {
4242
return e.msg
4343
}
4444

45-
func (r *Registry) RegisterWorkflow(workflow Workflow) error {
46-
r.Lock()
47-
defer r.Unlock()
48-
45+
func (r *Registry) RegisterWorkflowByName(name string, workflow Workflow) error {
4946
wfType := reflect.TypeOf(workflow)
5047
if wfType.Kind() != reflect.Func {
5148
return &ErrInvalidWorkflow{"workflow is not a function"}
@@ -73,16 +70,20 @@ func (r *Registry) RegisterWorkflow(workflow Workflow) error {
7370
return &ErrInvalidWorkflow{"workflow must return error as last return value"}
7471
}
7572

76-
name := fn.Name(workflow)
73+
r.Lock()
74+
defer r.Unlock()
75+
7776
r.workflowMap[name] = workflow
7877

7978
return nil
8079
}
8180

82-
func (r *Registry) RegisterActivity(activity interface{}) error {
83-
r.Lock()
84-
defer r.Unlock()
81+
func (r *Registry) RegisterWorkflow(workflow Workflow) error {
82+
name := fn.Name(workflow)
83+
return r.RegisterWorkflowByName(name, workflow)
84+
}
8585

86+
func (r *Registry) RegisterActivityByName(name string, activity interface{}) error {
8687
t := reflect.TypeOf(activity)
8788

8889
// Activities on struct
@@ -95,12 +96,19 @@ func (r *Registry) RegisterActivity(activity interface{}) error {
9596
return err
9697
}
9798

98-
name := fn.Name(activity)
99+
r.Lock()
100+
defer r.Unlock()
101+
99102
r.activityMap[name] = activity
100103

101104
return nil
102105
}
103106

107+
func (r *Registry) RegisterActivity(activity interface{}) error {
108+
name := fn.Name(activity)
109+
return r.RegisterActivityByName(name, activity)
110+
}
111+
104112
func (r *Registry) registerActivitiesFromStruct(a interface{}) error {
105113
// Enumerate functions defined on a
106114
v := reflect.ValueOf(a)

internal/workflow/registry_test.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ func reg_workflow1(ctx sync.Context) error {
1515

1616
func TestRegistry_RegisterWorkflow(t *testing.T) {
1717
type args struct {
18+
name string
1819
workflow Workflow
1920
}
2021
tests := []struct {
@@ -30,6 +31,14 @@ func TestRegistry_RegisterWorkflow(t *testing.T) {
3031
},
3132
wantName: "reg_workflow1",
3233
},
34+
{
35+
name: "valid workflow by name",
36+
args: args{
37+
name: "CustomName",
38+
workflow: reg_workflow1,
39+
},
40+
wantName: "CustomName",
41+
},
3342
{
3443
name: "valid workflow with results",
3544
args: args{
@@ -74,7 +83,15 @@ func TestRegistry_RegisterWorkflow(t *testing.T) {
7483
for _, tt := range tests {
7584
t.Run(tt.name, func(t *testing.T) {
7685
r := NewRegistry()
77-
if err := r.RegisterWorkflow(tt.args.workflow); (err != nil) != tt.wantErr {
86+
var err error
87+
88+
if tt.args.name != "" {
89+
err = r.RegisterWorkflowByName(tt.args.name, tt.args.workflow)
90+
} else {
91+
err = r.RegisterWorkflow(tt.args.workflow)
92+
}
93+
94+
if (err != nil) != tt.wantErr {
7895
t.Errorf("Registry.RegisterWorkflow() error = %v, wantErr %v", err, tt.wantErr)
7996
t.FailNow()
8097
}
@@ -108,6 +125,12 @@ func Test_ActivityRegistration(t *testing.T) {
108125

109126
err = fn(context.Background())
110127
require.NoError(t, err)
128+
129+
err = r.RegisterActivityByName("CustomName", reg_activity)
130+
require.NoError(t, err)
131+
132+
x, err = r.GetActivity("CustomName")
133+
require.NoError(t, err)
111134
}
112135

113136
func reg_activity_invalid(ctx context.Context) {

tester/tester.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,13 @@ type WorkflowTester[TResult any] interface {
7979

8080
Registry() *workflow.Registry
8181

82-
OnActivity(activity interface{}, args ...interface{}) *mock.Call
82+
OnActivity(activity workflow.Activity, args ...interface{}) *mock.Call
8383

84-
OnSubWorkflow(workflow interface{}, args ...interface{}) *mock.Call
84+
OnActivityByName(name string, activity workflow.Activity, args ...interface{}) *mock.Call
85+
86+
OnSubWorkflow(workflow workflow.Workflow, args ...interface{}) *mock.Call
87+
88+
OnSubWorkflowByName(name string, workflow workflow.Workflow, args ...interface{}) *mock.Call
8589

8690
SignalWorkflow(signalName string, value interface{})
8791

@@ -238,7 +242,15 @@ func (wt *workflowTester[TResult]) ListenSubWorkflow(listener func(*core.Workflo
238242
wt.subWorkflowListener = listener
239243
}
240244

241-
func (wt *workflowTester[TResult]) OnActivity(activity interface{}, args ...interface{}) *mock.Call {
245+
func (wt *workflowTester[TResult]) OnActivityByName(name string, activity workflow.Activity, args ...interface{}) *mock.Call {
246+
// Register activity so that we can correctly identify its arguments later
247+
wt.registry.RegisterActivityByName(name, activity)
248+
249+
wt.mockedActivities[name] = true
250+
return wt.ma.On(name, args...)
251+
}
252+
253+
func (wt *workflowTester[TResult]) OnActivity(activity workflow.Activity, args ...interface{}) *mock.Call {
242254
// Register activity so that we can correctly identify its arguments later
243255
wt.registry.RegisterActivity(activity)
244256

@@ -247,7 +259,15 @@ func (wt *workflowTester[TResult]) OnActivity(activity interface{}, args ...inte
247259
return wt.ma.On(name, args...)
248260
}
249261

250-
func (wt *workflowTester[TResult]) OnSubWorkflow(workflow interface{}, args ...interface{}) *mock.Call {
262+
func (wt *workflowTester[TResult]) OnSubWorkflowByName(name string, workflow workflow.Workflow, args ...interface{}) *mock.Call {
263+
// Register workflow so that we can correctly identify its arguments later
264+
wt.registry.RegisterWorkflowByName(name, workflow)
265+
266+
wt.mockedWorkflows[name] = true
267+
return wt.mw.On(name, args...)
268+
}
269+
270+
func (wt *workflowTester[TResult]) OnSubWorkflow(workflow workflow.Workflow, args ...interface{}) *mock.Call {
251271
// Register workflow so that we can correctly identify its arguments later
252272
wt.registry.RegisterWorkflow(workflow)
253273

tester/tester_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,19 @@ func Test_Activity(t *testing.T) {
5656
tester.AssertExpectations(t)
5757
}
5858

59+
func Test_OverrideActivity(t *testing.T) {
60+
tester := NewWorkflowTester[int](workflowWithActivity)
61+
62+
tester.OnActivityByName("activity1", activity1, mock.Anything).Return(23, nil)
63+
64+
tester.Execute()
65+
66+
require.True(t, tester.WorkflowFinished())
67+
wr, _ := tester.WorkflowResult()
68+
require.Equal(t, 23, wr)
69+
tester.AssertExpectations(t)
70+
}
71+
5972
func Test_FailingActivity(t *testing.T) {
6073
tester := NewWorkflowTester[int](workflowWithActivity)
6174

0 commit comments

Comments
 (0)