Asynchronous activity cancellation

Hi guys, I’m a newbie with Temporal and have been struggling with a problem.

I’m trying to cancel an asynchronous activity with the ActivityCompletionClient. I think the right way is to call the reportCancellation() but always have an exception. The replication case is easy, just change one line in the HelloAsyncActivityCompletion.java example. Change:
completionClient.complete(taskToken, result);
by
completionClient.reportCancellation(taskToken, result);

And the Java example shows:

io.grpc.StatusRuntimeException: DEADLINE_EXCEEDED: deadline exceeded after 9.999701372s. [remote_addr=127.0.0.1/127.0.0.1:7233]

And from temporal logs:

    {"level":"warn","ts":"2021-03-04T18:08:25.720Z","msg":"invalid history builder state for action","service":"history","shard-id":4,"address":"172.23.0.3:7234","shard-item":"0xc000978280","component":"history-cache","wf-action":"add-activitytask-canceled-event","wf-history-event-id":6,"error":"InvalidHistoryAction","wf-schedule-id":5,"wf-activity-id":"2117ce21-71a0-3812-8b9c-ce3d714a0db6","wf-started-id":-124,"wf-id":"b664fda4-6290-44a3-b4df-1c91691da51b","wf-run-id":"3c556d27-51ff-4503-a189-6c941a46abaf","wf-namespace-id":"b4ccae00-ef7b-4262-865d-1829aad8b393","logging-call-at":"mutableStateBuilder.go:4617"}

    {"level":"error","ts":"2021-03-04T18:08:25.720Z","msg":"Internal service error","service":"history","error":"Unable to add ActivityTaskCanceled event to history.","wf-id":"b664fda4-6290-44a3-b4df-1c91691da51b","wf-namespace-id":"b4ccae00-ef7b-4262-865d-1829aad8b393","logging-call-at":"handler.go:1788","stacktrace":"go.temporal.io/server/common/log/loggerimpl.(*loggerImpl).Error\n\t/temporal/common/log/loggerimpl/logger.go:138\ngo.temporal.io/server/service/history.(*Handler).updateErrorMetric\n\t/temporal/service/history/handler.go:1788\ngo.temporal.io/server/service/history.(*Handler).error\n\t/temporal/service/history/handler.go:1806\ngo.temporal.io/server/service/history.(*Handler).RespondActivityTaskCanceled\n\t/temporal/service/history/handler.go:514\ngo.temporal.io/server/api/historyservice/v1._HistoryService_RespondActivityTaskCanceled_Handler.func1\n\t/temporal/api/historyservice/v1/service.pb.go:1059\ngo.temporal.io/server/common/rpc.ServiceErrorInterceptor\n\t/temporal/common/rpc/grpc.go:100\ngo.temporal.io/server/api/historyservice/v1._HistoryService_RespondActivityTaskCanceled_Handler\n\t/temporal/api/historyservice/v1/service.pb.go:1061\ngoogle.golang.org/grpc.(*Server).processUnaryRPC\n\t/go/pkg/mod/google.golang.org/grpc@v1.34.0/server.go:1210\ngoogle.golang.org/grpc.(*Server).handleStream\n\t/go/pkg/mod/google.golang.org/grpc@v1.34.0/server.go:1533\ngoogle.golang.org/grpc.(*Server).serveStreams.func1.2\n\t/go/pkg/mod/google.golang.org/grpc@v1.34.0/server.go:871"}

Is this the correct way to do it?

The only time RespondActivityTaskCanceled can be called is when activity cancellation was requested by a workflow. The only way for an activity to learn about a cancellation request is to heartbeat.

If you want to stop activity execution without workflow requesting cancellation then call RespondActivityTaskFailed or cancelled.

Thank you Maxim.

I understand that the heartbeat is the right way to do it when activity cancellations were requested by a workflow.

But the last part of your comment “… or cancelled” I do not understand. I can call RespondActivityTaskFailed or complete, no problem about that, but how I achieve get/call “cancelled” ?.

In Temporal, cancellation by definition is a request from the caller to stop the execution of some action. It looks like you are trying to fail the activity without workflow requesting it. So to unblock the call fail the activity using RespondActivityTaskFailed.

1 Like

Thank you for the reply, I will use RespondActivityTaskFailed in that case.