-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* try afterBoth * update after_both * ActionToFunc * more tweaks * remove afterAll, ready to merge to main * code coverage * update comments
- Loading branch information
Showing
6 changed files
with
150 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package asynctask | ||
|
||
import "context" | ||
|
||
// AfterBothFunc is a function that has 2 input. | ||
type AfterBothFunc[T, S, R any] func(context.Context, *T, *S) (*R, error) | ||
|
||
// AfterBoth runs the function after both 2 input task finished, and will be fed with result from 2 input task. | ||
// if one of the input task failed, the AfterBoth task will be failed and returned, even other one are still running. | ||
func AfterBoth[T, S, R any](ctx context.Context, tskT *Task[T], tskS *Task[S], next AfterBothFunc[T, S, R]) *Task[R] { | ||
return Start(ctx, func(fCtx context.Context) (*R, error) { | ||
t, err := tskT.Result(fCtx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
s, err := tskS.Result(fCtx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return next(fCtx, t, s) | ||
}) | ||
} | ||
|
||
// AfterBothActionToFunc convert a Action to Func (C# term), to satisfy the AfterBothFunc interface. | ||
// Action is function that runs without return anything | ||
// Func is function that runs and return something | ||
func AfterBothActionToFunc[T, S any](action func(context.Context, *T, *S) error) func(context.Context, *T, *S) (*interface{}, error) { | ||
return func(ctx context.Context, t *T, s *S) (*interface{}, error) { | ||
return nil, action(ctx, t, s) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package asynctask_test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/Azure/go-asynctask" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func summarize2CountingTask(ctx context.Context, result1, result2 *int) (*int, error) { | ||
t := ctx.Value(testContextKey).(*testing.T) | ||
t.Logf("result1: %d", result1) | ||
t.Logf("result2: %d", result2) | ||
sum := *result1 + *result2 | ||
t.Logf("sum: %d", sum) | ||
return &sum, nil | ||
} | ||
|
||
func TestAfterBoth(t *testing.T) { | ||
t.Parallel() | ||
ctx := newTestContext(t) | ||
t1 := asynctask.Start(ctx, getCountingTask(10, "afterboth.P1", 20*time.Millisecond)) | ||
t2 := asynctask.Start(ctx, getCountingTask(10, "afterboth.P2", 20*time.Millisecond)) | ||
t3 := asynctask.AfterBoth(ctx, t1, t2, summarize2CountingTask) | ||
|
||
sum, err := t3.Result(ctx) | ||
assert.NoError(t, err) | ||
assert.Equal(t, asynctask.StateCompleted, t3.State(), "Task should complete with no error") | ||
assert.Equal(t, *sum, 18, "Sum should be 18") | ||
} | ||
|
||
func TestAfterBothFailureCase(t *testing.T) { | ||
t.Parallel() | ||
ctx := newTestContext(t) | ||
errTask := asynctask.Start(ctx, getErrorTask("devide by 0", 10*time.Millisecond)) | ||
countingTask := asynctask.Start(ctx, getCountingTask(10, "afterboth.P1", 20*time.Millisecond)) | ||
|
||
task1Err := asynctask.AfterBoth(ctx, errTask, countingTask, summarize2CountingTask) | ||
_, err := task1Err.Result(ctx) | ||
assert.Error(t, err) | ||
|
||
task2Err := asynctask.AfterBoth(ctx, errTask, countingTask, summarize2CountingTask) | ||
_, err = task2Err.Result(ctx) | ||
assert.Error(t, err) | ||
|
||
task3NoErr := asynctask.AfterBoth(ctx, countingTask, countingTask, summarize2CountingTask) | ||
_, err = task3NoErr.Result(ctx) | ||
assert.NoError(t, err) | ||
} | ||
|
||
func TestAfterBothActionToFunc(t *testing.T) { | ||
t.Parallel() | ||
ctx := newTestContext(t) | ||
|
||
countingTask1 := asynctask.Start(ctx, getCountingTask(10, "afterboth.P1", 20*time.Millisecond)) | ||
countingTask2 := asynctask.Start(ctx, getCountingTask(10, "afterboth.P2", 20*time.Millisecond)) | ||
t2 := asynctask.AfterBoth(ctx, countingTask1, countingTask2, asynctask.AfterBothActionToFunc(func(ctx context.Context, result1, result2 *int) error { | ||
t := ctx.Value(testContextKey).(*testing.T) | ||
t.Logf("result1: %d", result1) | ||
t.Logf("result2: %d", result2) | ||
sum := *result1 + *result2 | ||
t.Logf("sum: %d", sum) | ||
return nil | ||
})) | ||
_, err := t2.Result(ctx) | ||
assert.NoError(t, err) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters