use of io.temporal.api.taskqueue.v1.StickyExecutionAttributes in project sdk-java by temporalio.
the class TestWorkflowMutableStateImpl method completeWorkflowTask.
@Override
public void completeWorkflowTask(int historySizeFromToken, RespondWorkflowTaskCompletedRequest request) {
List<Command> commands = request.getCommandsList();
completeWorkflowTaskUpdate(ctx -> {
if (ctx.getInitialEventId() != historySizeFromToken + 1) {
throw Status.NOT_FOUND.withDescription("Expired workflow task: expectedHistorySize=" + historySizeFromToken + "," + " actualHistorySize=" + ctx.getInitialEventId()).asRuntimeException();
}
long workflowTaskCompletedId = ctx.getNextEventId() - 1;
// Fail the workflow task if there are new events and a command tries to complete the
// workflow
boolean newEvents = false;
for (RequestContext ctx2 : workflowTaskStateMachine.getData().bufferedEvents) {
if (!ctx2.getEvents().isEmpty()) {
newEvents = true;
break;
}
}
if (newEvents && hasCompletionCommand(request.getCommandsList())) {
RespondWorkflowTaskFailedRequest failedRequest = RespondWorkflowTaskFailedRequest.newBuilder().setCause(WorkflowTaskFailedCause.WORKFLOW_TASK_FAILED_CAUSE_UNHANDLED_COMMAND).setIdentity(request.getIdentity()).build();
workflowTaskStateMachine.action(Action.FAIL, ctx, failedRequest, workflowTaskCompletedId);
for (RequestContext deferredCtx : workflowTaskStateMachine.getData().bufferedEvents) {
ctx.add(deferredCtx);
}
workflowTaskStateMachine.getData().bufferedEvents.clear();
scheduleWorkflowTask(ctx);
return;
}
try {
workflowTaskStateMachine.action(StateMachines.Action.COMPLETE, ctx, request, 0);
for (Command command : commands) {
processCommand(ctx, command, request.getIdentity(), workflowTaskCompletedId);
}
for (RequestContext deferredCtx : workflowTaskStateMachine.getData().bufferedEvents) {
ctx.add(deferredCtx);
}
WorkflowTaskData data = this.workflowTaskStateMachine.getData();
boolean completed = workflow.getState() == StateMachines.State.COMPLETED || workflow.getState() == StateMachines.State.FAILED || workflow.getState() == StateMachines.State.CANCELED;
if (!completed && ((ctx.isNeedWorkflowTask() || !workflowTaskStateMachine.getData().bufferedEvents.isEmpty()) || request.getForceCreateNewWorkflowTask())) {
scheduleWorkflowTask(ctx);
}
workflowTaskStateMachine.getData().bufferedEvents.clear();
Map<String, ConsistentQuery> queries = data.consistentQueryRequests;
Map<String, WorkflowQueryResult> queryResultsMap = request.getQueryResultsMap();
for (Map.Entry<String, WorkflowQueryResult> resultEntry : queryResultsMap.entrySet()) {
String key = resultEntry.getKey();
ConsistentQuery query = queries.remove(key);
if (query != null) {
WorkflowQueryResult result = resultEntry.getValue();
switch(result.getResultType()) {
case QUERY_RESULT_TYPE_ANSWERED:
QueryWorkflowResponse response = QueryWorkflowResponse.newBuilder().setQueryResult(result.getAnswer()).build();
query.getResult().complete(response);
break;
case QUERY_RESULT_TYPE_FAILED:
query.getResult().completeExceptionally(StatusUtils.newException(Status.INTERNAL.withDescription(result.getErrorMessage()), QueryFailedFailure.getDefaultInstance()));
break;
case UNRECOGNIZED:
throw Status.INVALID_ARGUMENT.withDescription("UNRECOGNIZED query result type for =" + resultEntry.getKey()).asRuntimeException();
}
}
}
ctx.onCommit((historySize -> {
if (workflowTaskStateMachine.getState() == State.INITIATED) {
for (ConsistentQuery query : data.queryBuffer.values()) {
workflowTaskStateMachine.action(Action.QUERY, ctx, query, NO_EVENT_ID);
}
} else {
for (ConsistentQuery consistent : data.queryBuffer.values()) {
QueryId queryId = new QueryId(executionId, consistent.getKey());
PollWorkflowTaskQueueResponse.Builder task = PollWorkflowTaskQueueResponse.newBuilder().setTaskToken(queryId.toBytes()).setWorkflowExecution(executionId.getExecution()).setWorkflowType(startRequest.getWorkflowType()).setQuery(consistent.getRequest().getQuery()).setWorkflowExecutionTaskQueue(startRequest.getTaskQueue());
TestWorkflowStore.TaskQueueId taskQueueId = new TestWorkflowStore.TaskQueueId(consistent.getRequest().getNamespace(), stickyExecutionAttributes == null ? startRequest.getTaskQueue().getName() : stickyExecutionAttributes.getWorkerTaskQueue().getName());
store.sendQueryTask(executionId, taskQueueId, task);
this.queries.put(queryId.getQueryId(), consistent.getResult());
}
}
data.queryBuffer.clear();
}));
} finally {
ctx.unlockTimer("completeWorkflowTask");
}
}, request.hasStickyAttributes() ? request.getStickyAttributes() : null);
}
use of io.temporal.api.taskqueue.v1.StickyExecutionAttributes in project sdk-java by temporalio.
the class StateMachines method scheduleQueryWorkflowTask.
private static void scheduleQueryWorkflowTask(RequestContext ctx, WorkflowTaskData data, TestWorkflowMutableStateImpl.ConsistentQuery query, long notUsed) {
ctx.lockTimer("scheduleQueryWorkflowTask");
StartWorkflowExecutionRequest request = data.startRequest;
PollWorkflowTaskQueueResponse.Builder workflowTaskResponse = PollWorkflowTaskQueueResponse.newBuilder();
StickyExecutionAttributes stickyAttributes = ctx.getWorkflowMutableState().getStickyExecutionAttributes();
String taskQueue = stickyAttributes == null ? request.getTaskQueue().getName() : stickyAttributes.getWorkerTaskQueue().getName();
workflowTaskResponse.setWorkflowExecution(ctx.getExecution());
workflowTaskResponse.setWorkflowType(request.getWorkflowType());
workflowTaskResponse.setAttempt(data.attempt);
TaskQueueId taskQueueId = new TaskQueueId(ctx.getNamespace(), taskQueue);
WorkflowTask workflowTask = new WorkflowTask(taskQueueId, workflowTaskResponse);
ctx.setWorkflowTask(workflowTask);
ctx.onCommit((historySize) -> {
if (data.lastSuccessfulStartedEventId > 0) {
workflowTaskResponse.setPreviousStartedEventId(data.lastSuccessfulStartedEventId);
}
data.scheduledEventId = NO_EVENT_ID;
data.workflowTask = workflowTaskResponse;
if (query != null) {
data.consistentQueryRequests.put(query.getKey(), query);
}
});
}
use of io.temporal.api.taskqueue.v1.StickyExecutionAttributes in project sdk-java by temporalio.
the class ReplayWorkflowRunTaskHandlerTaskHandlerTests method ifStickyExecutionAttributesAreSetThenWorkflowsAreCached.
@Test
public void ifStickyExecutionAttributesAreSetThenWorkflowsAreCached() throws Throwable {
// Arrange
WorkflowExecutorCache cache = new WorkflowExecutorCache(10, new NoopScope());
WorkflowTaskHandler taskHandler = new ReplayWorkflowTaskHandler("namespace", setUpMockWorkflowFactory(), cache, SingleWorkerOptions.newBuilder().build(), "sticky", Duration.ofSeconds(5), service, null);
PollWorkflowTaskQueueResponse workflowTask = HistoryUtils.generateWorkflowTaskWithInitialHistory();
WorkflowTaskHandler.Result result = taskHandler.handleWorkflowTask(workflowTask);
assertTrue(result.isCompletionCommand());
// do not cache if completion command
assertEquals(0, cache.size());
assertNotNull(result.getTaskCompleted());
StickyExecutionAttributes attributes = result.getTaskCompleted().getStickyAttributes();
assertEquals("sticky", attributes.getWorkerTaskQueue().getName());
assertEquals(Durations.fromSeconds(5), attributes.getScheduleToStartTimeout());
}
use of io.temporal.api.taskqueue.v1.StickyExecutionAttributes in project sdk-java by temporalio.
the class TestWorkflowStoreImpl method save.
@Override
public long save(RequestContext ctx) {
long result;
lock.lock();
try {
ExecutionId executionId = ctx.getExecutionId();
HistoryStore history = histories.get(executionId);
List<HistoryEvent> events = ctx.getEvents();
if (history == null) {
if (events.isEmpty() || events.get(0).getEventType() != EventType.EVENT_TYPE_WORKFLOW_EXECUTION_STARTED) {
throw new IllegalStateException("No history found for " + executionId);
}
history = new HistoryStore(executionId, lock);
histories.put(executionId, history);
}
history.checkNextEventId(ctx.getInitialEventId());
history.addAllLocked(events, ctx.currentTime());
result = history.getNextEventIdLocked();
timerService.updateLocks(ctx.getTimerLocks());
ctx.fireCallbacks(history.getEventsLocked().size());
} finally {
if (emptyHistoryLockHandle != null && !histories.isEmpty()) {
// Initially locked in the constructor
emptyHistoryLockHandle.unlock("TestWorkflowStoreImpl first save");
emptyHistoryLockHandle = null;
}
lock.unlock();
}
// Push tasks to the queues out of locks
WorkflowTask workflowTask = ctx.getWorkflowTask();
if (workflowTask != null) {
StickyExecutionAttributes attributes = ctx.getWorkflowMutableState().getStickyExecutionAttributes();
TaskQueueId id = new TaskQueueId(workflowTask.getTaskQueueId().getNamespace(), attributes == null ? workflowTask.getTaskQueueId().getTaskQueueName() : attributes.getWorkerTaskQueue().getName());
if (id.getTaskQueueName().isEmpty() || id.getNamespace().isEmpty()) {
throw Status.INTERNAL.withDescription("Invalid TaskQueueId: " + id).asRuntimeException();
}
TaskQueue<PollWorkflowTaskQueueResponse.Builder> workflowTaskQueue = getWorkflowTaskQueueQueue(id);
workflowTaskQueue.add(workflowTask.getTask());
}
List<ActivityTask> activityTasks = ctx.getActivityTasks();
if (activityTasks != null) {
for (ActivityTask activityTask : activityTasks) {
TaskQueue<PollActivityTaskQueueResponse.Builder> activityTaskQueue = getActivityTaskQueueQueue(activityTask.getTaskQueueId());
activityTaskQueue.add(activityTask.getTask());
}
}
List<Timer> timers = ctx.getTimers();
if (timers != null) {
for (Timer t : timers) {
log.trace("scheduling timer with " + t.getDelay() + "delay. Current time=" + this.currentTime());
Functions.Proc cancellationHandle = timerService.schedule(t.getDelay(), t.getCallback(), t.getTaskInfo());
t.setCancellationHandle(cancellationHandle);
}
}
return result;
}
Aggregations