Repository metrics
- Stars
- (25,672 stars)
- PR merge metrics
- (Avg merge 2d 19h) (63 merged PRs in 30d)
Description
In golang, context.Context is widely used and it's always be the first argument of go method and passed everywhere.
In dapr current implementation, for example, pkg/grpc/api.go, all the public method called by gRPC have the context object, and some them (service incation, actor ) pass context in the next step (always calling the component):
func (a *api) CallLocal(ctx context.Context, in *internalv1pb.InternalInvokeRequest) (*internalv1pb.InternalInvokeResponse, error) {
callAllowed, errMsg := a.applyAccessControlPolicies(ctx, operation, httpVerb, a.appProtocol)
resp, err := a.appChannel.InvokeMethod(ctx, req)
}
func (a *api) CallActor(ctx context.Context, in *internalv1pb.InternalInvokeRequest) (*internalv1pb.InternalInvokeResponse, error) {
resp, err := a.actor.Call(ctx, req)
}
func (a *api) InvokeService(ctx context.Context, in *runtimev1pb.InvokeServiceRequest) (*commonv1pb.InvokeResponse, error) {
resp, err := a.directMessaging.Invoke(ctx, in.Id, req)
}
func (a *api) GetActorState(ctx context.Context, in *runtimev1pb.GetActorStateRequest) (*runtimev1pb.GetActorStateResponse, error) {
resp, err := a.actor.GetState(ctx, &req)
}
And some of them (pub-sub / binding / state ) don't pass context:
func (a *api) PublishEvent(ctx context.Context, in *runtimev1pb.PublishEventRequest) (*emptypb.Empty, error) {
err = a.pubsubAdapter.Publish(&req)
}
func (a *api) SubscribeEvent(srv runtimev1pb.Dapr_SubscribeEventServer) error {
err := curPubsub.Subscribe(req, func(msg *pubsub.NewMessage) error
}
func (a *api) InvokeBinding(ctx context.Context, in *runtimev1pb.InvokeBindingRequest) (*runtimev1pb.InvokeBindingResponse, error) {
resp, err := a.sendToOutputBindingFn(in.Name, req)
}
func (a *api) GetState(ctx context.Context, in *runtimev1pb.GetStateRequest) (*runtimev1pb.GetStateResponse, error) {
getResponse, err := store.Get(&req)
}
So, there are big difference between components.
For example, actor api, all the method start with context argument :
type Actors interface {
Call(ctx context.Context, req *invokev1.InvokeMethodRequest) (*invokev1.InvokeMethodResponse, error)
Init() error
Stop()
GetState(ctx context.Context, req *GetStateRequest) (*StateResponse, error)
TransactionalStateOperation(ctx context.Context, req *TransactionalRequest) error
GetReminder(ctx context.Context, req *GetReminderRequest) (*Reminder, error)
CreateReminder(ctx context.Context, req *CreateReminderRequest) error
DeleteReminder(ctx context.Context, req *DeleteReminderRequest) error
CreateTimer(ctx context.Context, req *CreateTimerRequest) error
DeleteTimer(ctx context.Context, req *DeleteTimerRequest) error
IsActorHosted(ctx context.Context, req *ActorHostedRequest) bool
GetActiveActorsCount(ctx context.Context) []ActiveActorsCount
}
But state api, no context at all:
type Store interface {
BulkStore
Init(metadata Metadata) error
Delete(req *DeleteRequest) error
Get(req *GetRequest) (*GetResponse, error)
Set(req *SetRequest) error
}
type BulkStore interface {
BulkDelete(req []DeleteRequest) error
BulkGet(req []GetRequest) (bool, []BulkGetResponse, error)
BulkSet(req []SetRequest) error
}
I suggest to pass the context to all the components in golang style.
In fact, now I'm working to add tracting support in our state and bindings component, and I find that I can't get the context from the public API method of dapr gRPC service, I have to find other way (using metadata, again, we use metadata to do almost everything that dapr don't support) to pass the tracing information like traceid.