mirror of https://github.com/dapr/go-sdk.git
Merge branch 'main' into dependabot/go_modules/dot-github/workflows/dapr-bot/golang.org/x/crypto-0.35.0
This commit is contained in:
commit
ba8e2627cc
|
|
@ -17,7 +17,7 @@ jobs:
|
|||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GOLANGCILINT_VER: v1.61.0
|
||||
GOLANGCILINT_VER: v1.64.6
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ jobs:
|
|||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GOLANGCILINT_VER: v1.61.0
|
||||
GOLANGCILINT_VER: v1.64.6
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ jobs:
|
|||
- "macos-latest"
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
GOLANGCILINT_VER: v1.61.0 # Make sure to bump /tools/check-lint-version/main_test.go
|
||||
GOLANGCILINT_VER: v1.64.6 # Make sure to bump /tools/check-lint-version/main_test.go
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ jobs:
|
|||
CHECKOUT_REF: ${{ github.ref }}
|
||||
outputs:
|
||||
DAPR_INSTALL_URL: ${{ env.DAPR_INSTALL_URL }}
|
||||
DAPR_CLI_VER: ${{ steps.outputs.outputs.DAPR_CLI_VER }}
|
||||
DAPR_CLI_VER: 1.16.0-rc.1
|
||||
DAPR_CLI_REF: ${{ steps.outputs.outputs.DAPR_CLI_REF }}
|
||||
DAPR_RUNTIME_VER: ${{ steps.outputs.outputs.DAPR_RUNTIME_VER }}
|
||||
DAPR_RUNTIME_VER: 1.16.0-rc.3
|
||||
CHECKOUT_REPO: ${{ steps.outputs.outputs.CHECKOUT_REPO }}
|
||||
CHECKOUT_REF: ${{ steps.outputs.outputs.CHECKOUT_REF }}
|
||||
DAPR_REF: ${{ steps.outputs.outputs.DAPR_REF }}
|
||||
|
|
@ -166,7 +166,7 @@ jobs:
|
|||
"configuration",
|
||||
"conversation",
|
||||
"crypto",
|
||||
"dist-scheduler",
|
||||
"jobs",
|
||||
"grpc-service",
|
||||
"hello-world",
|
||||
"pubsub",
|
||||
|
|
@ -175,6 +175,7 @@ jobs:
|
|||
"socket",
|
||||
"workflow",
|
||||
"workflow-parallel",
|
||||
"workflow-taskexecutionid"
|
||||
]
|
||||
steps:
|
||||
- name: Check out code onto GOPATH
|
||||
|
|
|
|||
|
|
@ -234,7 +234,6 @@ linters:
|
|||
- lll
|
||||
- unparam
|
||||
- wsl
|
||||
- gomnd
|
||||
- testpackage
|
||||
- nestif
|
||||
- nlreturn
|
||||
|
|
@ -271,8 +270,6 @@ linters:
|
|||
- tagalign
|
||||
- mnd
|
||||
- canonicalheader
|
||||
- exportloopref
|
||||
- execinquery
|
||||
- err113
|
||||
- fatcontext
|
||||
- forbidigo # TODO: Re-enable and remove fmt.println
|
||||
4
Makefile
4
Makefile
|
|
@ -33,6 +33,10 @@ cover: ## Displays test coverage in the client and service packages
|
|||
lint: check-lint ## Lints the entire project
|
||||
golangci-lint run --timeout=3m
|
||||
|
||||
.PHONY: lint-fix
|
||||
lint-fix: check-lint ## Lints the entire project
|
||||
golangci-lint run --timeout=3m --fix
|
||||
|
||||
.PHONY: check-lint
|
||||
check-lint: ## Compares the locally installed linter with the workflow version
|
||||
cd ./tools/check-lint-version && \
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ func TestRegisterActorFactoryAndInvokeMethod(t *testing.T) {
|
|||
mockServer.EXPECT().RegisterActorImplFactory(gomock.Any())
|
||||
rt.RegisterActorFactory(actorMock.ActorImplFactory)
|
||||
|
||||
//nolint:usetesting
|
||||
mockServer.EXPECT().InvokeMethod(context.Background(), "mockActorID", "Invoke", []byte("param")).Return([]byte("response"), actorErr.Success)
|
||||
rspData, err := rt.InvokeActorMethod("testActorType", "mockActorID", "Invoke", []byte("param"))
|
||||
|
||||
|
|
@ -89,6 +90,7 @@ func TestInvokeReminder(t *testing.T) {
|
|||
mockServer.EXPECT().RegisterActorImplFactory(gomock.Any())
|
||||
rt.RegisterActorFactory(actorMock.ActorImplFactory)
|
||||
|
||||
//nolint:usetesting
|
||||
mockServer.EXPECT().InvokeReminder(context.Background(), "mockActorID", "mockReminder", []byte("param")).Return(actorErr.Success)
|
||||
err = rt.InvokeReminder("testActorType", "mockActorID", "mockReminder", []byte("param"))
|
||||
|
||||
|
|
@ -109,6 +111,7 @@ func TestInvokeTimer(t *testing.T) {
|
|||
mockServer.EXPECT().RegisterActorImplFactory(gomock.Any())
|
||||
rt.RegisterActorFactory(actorMock.ActorImplFactory)
|
||||
|
||||
//nolint:usetesting
|
||||
mockServer.EXPECT().InvokeTimer(context.Background(), "mockActorID", "mockTimer", []byte("param")).Return(actorErr.Success)
|
||||
err = rt.InvokeTimer("testActorType", "mockActorID", "mockTimer", []byte("param"))
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ limitations under the License.
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -25,7 +24,7 @@ import (
|
|||
const testActorType = "test"
|
||||
|
||||
func TestInvokeActor(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
in := &InvokeActorRequest{
|
||||
ActorID: "fn",
|
||||
Method: "mockMethod",
|
||||
|
|
@ -74,7 +73,7 @@ func TestInvokeActor(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRegisterActorReminder(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
in := &RegisterActorReminderRequest{
|
||||
ActorID: "fn",
|
||||
Data: []byte(`{hello}`),
|
||||
|
|
@ -137,7 +136,7 @@ func TestRegisterActorReminder(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRegisterActorTimer(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
in := &RegisterActorTimerRequest{
|
||||
ActorID: "fn",
|
||||
Data: []byte(`{hello}`),
|
||||
|
|
@ -215,7 +214,7 @@ func TestRegisterActorTimer(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUnregisterActorReminder(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
in := &UnregisterActorReminderRequest{
|
||||
ActorID: "fn",
|
||||
ActorType: testActorType,
|
||||
|
|
@ -260,7 +259,7 @@ func TestUnregisterActorReminder(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUnregisterActorTimer(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
in := &UnregisterActorTimerRequest{
|
||||
ActorID: "fn",
|
||||
ActorType: testActorType,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ limitations under the License.
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -25,7 +24,7 @@ import (
|
|||
// go test -timeout 30s ./client -count 1 -run ^TestInvokeBinding$
|
||||
|
||||
func TestInvokeBinding(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
in := &InvokeBindingRequest{
|
||||
Name: "test",
|
||||
Operation: "fn",
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ func NewClientWithAddressContext(ctx context.Context, address string) (client Cl
|
|||
return nil, fmt.Errorf("error parsing address '%s': %w", address, err)
|
||||
}
|
||||
|
||||
at := &authToken{}
|
||||
at := newAuthToken()
|
||||
|
||||
opts := []grpc.DialOption{
|
||||
grpc.WithUserAgent(userAgent()),
|
||||
|
|
@ -404,7 +404,7 @@ func NewClientWithSocket(socket string) (client Client, err error) {
|
|||
if socket == "" {
|
||||
return nil, errors.New("nil socket")
|
||||
}
|
||||
at := &authToken{}
|
||||
at := newAuthToken()
|
||||
logger.Printf("dapr client initializing for: %s", socket)
|
||||
addr := "unix://" + socket
|
||||
conn, err := grpc.Dial( //nolint:staticcheck
|
||||
|
|
@ -421,11 +421,6 @@ func NewClientWithSocket(socket string) (client Client, err error) {
|
|||
}
|
||||
|
||||
func newClientWithConnection(conn *grpc.ClientConn, authToken *authToken) Client {
|
||||
apiToken := os.Getenv(apiTokenEnvVarName)
|
||||
if apiToken != "" {
|
||||
logger.Println("client uses API token")
|
||||
authToken.set(apiToken)
|
||||
}
|
||||
return &GRPCClient{
|
||||
connection: conn,
|
||||
protoClient: pb.NewDaprClient(conn),
|
||||
|
|
@ -435,14 +430,26 @@ func newClientWithConnection(conn *grpc.ClientConn, authToken *authToken) Client
|
|||
|
||||
// NewClientWithConnection instantiates Dapr client using specific connection.
|
||||
func NewClientWithConnection(conn *grpc.ClientConn) Client {
|
||||
return newClientWithConnection(conn, &authToken{})
|
||||
return newClientWithConnection(conn, newAuthToken())
|
||||
}
|
||||
|
||||
// NOTE: authToken must be created using newAuthToken()
|
||||
// it is crucial to correctly initialize the dapr client with the API token from the environment variable
|
||||
type authToken struct {
|
||||
mu sync.RWMutex
|
||||
authToken string
|
||||
}
|
||||
|
||||
func newAuthToken() *authToken {
|
||||
apiToken := os.Getenv(apiTokenEnvVarName)
|
||||
if apiToken != "" {
|
||||
logger.Println("API Token loaded from the environment variable")
|
||||
}
|
||||
return &authToken{
|
||||
authToken: apiToken,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *authToken) get() string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import (
|
|||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/test/bufconn"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
|
||||
commonv1pb "github.com/dapr/dapr/pkg/proto/common/v1"
|
||||
|
|
@ -98,7 +99,7 @@ func TestNewClient(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("new client with trace ID", func(t *testing.T) {
|
||||
_ = testClient.WithTraceID(context.Background(), "test")
|
||||
_ = testClient.WithTraceID(t.Context(), "test")
|
||||
})
|
||||
|
||||
t.Run("new socket client closed with token", func(t *testing.T) {
|
||||
|
|
@ -120,13 +121,13 @@ func TestNewClient(t *testing.T) {
|
|||
c, err := NewClientWithSocket(testSocket)
|
||||
require.NoError(t, err)
|
||||
defer c.Close()
|
||||
ctx := c.WithTraceID(context.Background(), "")
|
||||
ctx := c.WithTraceID(t.Context(), "")
|
||||
_ = c.WithTraceID(ctx, "test")
|
||||
})
|
||||
}
|
||||
|
||||
func TestShutdown(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
t.Run("shutdown", func(t *testing.T) {
|
||||
err := testClient.Shutdown(ctx)
|
||||
|
|
@ -563,10 +564,11 @@ func (s *testDaprServer) ScheduleJobAlpha1(ctx context.Context, in *pb.ScheduleJ
|
|||
|
||||
func (s *testDaprServer) GetJobAlpha1(ctx context.Context, in *pb.GetJobRequest) (*pb.GetJobResponse, error) {
|
||||
var (
|
||||
schedule = "@every 10s"
|
||||
dueTime = "10s"
|
||||
repeats uint32 = 4
|
||||
ttl = "10s"
|
||||
schedule = "@every 10s"
|
||||
dueTime = "10s"
|
||||
repeats uint32 = 4
|
||||
ttl = "10s"
|
||||
maxRetries uint32 = 4
|
||||
)
|
||||
return &pb.GetJobResponse{
|
||||
Job: &pb.Job{
|
||||
|
|
@ -576,6 +578,14 @@ func (s *testDaprServer) GetJobAlpha1(ctx context.Context, in *pb.GetJobRequest)
|
|||
DueTime: &dueTime,
|
||||
Ttl: &ttl,
|
||||
Data: nil,
|
||||
FailurePolicy: &commonv1pb.JobFailurePolicy{
|
||||
Policy: &commonv1pb.JobFailurePolicy_Constant{
|
||||
Constant: &commonv1pb.JobFailurePolicyConstant{
|
||||
MaxRetries: &maxRetries,
|
||||
Interval: &durationpb.Duration{Seconds: 10},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -16,7 +15,7 @@ const (
|
|||
)
|
||||
|
||||
func TestGetConfigurationItem(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
t.Run("get configuration item", func(t *testing.T) {
|
||||
resp, err := testClient.GetConfigurationItem(ctx, "example-config", "mykey")
|
||||
|
|
@ -31,7 +30,7 @@ func TestGetConfigurationItem(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetConfigurationItems(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
keys := []string{"mykey1", "mykey2", "mykey3"}
|
||||
t.Run("Test get configuration items", func(t *testing.T) {
|
||||
|
|
@ -44,7 +43,7 @@ func TestGetConfigurationItems(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSubscribeConfigurationItems(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
var counter, totalCounter uint32
|
||||
counter = 0
|
||||
|
|
@ -67,7 +66,7 @@ func TestSubscribeConfigurationItems(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUnSubscribeConfigurationItems(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
var counter, totalCounter uint32
|
||||
t.Run("Test unsubscribe configuration items", func(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -101,8 +101,10 @@ func WithTemperature(temp float64) conversationRequestOption {
|
|||
|
||||
// ConverseAlpha1 can invoke an LLM given a request created by the NewConversationRequest function.
|
||||
func (c *GRPCClient) ConverseAlpha1(ctx context.Context, req conversationRequest, options ...conversationRequestOption) (*ConversationResponse, error) {
|
||||
//nolint:staticcheck
|
||||
cinputs := make([]*runtimev1pb.ConversationInput, len(req.inputs))
|
||||
for i, in := range req.inputs {
|
||||
//nolint:staticcheck
|
||||
cinputs[i] = &runtimev1pb.ConversationInput{
|
||||
Content: in.Content,
|
||||
Role: in.Role,
|
||||
|
|
@ -115,7 +117,7 @@ func (c *GRPCClient) ConverseAlpha1(ctx context.Context, req conversationRequest
|
|||
opt(&req)
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
request := runtimev1pb.ConversationRequest{
|
||||
Name: req.name,
|
||||
ContextID: req.ContextID,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import (
|
|||
)
|
||||
|
||||
func TestEncrypt(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
t.Run("missing ComponentName", func(t *testing.T) {
|
||||
out, err := testClient.Encrypt(ctx,
|
||||
|
|
@ -138,7 +138,7 @@ func TestEncrypt(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDecrypt(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
t.Run("missing ComponentName", func(t *testing.T) {
|
||||
out, err := testClient.Decrypt(ctx,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ limitations under the License.
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -39,7 +38,7 @@ type _testStructwithSlices struct {
|
|||
}
|
||||
|
||||
func TestInvokeMethodWithContent(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
data := "ping"
|
||||
|
||||
t.Run("with content", func(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
Copyright 2021 The Dapr Authors
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
commonpb "github.com/dapr/dapr/pkg/proto/common/v1"
|
||||
runtimepb "github.com/dapr/dapr/pkg/proto/runtime/v1"
|
||||
"github.com/dapr/kit/ptr"
|
||||
)
|
||||
|
||||
type FailurePolicy interface {
|
||||
GetPBFailurePolicy() *commonpb.JobFailurePolicy
|
||||
}
|
||||
|
||||
type JobFailurePolicyConstant struct {
|
||||
MaxRetries *uint32
|
||||
Interval *time.Duration
|
||||
}
|
||||
|
||||
func (f *JobFailurePolicyConstant) GetPBFailurePolicy() *commonpb.JobFailurePolicy {
|
||||
constantfp := &commonpb.JobFailurePolicyConstant{}
|
||||
if f.MaxRetries != nil {
|
||||
constantfp.MaxRetries = f.MaxRetries
|
||||
}
|
||||
if f.Interval != nil {
|
||||
constantfp.Interval = durationpb.New(*f.Interval)
|
||||
}
|
||||
return &commonpb.JobFailurePolicy{
|
||||
Policy: &commonpb.JobFailurePolicy_Constant{
|
||||
Constant: constantfp,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type JobFailurePolicyDrop struct{}
|
||||
|
||||
func (f *JobFailurePolicyDrop) GetPBFailurePolicy() *commonpb.JobFailurePolicy {
|
||||
return &commonpb.JobFailurePolicy{
|
||||
Policy: &commonpb.JobFailurePolicy_Drop{
|
||||
Drop: &commonpb.JobFailurePolicyDrop{},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type Job struct {
|
||||
Name string
|
||||
Schedule *string
|
||||
Repeats *uint32
|
||||
DueTime *string
|
||||
TTL *string
|
||||
Data *anypb.Any
|
||||
FailurePolicy FailurePolicy
|
||||
Overwrite bool
|
||||
}
|
||||
|
||||
type JobOption func(*Job)
|
||||
|
||||
func NewJob(name string, opts ...JobOption) *Job {
|
||||
job := &Job{
|
||||
Name: name,
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(job)
|
||||
}
|
||||
return job
|
||||
}
|
||||
|
||||
func WithJobSchedule(schedule string) JobOption {
|
||||
return func(job *Job) {
|
||||
job.Schedule = &schedule
|
||||
}
|
||||
}
|
||||
|
||||
func WithJobRepeats(repeats uint32) JobOption {
|
||||
return func(job *Job) {
|
||||
job.Repeats = &repeats
|
||||
}
|
||||
}
|
||||
|
||||
func WithJobDueTime(dueTime string) JobOption {
|
||||
return func(job *Job) {
|
||||
job.DueTime = &dueTime
|
||||
}
|
||||
}
|
||||
|
||||
func WithJobTTL(ttl string) JobOption {
|
||||
return func(job *Job) {
|
||||
job.TTL = &ttl
|
||||
}
|
||||
}
|
||||
|
||||
func WithJobData(data *anypb.Any) JobOption {
|
||||
return func(job *Job) {
|
||||
job.Data = data
|
||||
}
|
||||
}
|
||||
|
||||
func WithJobConstantFailurePolicy() JobOption {
|
||||
return func(job *Job) {
|
||||
job.FailurePolicy = &JobFailurePolicyConstant{}
|
||||
}
|
||||
}
|
||||
|
||||
func WithJobConstantFailurePolicyMaxRetries(maxRetries uint32) JobOption {
|
||||
return func(job *Job) {
|
||||
if job.FailurePolicy == nil {
|
||||
job.FailurePolicy = &JobFailurePolicyConstant{}
|
||||
}
|
||||
if constantPolicy, ok := job.FailurePolicy.(*JobFailurePolicyConstant); ok {
|
||||
constantPolicy.MaxRetries = &maxRetries
|
||||
} else {
|
||||
job.FailurePolicy = &JobFailurePolicyConstant{
|
||||
MaxRetries: &maxRetries,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func WithJobConstantFailurePolicyInterval(interval time.Duration) JobOption {
|
||||
return func(job *Job) {
|
||||
if job.FailurePolicy == nil {
|
||||
job.FailurePolicy = &JobFailurePolicyConstant{}
|
||||
}
|
||||
if constantPolicy, ok := job.FailurePolicy.(*JobFailurePolicyConstant); ok {
|
||||
constantPolicy.Interval = &interval
|
||||
} else {
|
||||
job.FailurePolicy = &JobFailurePolicyConstant{
|
||||
Interval: &interval,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func WithJobDropFailurePolicy() JobOption {
|
||||
return func(job *Job) {
|
||||
job.FailurePolicy = &JobFailurePolicyDrop{}
|
||||
}
|
||||
}
|
||||
|
||||
// ScheduleJobAlpha1 raises and schedules a job.
|
||||
func (c *GRPCClient) ScheduleJobAlpha1(ctx context.Context, job *Job) error {
|
||||
if job.Name == "" {
|
||||
return errors.New("job name is required")
|
||||
}
|
||||
if job.Data == nil {
|
||||
return errors.New("job data is required")
|
||||
}
|
||||
|
||||
jobRequest := &runtimepb.Job{
|
||||
Name: job.Name,
|
||||
Data: job.Data,
|
||||
Schedule: job.Schedule,
|
||||
Repeats: job.Repeats,
|
||||
DueTime: job.DueTime,
|
||||
Ttl: job.TTL,
|
||||
}
|
||||
|
||||
if job.FailurePolicy != nil {
|
||||
jobRequest.FailurePolicy = job.FailurePolicy.GetPBFailurePolicy()
|
||||
}
|
||||
_, err := c.protoClient.ScheduleJobAlpha1(ctx, &runtimepb.ScheduleJobRequest{
|
||||
Job: jobRequest,
|
||||
Overwrite: job.Overwrite,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// GetJobAlpha1 retrieves a scheduled job.
|
||||
func (c *GRPCClient) GetJobAlpha1(ctx context.Context, name string) (*Job, error) {
|
||||
if name == "" {
|
||||
return nil, errors.New("job name is required")
|
||||
}
|
||||
|
||||
resp, err := c.protoClient.GetJobAlpha1(ctx, &runtimepb.GetJobRequest{
|
||||
Name: name,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var failurePolicy FailurePolicy
|
||||
switch policy := resp.GetJob().GetFailurePolicy().GetPolicy().(type) {
|
||||
case *commonpb.JobFailurePolicy_Constant:
|
||||
interval := time.Duration(policy.Constant.GetInterval().GetSeconds()) * time.Second
|
||||
failurePolicy = &JobFailurePolicyConstant{
|
||||
MaxRetries: ptr.Of(policy.Constant.GetMaxRetries()),
|
||||
Interval: &interval,
|
||||
}
|
||||
case *commonpb.JobFailurePolicy_Drop:
|
||||
failurePolicy = &JobFailurePolicyDrop{}
|
||||
}
|
||||
|
||||
return &Job{
|
||||
Name: resp.GetJob().GetName(),
|
||||
Schedule: ptr.Of(resp.GetJob().GetSchedule()),
|
||||
Repeats: ptr.Of(resp.GetJob().GetRepeats()),
|
||||
DueTime: ptr.Of(resp.GetJob().GetDueTime()),
|
||||
TTL: ptr.Of(resp.GetJob().GetTtl()),
|
||||
Data: resp.GetJob().GetData(),
|
||||
FailurePolicy: failurePolicy,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteJobAlpha1 deletes a scheduled job.
|
||||
func (c *GRPCClient) DeleteJobAlpha1(ctx context.Context, name string) error {
|
||||
if name == "" {
|
||||
return errors.New("job name is required")
|
||||
}
|
||||
|
||||
_, err := c.protoClient.DeleteJobAlpha1(ctx, &runtimepb.DeleteJobRequest{
|
||||
Name: name,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
Copyright 2021 The Dapr Authors
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
)
|
||||
|
||||
func TestSchedulingAlpha1(t *testing.T) {
|
||||
ctx := t.Context()
|
||||
|
||||
t.Run("schedule job - valid", func(t *testing.T) {
|
||||
job := NewJob("test",
|
||||
WithJobSchedule("test"),
|
||||
WithJobData(&anypb.Any{}),
|
||||
WithJobConstantFailurePolicy(),
|
||||
)
|
||||
|
||||
err := testClient.ScheduleJobAlpha1(ctx, job)
|
||||
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("get job - valid", func(t *testing.T) {
|
||||
expected := NewJob("name",
|
||||
WithJobSchedule("@every 10s"),
|
||||
WithJobRepeats(4),
|
||||
WithJobDueTime("10s"),
|
||||
WithJobTTL("10s"),
|
||||
WithJobConstantFailurePolicy(),
|
||||
WithJobConstantFailurePolicyMaxRetries(4),
|
||||
WithJobConstantFailurePolicyInterval(time.Second*10),
|
||||
)
|
||||
|
||||
resp, err := testClient.GetJobAlpha1(ctx, "name")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expected, resp)
|
||||
})
|
||||
|
||||
t.Run("delete job - valid", func(t *testing.T) {
|
||||
err := testClient.DeleteJobAlpha1(ctx, "name")
|
||||
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestJobBuilder(t *testing.T) {
|
||||
t.Run("basic job creation", func(t *testing.T) {
|
||||
job := NewJob("test-job")
|
||||
|
||||
assert.Equal(t, "test-job", job.Name)
|
||||
assert.Nil(t, job.Schedule)
|
||||
assert.Nil(t, job.Repeats)
|
||||
assert.Nil(t, job.DueTime)
|
||||
assert.Nil(t, job.TTL)
|
||||
assert.Nil(t, job.Data)
|
||||
assert.Nil(t, job.FailurePolicy)
|
||||
})
|
||||
|
||||
t.Run("job with all options and constant failure policy", func(t *testing.T) {
|
||||
job := NewJob("full-job",
|
||||
WithJobSchedule("@every 10m"),
|
||||
WithJobRepeats(5),
|
||||
WithJobDueTime("2024-12-31T23:59:59Z"),
|
||||
WithJobTTL("2h"),
|
||||
WithJobData(&anypb.Any{TypeUrl: "test", Value: []byte("test-data")}),
|
||||
WithJobConstantFailurePolicy(),
|
||||
WithJobConstantFailurePolicyMaxRetries(3),
|
||||
WithJobConstantFailurePolicyInterval(time.Minute*2),
|
||||
)
|
||||
|
||||
assert.Equal(t, "full-job", job.Name)
|
||||
assert.Equal(t, "@every 10m", *job.Schedule)
|
||||
assert.Equal(t, uint32(5), *job.Repeats)
|
||||
assert.Equal(t, "2024-12-31T23:59:59Z", *job.DueTime)
|
||||
assert.Equal(t, "2h", *job.TTL)
|
||||
assert.Equal(t, &anypb.Any{TypeUrl: "test", Value: []byte("test-data")}, job.Data)
|
||||
constantPolicy, ok := job.FailurePolicy.(*JobFailurePolicyConstant)
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, uint32(3), *constantPolicy.MaxRetries)
|
||||
assert.Equal(t, time.Minute*2, *constantPolicy.Interval)
|
||||
})
|
||||
|
||||
t.Run("job with all options and drop failure policy", func(t *testing.T) {
|
||||
job := NewJob("full-job",
|
||||
WithJobSchedule("@every 10m"),
|
||||
WithJobRepeats(5),
|
||||
WithJobDueTime("2024-12-31T23:59:59Z"),
|
||||
WithJobTTL("2h"),
|
||||
WithJobData(&anypb.Any{TypeUrl: "test", Value: []byte("test-data")}),
|
||||
WithJobDropFailurePolicy(),
|
||||
)
|
||||
|
||||
assert.Equal(t, "full-job", job.Name)
|
||||
assert.Equal(t, "@every 10m", *job.Schedule)
|
||||
assert.Equal(t, uint32(5), *job.Repeats)
|
||||
assert.Equal(t, "2024-12-31T23:59:59Z", *job.DueTime)
|
||||
assert.Equal(t, "2h", *job.TTL)
|
||||
assert.Equal(t, &anypb.Any{TypeUrl: "test", Value: []byte("test-data")}, job.Data)
|
||||
_, ok := job.FailurePolicy.(*JobFailurePolicyDrop)
|
||||
require.True(t, ok)
|
||||
})
|
||||
}
|
||||
|
|
@ -14,7 +14,6 @@ limitations under the License.
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -29,7 +28,7 @@ const (
|
|||
)
|
||||
|
||||
func TestLock(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
t.Run("try lock invalid store name", func(t *testing.T) {
|
||||
r, err := testClient.TryLockAlpha1(ctx, "", &LockRequest{})
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -11,7 +10,7 @@ import (
|
|||
|
||||
// Test GetMetadata returns
|
||||
func TestGetMetadata(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
t.Run("get meta", func(t *testing.T) {
|
||||
metadata, err := testClient.GetMetadata(ctx)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -20,7 +19,7 @@ func TestGetMetadata(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSetMetadata(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
t.Run("set meta", func(t *testing.T) {
|
||||
err := testClient.SetMetadata(ctx, "test_key", "test_value")
|
||||
require.NoError(t, err)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ limitations under the License.
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -39,7 +38,7 @@ type _testCustomContentwithSlices struct {
|
|||
|
||||
// go test -timeout 30s ./client -count 1 -run ^TestPublishEvent$
|
||||
func TestPublishEvent(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
t.Run("with data", func(t *testing.T) {
|
||||
err := testClient.PublishEvent(ctx, "messages", "test", []byte("ping"))
|
||||
|
|
@ -96,7 +95,7 @@ func TestPublishEvent(t *testing.T) {
|
|||
|
||||
// go test -timeout 30s ./client -count 1 -run ^TestPublishEvents$
|
||||
func TestPublishEvents(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
t.Run("without pubsub name", func(t *testing.T) {
|
||||
res := testClient.PublishEvents(ctx, "", "test", []interface{}{"ping", "pong"})
|
||||
|
|
|
|||
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
Copyright 2021 The Dapr Authors
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
|
||||
pb "github.com/dapr/dapr/pkg/proto/runtime/v1"
|
||||
)
|
||||
|
||||
type Job struct {
|
||||
Name string
|
||||
Schedule string // Optional
|
||||
Repeats uint32 // Optional
|
||||
DueTime string // Optional
|
||||
TTL string // Optional
|
||||
Data *anypb.Any
|
||||
}
|
||||
|
||||
// ScheduleJobAlpha1 raises and schedules a job.
|
||||
func (c *GRPCClient) ScheduleJobAlpha1(ctx context.Context, job *Job) error {
|
||||
// TODO: Assert job fields are defined: Name, Data
|
||||
jobRequest := &pb.Job{
|
||||
Name: job.Name,
|
||||
Data: job.Data,
|
||||
}
|
||||
|
||||
if job.Schedule != "" {
|
||||
jobRequest.Schedule = &job.Schedule
|
||||
}
|
||||
|
||||
if job.Repeats != 0 {
|
||||
jobRequest.Repeats = &job.Repeats
|
||||
}
|
||||
|
||||
if job.DueTime != "" {
|
||||
jobRequest.DueTime = &job.DueTime
|
||||
}
|
||||
|
||||
if job.TTL != "" {
|
||||
jobRequest.Ttl = &job.TTL
|
||||
}
|
||||
_, err := c.protoClient.ScheduleJobAlpha1(ctx, &pb.ScheduleJobRequest{
|
||||
Job: jobRequest,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// GetJobAlpha1 retrieves a scheduled job.
|
||||
func (c *GRPCClient) GetJobAlpha1(ctx context.Context, name string) (*Job, error) {
|
||||
// TODO: Name validation
|
||||
resp, err := c.protoClient.GetJobAlpha1(ctx, &pb.GetJobRequest{
|
||||
Name: name,
|
||||
})
|
||||
log.Println(resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Job{
|
||||
Name: resp.GetJob().GetName(),
|
||||
Schedule: resp.GetJob().GetSchedule(),
|
||||
Repeats: resp.GetJob().GetRepeats(),
|
||||
DueTime: resp.GetJob().GetDueTime(),
|
||||
TTL: resp.GetJob().GetTtl(),
|
||||
Data: resp.GetJob().GetData(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteJobAlpha1 deletes a scheduled job.
|
||||
func (c *GRPCClient) DeleteJobAlpha1(ctx context.Context, name string) error {
|
||||
// TODO: Name validation
|
||||
_, err := c.protoClient.DeleteJobAlpha1(ctx, &pb.DeleteJobRequest{
|
||||
Name: name,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
Copyright 2021 The Dapr Authors
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
)
|
||||
|
||||
func TestSchedulingAlpha1(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("schedule job - valid", func(t *testing.T) {
|
||||
err := testClient.ScheduleJobAlpha1(ctx, &Job{
|
||||
Name: "test",
|
||||
Schedule: "test",
|
||||
Data: &anypb.Any{},
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("get job - valid", func(t *testing.T) {
|
||||
expected := &Job{
|
||||
Name: "name",
|
||||
Schedule: "@every 10s",
|
||||
Repeats: 4,
|
||||
DueTime: "10s",
|
||||
TTL: "10s",
|
||||
Data: nil,
|
||||
}
|
||||
|
||||
resp, err := testClient.GetJobAlpha1(ctx, "name")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expected, resp)
|
||||
})
|
||||
|
||||
t.Run("delete job - valid", func(t *testing.T) {
|
||||
err := testClient.DeleteJobAlpha1(ctx, "name")
|
||||
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
|
@ -14,7 +14,6 @@ limitations under the License.
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -24,7 +23,7 @@ import (
|
|||
|
||||
// go test -timeout 30s ./client -count 1 -run ^TestGetSecret$
|
||||
func TestGetSecret(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
t.Run("without store", func(t *testing.T) {
|
||||
out, err := testClient.GetSecret(ctx, "", "key1", nil)
|
||||
|
|
@ -53,7 +52,7 @@ func TestGetSecret(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetBulkSecret(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
t.Run("without store", func(t *testing.T) {
|
||||
out, err := testClient.GetBulkSecret(ctx, "", nil)
|
||||
|
|
|
|||
|
|
@ -17,10 +17,6 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
v1 "github.com/dapr/dapr/pkg/proto/common/v1"
|
||||
pb "github.com/dapr/dapr/pkg/proto/runtime/v1"
|
||||
|
|
@ -249,22 +245,6 @@ func copyStateOptionDefault() *StateOptions {
|
|||
}
|
||||
}
|
||||
|
||||
func toProtoDuration(d time.Duration) *durationpb.Duration {
|
||||
nanos := d.Nanoseconds()
|
||||
secs := nanos / 1e9
|
||||
nanos -= secs * 1e9
|
||||
|
||||
// conversion check - gosec ignored below for conversion
|
||||
if nanos <= int64(math.MinInt32) && nanos >= int64(math.MaxInt32) {
|
||||
panic("integer overflow converting duration to proto")
|
||||
}
|
||||
|
||||
return &durationpb.Duration{
|
||||
Seconds: secs,
|
||||
Nanos: int32(nanos), //nolint:gosec
|
||||
}
|
||||
}
|
||||
|
||||
// ExecuteStateTransaction provides way to execute multiple operations on a specified store.
|
||||
func (c *GRPCClient) ExecuteStateTransaction(ctx context.Context, storeName string, meta map[string]string, ops []*StateOperation) error {
|
||||
if storeName == "" {
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ limitations under the License.
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ func TestTypes(t *testing.T) {
|
|||
|
||||
func TestDurationConverter(t *testing.T) {
|
||||
d := 10 * time.Second
|
||||
pd := toProtoDuration(d)
|
||||
pd := durationpb.New(d)
|
||||
assert.NotNil(t, pd)
|
||||
assert.Equal(t, int64(10), pd.GetSeconds())
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ func TestStateOptionsConverter(t *testing.T) {
|
|||
|
||||
// go test -timeout 30s ./client -count 1 -run ^TestSaveState$
|
||||
func TestSaveState(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
data := testData
|
||||
store := testStore
|
||||
key := "key1"
|
||||
|
|
@ -118,7 +118,7 @@ func TestSaveState(t *testing.T) {
|
|||
|
||||
// go test -timeout 30s ./client -count 1 -run ^TestDeleteState$
|
||||
func TestDeleteState(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
data := testData
|
||||
store := testStore
|
||||
key := "key1"
|
||||
|
|
@ -189,7 +189,7 @@ func TestDeleteState(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDeleteBulkState(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
data := testData
|
||||
store := testStore
|
||||
keys := []string{"key1", "key2", "key3"}
|
||||
|
|
@ -337,7 +337,7 @@ func TestDeleteBulkState(t *testing.T) {
|
|||
|
||||
// go test -timeout 30s ./client -count 1 -run ^TestStateTransactions$
|
||||
func TestStateTransactions(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
data := `{ "message": "test" }`
|
||||
store := testStore
|
||||
meta := map[string]string{}
|
||||
|
|
@ -410,7 +410,7 @@ func TestStateTransactions(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestQueryState(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
data := testData
|
||||
store := testStore
|
||||
key1 := "key1"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ limitations under the License.
|
|||
|
||||
package client
|
||||
|
||||
import "encoding/json"
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// isCloudEvent returns true if the event is a CloudEvent.
|
||||
// An event is a CloudEvent if it `id`, `source`, `specversion` and `type` fields.
|
||||
|
|
|
|||
|
|
@ -116,14 +116,14 @@ func createNonBlockingClient(ctx context.Context, serverAddr string) (client Cli
|
|||
}
|
||||
|
||||
func TestGrpcWaitHappyCase(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
err := testClient.Wait(ctx, waitTimeout)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestGrpcWaitUnresponsiveTcpServer(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
server, err := createUnresponsiveTCPServer()
|
||||
require.NoError(t, err)
|
||||
|
|
@ -141,7 +141,7 @@ func TestGrpcWaitUnresponsiveTcpServer(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGrpcWaitUnresponsiveUnixServer(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
server, err := createUnresponsiveUnixServer()
|
||||
require.NoError(t, err)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ limitations under the License.
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
|
|
@ -35,7 +34,7 @@ func TestMarshalInput(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestWorkflowBeta1(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
// 1: StartWorkflow
|
||||
t.Run("start workflow - valid (without id)", func(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ When contributing to the [Go SDK](https://github.com/dapr/go-sdk) the following
|
|||
|
||||
The `examples` directory contains code samples for users to run to try out specific functionality of the various Go SDK packages and extensions. When writing new and updated samples keep in mind:
|
||||
|
||||
- All examples should be runnable on Windows, Linux, and MacOS. While Go code is consistent among operating systems, any pre/post example commands should provide options through [codetabs]({{< ref "contributing-docs.md#tabbed-content" >}})
|
||||
- All examples should be runnable on Windows, Linux, and MacOS. While Go code is consistent among operating systems, any pre/post example commands should provide options through [tabpane]({{% ref "contributing-docs.md#tabbed-content" %}})
|
||||
- Contain steps to download/install any required pre-requisites. Someone coming in with a fresh OS install should be able to start on the example and complete it without an error. Links to external download pages are fine.
|
||||
|
||||
## Docs
|
||||
|
||||
The `daprdocs` directory contains the markdown files that are rendered into the [Dapr Docs](https://docs.dapr.io) website. When the documentation website is built this repo is cloned and configured so that its contents are rendered with the docs content. When writing docs keep in mind:
|
||||
|
||||
- All rules in the [docs guide]({{< ref contributing-docs.md >}}) should be followed in addition to these.
|
||||
- All rules in the [docs guide]({{% ref contributing-docs.md %}}) should be followed in addition to these.
|
||||
- All files and directories should be prefixed with `go-` to ensure all file/directory names are globally unique across all Dapr documentation.
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ A client library to help build Dapr applications in Go. This client supports all
|
|||
{{< card title="**Client**">}}
|
||||
Use the Go Client SDK for invoking public Dapr APIs
|
||||
|
||||
[**Learn more about the Go Client SDK**]({{< ref go-client >}})
|
||||
[**Learn more about the Go Client SDK**]({{% ref go-client %}})
|
||||
{{< /card >}}
|
||||
{{< card title="**Service**">}}
|
||||
Use the Dapr Service (Callback) SDK for Go to create services that will be invoked by Dapr.
|
||||
|
||||
[**Learn more about the Go Service (Callback) SDK**]({{< ref go-service >}})
|
||||
[**Learn more about the Go Service (Callback) SDK**]({{% ref go-service %}})
|
||||
{{< /card >}}
|
||||
{{< /cardpane >}}
|
||||
|
|
@ -11,17 +11,17 @@ The Dapr client package allows you to interact with other Dapr applications from
|
|||
|
||||
## Prerequisites
|
||||
|
||||
- [Dapr CLI]({{< ref install-dapr-cli.md >}}) installed
|
||||
- Initialized [Dapr environment]({{< ref install-dapr-selfhost.md >}})
|
||||
- [Dapr CLI]({{% ref install-dapr-cli.md %}}) installed
|
||||
- Initialized [Dapr environment]({{% ref install-dapr-selfhost.md %}})
|
||||
- [Go installed](https://golang.org/doc/install)
|
||||
|
||||
|
||||
## Import the client package
|
||||
## Import the client package
|
||||
```go
|
||||
import "github.com/dapr/go-sdk/client"
|
||||
```
|
||||
## Error handling
|
||||
Dapr errors are based on [gRPC's richer error model](https://cloud.google.com/apis/design/errors#error_model).
|
||||
Dapr errors are based on [gRPC's richer error model](https://cloud.google.com/apis/design/errors#error_model).
|
||||
The following code shows an example of how you can parse and handle the error details:
|
||||
|
||||
```go
|
||||
|
|
@ -54,7 +54,7 @@ if err != nil {
|
|||
fmt.Printf("- Url: %s\n", link.Url)
|
||||
fmt.Printf("- Description: %s\n", link.Description)
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
// Add cases for other types of details you expect
|
||||
fmt.Printf("Unhandled error detail type: %v\n", t)
|
||||
|
|
@ -65,7 +65,7 @@ if err != nil {
|
|||
|
||||
## Building blocks
|
||||
|
||||
The Go SDK allows you to interface with all of the [Dapr building blocks]({{< ref building-blocks >}}).
|
||||
The Go SDK allows you to interface with all of the [Dapr building blocks]({{% ref building-blocks %}}).
|
||||
|
||||
### Service Invocation
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ content := &dapr.DataContent{
|
|||
resp, err = client.InvokeMethodWithContent(ctx, "app-id", "method-name", "post", content)
|
||||
```
|
||||
|
||||
For a full guide on service invocation, visit [How-To: Invoke a service]({{< ref howto-invoke-discover-services.md >}}).
|
||||
For a full guide on service invocation, visit [How-To: Invoke a service]({{% ref howto-invoke-discover-services.md %}}).
|
||||
|
||||
### Workflows
|
||||
|
||||
|
|
@ -102,14 +102,14 @@ import (
|
|||
func ExampleWorkflow(ctx *workflow.WorkflowContext) (any, error) {
|
||||
var output string
|
||||
input := "world"
|
||||
|
||||
|
||||
if err := ctx.CallActivity(ExampleActivity, workflow.ActivityInput(input)).Await(&output); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
// Print output - "hello world"
|
||||
fmt.Println(output)
|
||||
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ func ExampleActivity(ctx workflow.ActivityContext) (any, error) {
|
|||
if err := ctx.GetInput(&input); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
|
||||
return fmt.Sprintf("hello %s", input), nil
|
||||
}
|
||||
|
||||
|
|
@ -128,47 +128,47 @@ func main() {
|
|||
if err != nil {
|
||||
log.Fatalf("error creating worker: %v", err)
|
||||
}
|
||||
|
||||
|
||||
// Register the workflow
|
||||
w.RegisterWorkflow(ExampleWorkflow)
|
||||
|
||||
|
||||
// Register the activity
|
||||
w.RegisterActivity(ExampleActivity)
|
||||
|
||||
|
||||
// Start workflow runner
|
||||
if err := w.Start(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
||||
// Create a workflow client
|
||||
wfClient, err := workflow.NewClient()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
||||
// Start a new workflow
|
||||
id, err := wfClient.ScheduleNewWorkflow(context.Background(), "ExampleWorkflow")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
||||
// Wait for the workflow to complete
|
||||
metadata, err := wfClient.WaitForWorkflowCompletion(ctx, id)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
||||
// Print workflow status post-completion
|
||||
fmt.Println(metadata.RuntimeStatus)
|
||||
|
||||
|
||||
// Shutdown Worker
|
||||
w.Shutdown()
|
||||
}
|
||||
```
|
||||
|
||||
- For a more comprehensive guide on workflows visit these How-To guides:
|
||||
- [How-To: Author a workflow]({{< ref howto-author-workflow.md >}}).
|
||||
- [How-To: Manage a workflow]({{< ref howto-manage-workflow.md >}}).
|
||||
- [How-To: Author a workflow]({{% ref howto-author-workflow.md %}}).
|
||||
- [How-To: Manage a workflow]({{% ref howto-manage-workflow.md %}}).
|
||||
- Visit the Go SDK Examples to jump into complete examples:
|
||||
- [Workflow Example](https://github.com/dapr/go-sdk/tree/main/examples/workflow)
|
||||
- [Workflow - Parallelised](https://github.com/dapr/go-sdk/tree/main/examples/workflow-parallel)
|
||||
|
|
@ -180,7 +180,7 @@ For simple use-cases, Dapr client provides easy to use `Save`, `Get`, `Delete` m
|
|||
```go
|
||||
ctx := context.Background()
|
||||
data := []byte("hello")
|
||||
store := "my-store" // defined in the component YAML
|
||||
store := "my-store" // defined in the component YAML
|
||||
|
||||
// save state with the key key1, default options: strong, last-write
|
||||
if err := client.SaveState(ctx, store, "key1", data, nil); err != nil {
|
||||
|
|
@ -269,7 +269,7 @@ meta := map[string]string{}
|
|||
err := testClient.ExecuteStateTransaction(ctx, store, meta, ops)
|
||||
```
|
||||
|
||||
Retrieve, filter, and sort key/value data stored in your statestore using `QueryState`.
|
||||
Retrieve, filter, and sort key/value data stored in your statestore using `QueryState`.
|
||||
|
||||
```go
|
||||
// Define the query string
|
||||
|
|
@ -306,7 +306,7 @@ for _, account := range queryResponse {
|
|||
|
||||
> **Note:** Query state API is currently in alpha
|
||||
|
||||
For a full guide on state management, visit [How-To: Save & get state]({{< ref howto-get-save-state.md >}}).
|
||||
For a full guide on state management, visit [How-To: Save & get state]({{% ref howto-get-save-state.md %}}).
|
||||
|
||||
### Publish Messages
|
||||
To publish data onto a topic, the Dapr Go client provides a simple method:
|
||||
|
|
@ -328,11 +328,11 @@ if res.Error != nil {
|
|||
}
|
||||
```
|
||||
|
||||
For a full guide on pub/sub, visit [How-To: Publish & subscribe]({{< ref howto-publish-subscribe.md >}}).
|
||||
For a full guide on pub/sub, visit [How-To: Publish & subscribe]({{% ref howto-publish-subscribe.md %}}).
|
||||
|
||||
### Workflow
|
||||
|
||||
You can create [workflows]({{< ref workflow-overview.md >}}) using the Go SDK. For example, start with a simple workflow activity:
|
||||
You can create [workflows]({{% ref workflow-overview.md %}}) using the Go SDK. For example, start with a simple workflow activity:
|
||||
|
||||
```go
|
||||
func TestActivity(ctx workflow.ActivityContext) (any, error) {
|
||||
|
|
@ -340,7 +340,7 @@ func TestActivity(ctx workflow.ActivityContext) (any, error) {
|
|||
if err := ctx.GetInput(&input); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
|
||||
// Do something here
|
||||
return "result", nil
|
||||
}
|
||||
|
|
@ -361,7 +361,7 @@ func TestWorkflow(ctx *workflow.WorkflowContext) (any, error) {
|
|||
if err := ctx.WaitForExternalEvent("testEvent", time.Second*60).Await(&output); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
if err := ctx.CreateTimer(time.Second).Await(nil); err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -369,10 +369,113 @@ func TestWorkflow(ctx *workflow.WorkflowContext) (any, error) {
|
|||
}
|
||||
```
|
||||
|
||||
Then compose your application that will use the workflow you've created. [Refer to the How-To: Author workflows guide]({{< ref howto-author-workflow.md >}}) for a full walk-through.
|
||||
Then compose your application that will use the workflow you've created. [Refer to the How-To: Author workflows guide]({{% ref howto-author-workflow.md %}}) for a full walk-through.
|
||||
|
||||
Try out the [Go SDK workflow example.](https://github.com/dapr/go-sdk/blob/main/examples/workflow)
|
||||
|
||||
### Jobs
|
||||
|
||||
The Dapr client Go SDK allows you to schedule, get, and delete jobs. Jobs enable you to schedule work to be executed at specific times or intervals.
|
||||
|
||||
#### Scheduling a Job
|
||||
|
||||
To schedule a new job, use the `ScheduleJobAlpha1` method:
|
||||
|
||||
```go
|
||||
import (
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
)
|
||||
|
||||
// Create job data
|
||||
data, err := anypb.New(&YourDataStruct{Message: "Hello, Job!"})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Create a simple job using the builder pattern
|
||||
job := client.NewJob("my-scheduled-job",
|
||||
client.WithJobData(data),
|
||||
client.WithJobDueTime("10s"), // Execute in 10 seconds
|
||||
)
|
||||
|
||||
// Schedule the job
|
||||
err = client.ScheduleJobAlpha1(ctx, job)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
```
|
||||
|
||||
#### Job with Schedule and Repeats
|
||||
|
||||
You can create recurring jobs using the `Schedule` field with cron expressions:
|
||||
|
||||
```go
|
||||
job := client.NewJob("recurring-job",
|
||||
client.WithJobData(data),
|
||||
client.WithJobSchedule("0 9 * * *"), // Run at 9 AM every day
|
||||
client.WithJobRepeats(10), // Repeat 10 times
|
||||
client.WithJobTTL("1h"), // Job expires after 1 hour
|
||||
)
|
||||
|
||||
err = client.ScheduleJobAlpha1(ctx, job)
|
||||
```
|
||||
|
||||
#### Job with Failure Policy
|
||||
|
||||
Configure how jobs should handle failures using failure policies:
|
||||
|
||||
```go
|
||||
// Constant retry policy with max retries and interval
|
||||
job := client.NewJob("resilient-job",
|
||||
client.WithJobData(data),
|
||||
client.WithJobDueTime("2024-01-01T10:00:00Z"),
|
||||
client.WithJobConstantFailurePolicy(),
|
||||
client.WithJobConstantFailurePolicyMaxRetries(3),
|
||||
client.WithJobConstantFailurePolicyInterval(30*time.Second),
|
||||
)
|
||||
|
||||
err = client.ScheduleJobAlpha1(ctx, job)
|
||||
```
|
||||
|
||||
For jobs that should not be retried on failure, use the drop policy:
|
||||
|
||||
```go
|
||||
job := client.NewJob("one-shot-job",
|
||||
client.WithJobData(data),
|
||||
client.WithJobDueTime("2024-01-01T10:00:00Z"),
|
||||
client.WithJobDropFailurePolicy(),
|
||||
)
|
||||
|
||||
err = client.ScheduleJobAlpha1(ctx, job)
|
||||
```
|
||||
|
||||
#### Getting a Job
|
||||
|
||||
To get information about a scheduled job:
|
||||
|
||||
```go
|
||||
job, err := client.GetJobAlpha1(ctx, "my-scheduled-job")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Job: %s, Schedule: %s, Repeats: %d\n",
|
||||
job.Name, job.Schedule, job.Repeats)
|
||||
```
|
||||
|
||||
#### Deleting a Job
|
||||
|
||||
To cancel a scheduled job:
|
||||
|
||||
```go
|
||||
err = client.DeleteJobAlpha1(ctx, "my-scheduled-job")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
```
|
||||
|
||||
For a full guide on jobs, visit [How-To: Schedule and manage jobs]({{< ref howto-schedule-and-handle-triggered-jobs.md >}}).
|
||||
|
||||
### Output Bindings
|
||||
|
||||
|
||||
|
|
@ -398,7 +501,7 @@ in := &dapr.InvokeBindingRequest{
|
|||
out, err := client.InvokeBinding(ctx, in)
|
||||
```
|
||||
|
||||
For a full guide on output bindings, visit [How-To: Use bindings]({{< ref howto-bindings.md >}}).
|
||||
For a full guide on output bindings, visit [How-To: Use bindings]({{% ref howto-bindings.md %}}).
|
||||
|
||||
### Actors
|
||||
|
||||
|
|
@ -460,7 +563,7 @@ func main() {
|
|||
}
|
||||
```
|
||||
|
||||
For a full guide on actors, visit [the Actors building block documentation]({{< ref actors >}}).
|
||||
For a full guide on actors, visit [the Actors building block documentation]({{% ref actors %}}).
|
||||
|
||||
### Secret Management
|
||||
|
||||
|
|
@ -498,7 +601,7 @@ func main() {
|
|||
```
|
||||
|
||||
|
||||
For a full guide on secrets, visit [How-To: Retrieve secrets]({{< ref howto-secrets.md >}}).
|
||||
For a full guide on secrets, visit [How-To: Retrieve secrets]({{% ref howto-secrets.md %}}).
|
||||
|
||||
### Distributed Lock
|
||||
|
||||
|
|
@ -522,7 +625,7 @@ func main() {
|
|||
panic(err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
|
||||
resp, err := client.TryLockAlpha1(ctx, "lockstore", &dapr.LockRequest{
|
||||
LockOwner: "random_id_abc123",
|
||||
ResourceID: "my_file_name",
|
||||
|
|
@ -533,7 +636,7 @@ func main() {
|
|||
}
|
||||
```
|
||||
|
||||
For a full guide on distributed lock, visit [How-To: Use a lock]({{< ref howto-use-distributed-lock.md >}}).
|
||||
For a full guide on distributed lock, visit [How-To: Use a lock]({{% ref howto-use-distributed-lock.md %}}).
|
||||
|
||||
### Configuration
|
||||
|
||||
|
|
@ -564,7 +667,7 @@ go func() {
|
|||
}()
|
||||
```
|
||||
|
||||
For a full guide on configuration, visit [How-To: Manage configuration from a store]({{< ref howto-manage-configuration.md >}}).
|
||||
For a full guide on configuration, visit [How-To: Manage configuration from a store]({{% ref howto-manage-configuration.md %}}).
|
||||
|
||||
### Cryptography
|
||||
|
||||
|
|
@ -595,7 +698,7 @@ out, err := client.Decrypt(context.Background(), rf, dapr.EncryptOptions{
|
|||
})
|
||||
```
|
||||
|
||||
For a full guide on cryptography, visit [How-To: Use the cryptography APIs]({{< ref howto-cryptography.md >}}).
|
||||
For a full guide on cryptography, visit [How-To: Use the cryptography APIs]({{% ref howto-cryptography.md %}}).
|
||||
|
||||
## Related links
|
||||
[Go SDK Examples](https://github.com/dapr/go-sdk/tree/main/examples)
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ description: How to get up and running with the Dapr Service (Callback) SDK for
|
|||
no_list: true
|
||||
---
|
||||
In addition to this Dapr API client, Dapr Go SDK also provides service package to bootstrap your Dapr callback services. These services can be developed in either gRPC or HTTP:
|
||||
- [HTTP Service]({{< ref http-service.md >}})
|
||||
- [gRPC Service]({{< ref grpc-service.md >}})
|
||||
- [HTTP Service]({{% ref http-service.md %}})
|
||||
- [gRPC Service]({{% ref grpc-service.md %}})
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
module github.com/dapr/go-sdk/examples
|
||||
|
||||
go 1.23.6
|
||||
go 1.24.4
|
||||
|
||||
replace github.com/dapr/go-sdk => ../
|
||||
|
||||
|
|
@ -9,32 +9,32 @@ require (
|
|||
github.com/dapr/go-sdk v0.0.0-00010101000000-000000000000
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/google/uuid v1.6.0
|
||||
google.golang.org/grpc v1.70.0
|
||||
google.golang.org/grpc v1.73.0
|
||||
google.golang.org/grpc/examples v0.0.0-20240516203910-e22436abb809
|
||||
google.golang.org/protobuf v1.36.4
|
||||
google.golang.org/protobuf v1.36.6
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/dapr/dapr v1.15.0-rc.17 // indirect
|
||||
github.com/dapr/durabletask-go v0.6.3 // indirect
|
||||
github.com/dapr/kit v0.15.0 // indirect
|
||||
github.com/dapr/dapr v1.16.0-rc.3 // indirect
|
||||
github.com/dapr/durabletask-go v0.7.3-0.20250711135247-7a35af6fe0e5 // indirect
|
||||
github.com/dapr/kit v0.15.4 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/go-chi/chi/v5 v5.1.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-chi/chi/v5 v5.2.2 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 // indirect
|
||||
go.opentelemetry.io/otel v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.37.0 // indirect
|
||||
golang.org/x/net v0.41.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/text v0.26.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect
|
||||
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 // indirect
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,25 +6,25 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3
|
|||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/dapr/dapr v1.15.0-rc.17 h1:bR0rd4FH81IteuOHTWVNyl58ZuQTDp3DYaTtXnpZ6JA=
|
||||
github.com/dapr/dapr v1.15.0-rc.17/go.mod h1:SD0AXom2XpX7pr8eYlbJ+gHfNREsflsrzCR19AZJ7/Q=
|
||||
github.com/dapr/durabletask-go v0.6.3 h1:WHhSAw1YL4xneK3Jo5nGfmMaJxfFodIIF5q1rpkDDfs=
|
||||
github.com/dapr/durabletask-go v0.6.3/go.mod h1:nTZ5fCbJLnZbVdi6Z2YxdDF1OgQZL3LroogGuetrwuA=
|
||||
github.com/dapr/kit v0.15.0 h1:446jrEOQV/0rt6FwmoKrifP3vav5+Uh/u38DqU8q+JM=
|
||||
github.com/dapr/kit v0.15.0/go.mod h1:HwFsBKEbcyLanWlDZE7u/jnaDCD/tU+n3pkFNUctQNw=
|
||||
github.com/dapr/dapr v1.16.0-rc.3 h1:D99V20GOhb+bZXH1PngME+wgzIZCcBFOvmaP7DOZxGo=
|
||||
github.com/dapr/dapr v1.16.0-rc.3/go.mod h1:uyKnxMohSg87LSFzZ/oyuiGSo0+qkzeR0eXncPyIV9c=
|
||||
github.com/dapr/durabletask-go v0.7.3-0.20250711135247-7a35af6fe0e5 h1:l8oBGwcfCwqvSYDZwla0A2fhENmXFc1Wk4lR0VEq+is=
|
||||
github.com/dapr/durabletask-go v0.7.3-0.20250711135247-7a35af6fe0e5/go.mod h1:0Ts4rXp74JyG19gDWPcwNo5V6NBZzhARzHF5XynmA7Q=
|
||||
github.com/dapr/kit v0.15.4 h1:29DezCR22OuZhXX4yPEc+lqcOf/PNaeAuIEx9nGv394=
|
||||
github.com/dapr/kit v0.15.4/go.mod h1:HwFsBKEbcyLanWlDZE7u/jnaDCD/tU+n3pkFNUctQNw=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
|
||||
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618=
|
||||
github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
|
|
@ -33,8 +33,8 @@ github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
|||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
|
|
@ -63,33 +63,33 @@ github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8
|
|||
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c h1:KL/ZBHXgKGVmuZBZ01Lt57yE5ws8ZPSkkihmEyq7FXc=
|
||||
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 h1:J1H9f+LEdWAfHcez/4cvaVBox7cOYT+IU6rgqj5x++8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
|
||||
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
|
||||
google.golang.org/grpc/examples v0.0.0-20240516203910-e22436abb809 h1:f96Rv5C5Y2CWlbKK6KhKDdyFgGOjPHPEMsdyaxE9k0c=
|
||||
google.golang.org/grpc/examples v0.0.0-20240516203910-e22436abb809/go.mod h1:uaPEAc5V00jjG3DPhGFLXGT290RUV3+aNQigs1W50/8=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
|
@ -101,5 +101,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
|
||||
k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 h1:jgJW5IePPXLGB8e/1wvd0Ich9QE97RvvF3a8J3fP/Lg=
|
||||
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Dapr Distributed Scheduler Example with go-sdk
|
||||
# Dapr Jobs Example with go-sdk
|
||||
|
||||
## Steps
|
||||
|
||||
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
- Dapr installed (v1.14 or higher)
|
||||
|
||||
### Run Distributed Scheduling Example
|
||||
### Run Jobs Example
|
||||
|
||||
<!-- STEP
|
||||
name: Run Distributed Scheduling Example
|
||||
name: Run Jobs Example
|
||||
output_match_mode: substring
|
||||
expected_stdout_lines:
|
||||
- 'Scheduler stream connected'
|
||||
|
|
@ -20,7 +20,7 @@ expected_stdout_lines:
|
|||
- 'payload: {db-backup {my-prod-db /backup-dir}}'
|
||||
- 'job 2 received'
|
||||
- 'payload: {db-backup {my-prod-db /backup-dir}}'
|
||||
- 'getjob - resp: &{prod-db-backup @every 1s 10 value:"{\"task\":\"db-backup\",\"metadata\":{\"db_name\":\"my-prod-db\",\"backup_location\":\"/backup-dir\"}}"}'
|
||||
- 'getjob - resp: Name: prod-db-backup, Schedule: @every 1s, Repeats: 10, DueTime: , TTL: , Data: value:"{\"task\":\"db-backup\",\"metadata\":{\"db_name\":\"my-prod-db\",\"backup_location\":\"/backup-dir\"}}"'
|
||||
- 'deletejob - success'
|
||||
|
||||
background: true
|
||||
|
|
@ -29,7 +29,7 @@ sleep: 30
|
|||
-->
|
||||
|
||||
```bash
|
||||
dapr run --app-id=distributed-scheduler \
|
||||
dapr run --app-id=jobs \
|
||||
--metrics-port=9091 \
|
||||
--scheduler-host-address=localhost:50006 \
|
||||
--dapr-grpc-port 50001 \
|
||||
|
|
@ -10,7 +10,7 @@ import (
|
|||
"google.golang.org/protobuf/types/known/anypb"
|
||||
|
||||
daprc "github.com/dapr/go-sdk/client"
|
||||
"github.com/dapr/go-sdk/examples/dist-scheduler/api"
|
||||
"github.com/dapr/go-sdk/examples/jobs/api"
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
daprs "github.com/dapr/go-sdk/service/grpc"
|
||||
)
|
||||
|
|
@ -49,14 +49,16 @@ func main() {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
job := daprc.Job{
|
||||
Name: "prod-db-backup",
|
||||
Schedule: "@every 1s",
|
||||
Repeats: 10,
|
||||
Data: &anypb.Any{
|
||||
job := daprc.NewJob("prod-db-backup",
|
||||
daprc.WithJobSchedule("@every 1s"),
|
||||
daprc.WithJobRepeats(10),
|
||||
daprc.WithJobData(&anypb.Any{
|
||||
Value: jobData,
|
||||
},
|
||||
}
|
||||
}),
|
||||
daprc.WithJobConstantFailurePolicy(),
|
||||
daprc.WithJobConstantFailurePolicyMaxRetries(4),
|
||||
daprc.WithJobConstantFailurePolicyInterval(time.Second*30),
|
||||
)
|
||||
|
||||
// create the client
|
||||
client, err := daprc.NewClient()
|
||||
|
|
@ -65,7 +67,7 @@ func main() {
|
|||
}
|
||||
defer client.Close()
|
||||
|
||||
err = client.ScheduleJobAlpha1(ctx, &job)
|
||||
err = client.ScheduleJobAlpha1(ctx, job)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
@ -78,7 +80,7 @@ func main() {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("getjob - resp: %v\n", resp) // parse
|
||||
fmt.Printf("getjob - resp: Name: %s, Schedule: %s, Repeats: %d, DueTime: %s, TTL: %s, Data: %v\n", resp.Name, *resp.Schedule, *resp.Repeats, *resp.DueTime, *resp.TTL, resp.Data) // parse
|
||||
|
||||
err = client.DeleteJobAlpha1(ctx, "prod-db-backup")
|
||||
if err != nil {
|
||||
|
|
@ -16,7 +16,7 @@ output_match_mode: substring
|
|||
expected_stdout_lines:
|
||||
- "ContentType:text/plain, Verb:POST, QueryString:, hellow"
|
||||
background: true
|
||||
sleep: 15
|
||||
sleep: 30
|
||||
timeout_seconds: 60
|
||||
-->
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
# Dapr Parallel Workflow Example with go-sdk
|
||||
|
||||
## Step
|
||||
|
||||
### Prepare
|
||||
|
||||
- Dapr installed
|
||||
|
||||
### Run Workflow
|
||||
|
||||
<!-- STEP
|
||||
name: Run Workflow
|
||||
output_match_mode: substring
|
||||
expected_stdout_lines:
|
||||
- '== APP == Workflow(s) and activities registered.'
|
||||
- 'work item listener started'
|
||||
- '== APP == RetryN 1'
|
||||
- '== APP == RetryN 2'
|
||||
- '== APP == RetryN 3'
|
||||
- '== APP == RetryN 4'
|
||||
- '== APP == RetryN 1'
|
||||
- '== APP == RetryN 2'
|
||||
- '== APP == RetryN 3'
|
||||
- '== APP == RetryN 4'
|
||||
- '== APP == workflow status: COMPLETED'
|
||||
- '== APP == workflow terminated'
|
||||
- '== APP == workflow purged'
|
||||
|
||||
background: true
|
||||
sleep: 30
|
||||
timeout_seconds: 60
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr run --app-id workflow-taskexecutionid \
|
||||
--dapr-grpc-port 50001 \
|
||||
--log-level debug \
|
||||
--resources-path ./config \
|
||||
-- go run ./main.go
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
## Result
|
||||
|
||||
```
|
||||
- '== APP == Workflow(s) and activities registered.'
|
||||
- 'work item listener started'
|
||||
- '== APP == RetryN 1'
|
||||
- '== APP == RetryN 2'
|
||||
- '== APP == RetryN 3'
|
||||
- '== APP == RetryN 4'
|
||||
- '== APP == RetryN 1'
|
||||
- '== APP == RetryN 2'
|
||||
- '== APP == RetryN 3'
|
||||
- '== APP == RetryN 4'
|
||||
- '== APP == workflow status: COMPLETED'
|
||||
- '== APP == workflow terminated'
|
||||
- '== APP == workflow purged'
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: wf-store
|
||||
spec:
|
||||
type: state.redis
|
||||
version: v1
|
||||
metadata:
|
||||
- name: redisHost
|
||||
value: localhost:6379
|
||||
- name: redisPassword
|
||||
value: ""
|
||||
- name: actorStateStore
|
||||
value: "true"
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/dapr/go-sdk/workflow"
|
||||
)
|
||||
|
||||
func main() {
|
||||
w, err := workflow.NewWorker()
|
||||
if err != nil {
|
||||
log.Fatalf("failed to initialise worker: %v", err)
|
||||
}
|
||||
|
||||
if err := w.RegisterWorkflow(TaskExecutionIdWorkflow); err != nil {
|
||||
log.Fatalf("failed to register workflow: %v", err)
|
||||
}
|
||||
if err := w.RegisterActivity(RetryN); err != nil {
|
||||
log.Fatalf("failed to register activity: %v", err)
|
||||
}
|
||||
fmt.Println("Workflow(s) and activities registered.")
|
||||
|
||||
if err := w.Start(); err != nil {
|
||||
log.Fatalf("failed to start worker")
|
||||
}
|
||||
|
||||
wfClient, err := workflow.NewClient()
|
||||
if err != nil {
|
||||
log.Fatalf("failed to initialise client: %v", err)
|
||||
}
|
||||
ctx := context.Background()
|
||||
id, err := wfClient.ScheduleNewWorkflow(ctx, "TaskExecutionIdWorkflow", workflow.WithInput(5))
|
||||
if err != nil {
|
||||
log.Fatalf("failed to schedule a new workflow: %v", err)
|
||||
}
|
||||
|
||||
metadata, err := wfClient.WaitForWorkflowCompletion(ctx, id)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to get workflow: %v", err)
|
||||
}
|
||||
fmt.Printf("workflow status: %s\n", metadata.RuntimeStatus.String())
|
||||
|
||||
err = wfClient.TerminateWorkflow(ctx, id)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to terminate workflow: %v", err)
|
||||
}
|
||||
fmt.Println("workflow terminated")
|
||||
|
||||
err = wfClient.PurgeWorkflow(ctx, id)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to purge workflow: %v", err)
|
||||
}
|
||||
fmt.Println("workflow purged")
|
||||
}
|
||||
|
||||
var eMap = sync.Map{}
|
||||
|
||||
func TaskExecutionIdWorkflow(ctx *workflow.WorkflowContext) (any, error) {
|
||||
var retries int
|
||||
if err := ctx.GetInput(&retries); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var workBatch []int
|
||||
if err := ctx.CallActivity(RetryN, workflow.ActivityRetryPolicy(workflow.RetryPolicy{
|
||||
MaxAttempts: retries,
|
||||
InitialRetryInterval: 100 * time.Millisecond,
|
||||
BackoffCoefficient: 2,
|
||||
MaxRetryInterval: 1 * time.Second,
|
||||
}), workflow.ActivityInput(retries)).Await(&workBatch); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err := ctx.CallActivity(RetryN, workflow.ActivityRetryPolicy(workflow.RetryPolicy{
|
||||
MaxAttempts: retries,
|
||||
InitialRetryInterval: 100 * time.Millisecond,
|
||||
BackoffCoefficient: 2,
|
||||
MaxRetryInterval: 1 * time.Second,
|
||||
}), workflow.ActivityInput(retries)).Await(&workBatch); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func RetryN(ctx workflow.ActivityContext) (any, error) {
|
||||
taskExecutionID := ctx.GetTaskExecutionID()
|
||||
counter, _ := eMap.LoadOrStore(taskExecutionID, &atomic.Int32{})
|
||||
var retries int32
|
||||
if err := ctx.GetInput(&retries); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
counter.(*atomic.Int32).Add(1)
|
||||
fmt.Println("RetryN ", counter.(*atomic.Int32).Load())
|
||||
|
||||
if counter.(*atomic.Int32).Load() < retries-1 {
|
||||
return nil, fmt.Errorf("failed")
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
||||
}
|
||||
|
|
@ -64,6 +64,10 @@ func main() {
|
|||
ctx := context.Background()
|
||||
|
||||
// Start workflow test
|
||||
// Set the start time to the current time to not wait for the workflow to
|
||||
// "start". This is useful for increasing the throughput of creating
|
||||
// workflows.
|
||||
// workflow.WithStartTime(time.Now())
|
||||
instanceID, err := wfClient.ScheduleNewWorkflow(ctx, "TestWorkflow", workflow.WithInstanceID("a7a4168d-3a1c-41da-8a4f-e7f6d9c718d9"), workflow.WithInput(1))
|
||||
if err != nil {
|
||||
log.Fatalf("failed to start workflow: %v", err)
|
||||
|
|
|
|||
31
go.mod
31
go.mod
|
|
@ -1,35 +1,34 @@
|
|||
module github.com/dapr/go-sdk
|
||||
|
||||
go 1.23.6
|
||||
go 1.24.4
|
||||
|
||||
require (
|
||||
github.com/dapr/dapr v1.15.0-rc.17
|
||||
github.com/dapr/durabletask-go v0.6.3
|
||||
github.com/go-chi/chi/v5 v5.1.0
|
||||
github.com/dapr/dapr v1.16.0-rc.3
|
||||
github.com/dapr/durabletask-go v0.7.3-0.20250711135247-7a35af6fe0e5
|
||||
github.com/dapr/kit v0.15.4
|
||||
github.com/go-chi/chi/v5 v5.2.2
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
google.golang.org/grpc v1.70.0
|
||||
google.golang.org/protobuf v1.36.4
|
||||
google.golang.org/grpc v1.73.0
|
||||
google.golang.org/protobuf v1.36.6
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/dapr/kit v0.15.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c // indirect
|
||||
golang.org/x/net v0.36.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 // indirect
|
||||
k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect
|
||||
go.opentelemetry.io/otel v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.36.0 // indirect
|
||||
golang.org/x/net v0.41.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/text v0.26.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
|
||||
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 // indirect
|
||||
)
|
||||
|
|
|
|||
72
go.sum
72
go.sum
|
|
@ -1,17 +1,17 @@
|
|||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/dapr/dapr v1.15.0-rc.17 h1:bR0rd4FH81IteuOHTWVNyl58ZuQTDp3DYaTtXnpZ6JA=
|
||||
github.com/dapr/dapr v1.15.0-rc.17/go.mod h1:SD0AXom2XpX7pr8eYlbJ+gHfNREsflsrzCR19AZJ7/Q=
|
||||
github.com/dapr/durabletask-go v0.6.3 h1:WHhSAw1YL4xneK3Jo5nGfmMaJxfFodIIF5q1rpkDDfs=
|
||||
github.com/dapr/durabletask-go v0.6.3/go.mod h1:nTZ5fCbJLnZbVdi6Z2YxdDF1OgQZL3LroogGuetrwuA=
|
||||
github.com/dapr/kit v0.15.0 h1:446jrEOQV/0rt6FwmoKrifP3vav5+Uh/u38DqU8q+JM=
|
||||
github.com/dapr/kit v0.15.0/go.mod h1:HwFsBKEbcyLanWlDZE7u/jnaDCD/tU+n3pkFNUctQNw=
|
||||
github.com/dapr/dapr v1.16.0-rc.3 h1:D99V20GOhb+bZXH1PngME+wgzIZCcBFOvmaP7DOZxGo=
|
||||
github.com/dapr/dapr v1.16.0-rc.3/go.mod h1:uyKnxMohSg87LSFzZ/oyuiGSo0+qkzeR0eXncPyIV9c=
|
||||
github.com/dapr/durabletask-go v0.7.3-0.20250711135247-7a35af6fe0e5 h1:l8oBGwcfCwqvSYDZwla0A2fhENmXFc1Wk4lR0VEq+is=
|
||||
github.com/dapr/durabletask-go v0.7.3-0.20250711135247-7a35af6fe0e5/go.mod h1:0Ts4rXp74JyG19gDWPcwNo5V6NBZzhARzHF5XynmA7Q=
|
||||
github.com/dapr/kit v0.15.4 h1:29DezCR22OuZhXX4yPEc+lqcOf/PNaeAuIEx9nGv394=
|
||||
github.com/dapr/kit v0.15.4/go.mod h1:HwFsBKEbcyLanWlDZE7u/jnaDCD/tU+n3pkFNUctQNw=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
|
||||
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618=
|
||||
github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
|
|
@ -21,8 +21,8 @@ github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
|||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
|
|
@ -43,26 +43,26 @@ github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf
|
|||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
|
||||
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
|
||||
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
|
||||
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
|
||||
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c h1:KL/ZBHXgKGVmuZBZ01Lt57yE5ws8ZPSkkihmEyq7FXc=
|
||||
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
|
||||
golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
|
||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
|
@ -71,30 +71,30 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 h1:J1H9f+LEdWAfHcez/4cvaVBox7cOYT+IU6rgqj5x++8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
|
||||
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
|
||||
k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 h1:jgJW5IePPXLGB8e/1wvd0Ich9QE97RvvF3a8J3fP/Lg=
|
||||
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ func TestListInputBindings(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
err = server.AddBindingInvocationHandler("test2", testBindingHandler)
|
||||
require.NoError(t, err)
|
||||
resp, err := server.ListInputBindings(context.Background(), &emptypb.Empty{})
|
||||
resp, err := server.ListInputBindings(t.Context(), &emptypb.Empty{})
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, resp)
|
||||
assert.Lenf(t, resp.GetBindings(), 2, "expected 2 handlers")
|
||||
|
|
@ -57,7 +57,7 @@ func TestBindingForErrors(t *testing.T) {
|
|||
|
||||
// go test -timeout 30s ./service/grpc -count 1 -run ^TestBinding$
|
||||
func TestBinding(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
methodName := "test"
|
||||
|
||||
server := getTestServer()
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ func TestHealthCheckHandlerForErrors(t *testing.T) {
|
|||
|
||||
// go test -timeout 30s ./service/grpc -count 1 -run ^TestHealthCheck$
|
||||
func TestHealthCheck(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
server := getTestServer()
|
||||
startTestServer(server)
|
||||
|
|
|
|||
|
|
@ -67,21 +67,21 @@ func TestInvokeWithToken(t *testing.T) {
|
|||
grpcMetadata := metadata.New(map[string]string{
|
||||
cc.APITokenKey: os.Getenv(cc.AppAPITokenEnvVar),
|
||||
})
|
||||
ctx := metadata.NewIncomingContext(context.Background(), grpcMetadata)
|
||||
ctx := metadata.NewIncomingContext(t.Context(), grpcMetadata)
|
||||
in := &common.InvokeRequest{Method: methodName}
|
||||
_, err := server.OnInvoke(ctx, in)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
t.Run("invoke with empty token, return failed", func(t *testing.T) {
|
||||
in := &common.InvokeRequest{Method: methodName}
|
||||
_, err := server.OnInvoke(context.Background(), in)
|
||||
_, err := server.OnInvoke(t.Context(), in)
|
||||
require.Error(t, err)
|
||||
})
|
||||
t.Run("invoke with mismatch token, return failed", func(t *testing.T) {
|
||||
grpcMetadata := metadata.New(map[string]string{
|
||||
cc.APITokenKey: "mismatch-token",
|
||||
})
|
||||
ctx := metadata.NewOutgoingContext(context.Background(), grpcMetadata)
|
||||
ctx := metadata.NewOutgoingContext(t.Context(), grpcMetadata)
|
||||
in := &common.InvokeRequest{Method: methodName}
|
||||
_, err := server.OnInvoke(ctx, in)
|
||||
require.Error(t, err)
|
||||
|
|
@ -93,7 +93,7 @@ func TestInvokeWithToken(t *testing.T) {
|
|||
func TestInvoke(t *testing.T) {
|
||||
methodName := "test"
|
||||
methodNameWithError := "error"
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
server := getTestServer()
|
||||
err := server.AddServiceInvocationHandler("/"+methodName, testInvokeHandler)
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ func TestTopicSubscriptionList(t *testing.T) {
|
|||
}
|
||||
err := server.AddTopicEventHandler(sub1, eventHandler)
|
||||
require.NoError(t, err)
|
||||
resp, err := server.ListTopicSubscriptions(context.Background(), &emptypb.Empty{})
|
||||
resp, err := server.ListTopicSubscriptions(t.Context(), &emptypb.Empty{})
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, resp)
|
||||
if assert.Lenf(t, resp.GetSubscriptions(), 1, "expected 1 handlers") {
|
||||
|
|
@ -76,7 +76,7 @@ func TestTopicSubscriptionList(t *testing.T) {
|
|||
}
|
||||
err = server.AddTopicEventHandler(sub2, eventHandler)
|
||||
require.NoError(t, err)
|
||||
resp, err = server.ListTopicSubscriptions(context.Background(), &emptypb.Empty{})
|
||||
resp, err = server.ListTopicSubscriptions(t.Context(), &emptypb.Empty{})
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, resp)
|
||||
if assert.Lenf(t, resp.GetSubscriptions(), 1, "expected 1 handlers") {
|
||||
|
|
@ -96,7 +96,7 @@ func TestTopicSubscriptionList(t *testing.T) {
|
|||
|
||||
// go test -timeout 30s ./service/grpc -count 1 -run ^TestTopic$
|
||||
func TestTopic(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
sub := &common.Subscription{
|
||||
PubsubName: "messages",
|
||||
|
|
@ -158,7 +158,7 @@ func TestTopic(t *testing.T) {
|
|||
Topic: sub2.Topic,
|
||||
PubsubName: sub2.PubsubName,
|
||||
}
|
||||
ctx := metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{"Metadata.key1": "value1"}))
|
||||
ctx := metadata.NewIncomingContext(t.Context(), metadata.New(map[string]string{"Metadata.key1": "value1"}))
|
||||
_, err = server.OnTopicEvent(ctx, in)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
|
@ -167,7 +167,7 @@ func TestTopic(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTopicWithValidationDisabled(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
sub := &common.Subscription{
|
||||
PubsubName: "messages",
|
||||
|
|
@ -197,7 +197,7 @@ func TestTopicWithValidationDisabled(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTopicWithErrors(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
sub1 := &common.Subscription{
|
||||
PubsubName: "messages",
|
||||
|
|
@ -269,7 +269,7 @@ func eventHandlerWithError(ctx context.Context, event *common.TopicEvent) (retry
|
|||
}
|
||||
|
||||
func TestEventDataHandling(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
tests := map[string]struct {
|
||||
contentType string
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ func TestParseWorkflow(t *testing.T) {
|
|||
|
||||
t.Run("parse testing workflow file", func(t *testing.T) {
|
||||
parsedVersion, err := parseWorkflowVersionFromFile("../../.github/workflows/test-tooling.yml")
|
||||
assert.Equal(t, "v1.61.0", parsedVersion)
|
||||
assert.Equal(t, "v1.64.6", parsedVersion)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ func TestParseWorkflow(t *testing.T) {
|
|||
func TestGetCurrentVersion(t *testing.T) {
|
||||
t.Run("get current version from system", func(t *testing.T) {
|
||||
currentVersion, err := getCurrentVersion()
|
||||
assert.Equal(t, "v1.61.0", currentVersion)
|
||||
assert.Equal(t, "v1.64.6", currentVersion)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
|
|
@ -49,23 +49,23 @@ func TestGetCurrentVersion(t *testing.T) {
|
|||
|
||||
func TestIsVersionValid(t *testing.T) {
|
||||
t.Run("compare versions - exactly equal to", func(t *testing.T) {
|
||||
assert.True(t, true, isVersionValid("v1.54.2", "v1.54.2"))
|
||||
assert.True(t, isVersionValid("v1.54.2", "v1.54.2"))
|
||||
})
|
||||
|
||||
t.Run("compare versions - patch version greater (workflow)", func(t *testing.T) {
|
||||
assert.True(t, true, isVersionValid("v1.54.3", "v1.54.2"))
|
||||
assert.True(t, isVersionValid("v1.54.3", "v1.54.2"))
|
||||
})
|
||||
|
||||
t.Run("compare versions - patch version greater (installed)", func(t *testing.T) {
|
||||
assert.True(t, true, isVersionValid("v1.54.2", "v1.54.3"))
|
||||
assert.True(t, isVersionValid("v1.54.2", "v1.54.3"))
|
||||
})
|
||||
|
||||
t.Run("compare versions - invalid (installed)", func(t *testing.T) {
|
||||
assert.False(t, false, isVersionValid("v1.54.2", "v1.52.2"))
|
||||
assert.False(t, isVersionValid("v1.54.2", "v1.52.2"))
|
||||
})
|
||||
|
||||
t.Run("compare versions - invalid (workflow)", func(t *testing.T) {
|
||||
assert.False(t, false, isVersionValid("v1.52.2", "v1.54.2"))
|
||||
assert.False(t, isVersionValid("v1.52.2", "v1.54.2"))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
v1.12.0
|
||||
v1.13.0
|
||||
|
|
@ -36,6 +36,10 @@ func (wfac *ActivityContext) Context() context.Context {
|
|||
return wfac.ctx.Context()
|
||||
}
|
||||
|
||||
func (wfac *ActivityContext) GetTaskExecutionID() string {
|
||||
return wfac.ctx.GetTaskExecutionID()
|
||||
}
|
||||
|
||||
type callActivityOption func(*callActivityOptions) error
|
||||
|
||||
type callActivityOptions struct {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,17 @@ import (
|
|||
)
|
||||
|
||||
type testingTaskActivityContext struct {
|
||||
inputBytes []byte
|
||||
inputBytes []byte
|
||||
ctx context.Context
|
||||
taskExecutionID string
|
||||
}
|
||||
|
||||
func (t *testingTaskActivityContext) GetTaskID() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (t *testingTaskActivityContext) GetTaskExecutionID() string {
|
||||
return t.taskExecutionID
|
||||
}
|
||||
|
||||
func (t *testingTaskActivityContext) GetInput(v any) error {
|
||||
|
|
@ -36,7 +46,7 @@ func (t *testingTaskActivityContext) GetInput(v any) error {
|
|||
}
|
||||
|
||||
func (t *testingTaskActivityContext) Context() context.Context {
|
||||
return context.TODO()
|
||||
return t.ctx
|
||||
}
|
||||
|
||||
func TestActivityContext(t *testing.T) {
|
||||
|
|
@ -44,7 +54,7 @@ func TestActivityContext(t *testing.T) {
|
|||
inputBytes, err := json.Marshal(inputString)
|
||||
require.NoErrorf(t, err, "required no error, but got %v", err)
|
||||
|
||||
ac := ActivityContext{ctx: &testingTaskActivityContext{inputBytes: inputBytes}}
|
||||
ac := ActivityContext{ctx: &testingTaskActivityContext{inputBytes: inputBytes, ctx: t.Context()}}
|
||||
t.Run("test getinput", func(t *testing.T) {
|
||||
var inputReturn string
|
||||
err := ac.GetInput(&inputReturn)
|
||||
|
|
@ -53,7 +63,7 @@ func TestActivityContext(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("test context", func(t *testing.T) {
|
||||
assert.Equal(t, context.TODO(), ac.Context())
|
||||
assert.Equal(t, t.Context(), ac.Context())
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -118,3 +128,19 @@ func TestMarshalData(t *testing.T) {
|
|||
assert.Equal(t, []byte{0x22, 0x74, 0x65, 0x73, 0x74, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22}, out)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTaskExecutionID(t *testing.T) {
|
||||
ac := ActivityContext{ctx: &testingTaskActivityContext{ctx: t.Context(), taskExecutionID: "testTaskExecutionID"}}
|
||||
|
||||
t.Run("test getTaskExecutionID", func(t *testing.T) {
|
||||
assert.Equal(t, "testTaskExecutionID", ac.GetTaskExecutionID())
|
||||
})
|
||||
}
|
||||
|
||||
func TestTaskID(t *testing.T) {
|
||||
ac := ActivityContext{ctx: &testingTaskActivityContext{ctx: t.Context(), taskExecutionID: "testTaskExecutionID"}}
|
||||
|
||||
t.Run("test getTaskID", func(t *testing.T) {
|
||||
assert.EqualValues(t, 0, ac.ctx.GetTaskID())
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,10 @@ func WithRawInput(input string) api.NewOrchestrationOptions {
|
|||
return api.WithRawInput(wrapperspb.String(input))
|
||||
}
|
||||
|
||||
// WithStartTime is an option to set the start time when scheduling a new workflow.
|
||||
// WithStartTime is an option to set the start time when scheduling a new
|
||||
// workflow. Setting this option will prevent Dapr from "waiting" for the
|
||||
// Workflow to start, meaning that it can improve workflow creation throughput.
|
||||
// Meaning setting this value to `time.Now()` can be useful.
|
||||
func WithStartTime(time time.Time) api.NewOrchestrationOptions {
|
||||
return api.WithStartTime(time)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ limitations under the License.
|
|||
package workflow
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -52,7 +51,7 @@ func TestClientMethods(t *testing.T) {
|
|||
testClient := Client{
|
||||
taskHubClient: nil,
|
||||
}
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
t.Run("ScheduleNewWorkflow - empty wf name", func(t *testing.T) {
|
||||
id, err := testClient.ScheduleNewWorkflow(ctx, "", WithReuseIDPolicy(WorkflowIDReusePolicy{
|
||||
OperationStatus: []Status{StatusCompleted},
|
||||
|
|
|
|||
|
|
@ -94,7 +94,16 @@ func (wfc *WorkflowContext) CallChildWorkflow(workflow interface{}, opts ...call
|
|||
// The value passed to the Await method must be a pointer or can be nil to ignore the returned value.
|
||||
// Alternatively, tasks can be awaited using the task.WhenAll or task.WhenAny methods, allowing the workflow
|
||||
// to block and wait for multiple tasks at the same time.
|
||||
func (wfc *WorkflowContext) CreateTimer(duration time.Duration) task.Task {
|
||||
func (wfc *WorkflowContext) CreateTimer(duration time.Duration, opts ...createTimerOption) task.Task {
|
||||
options := new(createTimerOptions)
|
||||
for _, configure := range opts {
|
||||
if err := configure(options); err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if options.name != nil {
|
||||
return wfc.orchestrationContext.CreateTimer(duration, task.WithTimerName(*options.name))
|
||||
}
|
||||
return wfc.orchestrationContext.CreateTimer(duration)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,22 +64,29 @@ func NewWorker(opts ...workerOption) (*WorkflowWorker, error) {
|
|||
return nil, errors.New("failed to load options")
|
||||
}
|
||||
}
|
||||
var daprClient dapr.Client
|
||||
var err error
|
||||
if options.daprClient == nil {
|
||||
daprClient, err = dapr.NewClient()
|
||||
} else {
|
||||
|
||||
var (
|
||||
daprClient dapr.Client
|
||||
err error
|
||||
closeFunc = func() {}
|
||||
)
|
||||
|
||||
if options.daprClient != nil {
|
||||
daprClient = options.daprClient
|
||||
} else {
|
||||
if daprClient, err = dapr.NewClient(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
closeFunc = daprClient.Close
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
grpcConn := daprClient.GrpcClientConn()
|
||||
|
||||
return &WorkflowWorker{
|
||||
tasks: task.NewTaskRegistry(),
|
||||
client: durabletaskclient.NewTaskHubGrpcClient(grpcConn, backend.DefaultLogger()),
|
||||
close: daprClient.Close,
|
||||
close: closeFunc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -148,3 +148,16 @@ func NewTaskSlice(length int) []task.Task {
|
|||
taskSlice := make([]task.Task, length)
|
||||
return taskSlice
|
||||
}
|
||||
|
||||
type createTimerOption func(*createTimerOptions) error
|
||||
|
||||
type createTimerOptions struct {
|
||||
name *string
|
||||
}
|
||||
|
||||
func WithTimerName(name string) createTimerOption {
|
||||
return func(opt *createTimerOptions) error {
|
||||
opt.name = &name
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/dapr/durabletask-go/api/protos"
|
||||
"github.com/dapr/durabletask-go/task"
|
||||
|
|
@ -76,3 +77,21 @@ func TestNewTaskSlice(t *testing.T) {
|
|||
tasks := NewTaskSlice(10)
|
||||
assert.Len(t, tasks, 10)
|
||||
}
|
||||
|
||||
func TestCreateTimerOptions(t *testing.T) {
|
||||
t.Run("create timer options - valid", func(t *testing.T) {
|
||||
opts := returnCreateTimerOptions(WithTimerName("test"))
|
||||
require.NotNil(t, opts.name)
|
||||
require.Equal(t, "test", *opts.name)
|
||||
})
|
||||
}
|
||||
|
||||
func returnCreateTimerOptions(opts ...createTimerOption) createTimerOptions {
|
||||
options := new(createTimerOptions)
|
||||
for _, configure := range opts {
|
||||
if err := configure(options); err != nil {
|
||||
return *options
|
||||
}
|
||||
}
|
||||
return *options
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue