Выполнение рабочего процесса завершается неудачно, когда работник перезапускается на том же клиенте службы рабочего процесса
Мы находимся в процессе написания клиента.NET Cadence и столкнулись с проблемой во время рабочих процессов модульного тестирования. Когда мы запускаем работника, выполняем рабочий процесс, останавливаем работника, запускаем его снова, а затем пытаемся выполнить другой рабочий процесс, первый рабочий процесс завершается, но любой рабочий процесс после первого зависает во время client.ExecuteWorkflow()
позвонить, в конечном итоге не удается с START_TO_CLOSE
тайм-аут. Я повторил это поведение путем манипулирования рабочим процессом cadence-samples. Смотрите петлю в func main()
:
package main
import (
"context"
"time"
"go.uber.org/cadence/client"
"go.uber.org/cadence/worker"
"go.uber.org/zap"
"github.com/pborman/uuid"
"github.com/samarabbas/cadence-samples/cmd/samples/common"
)
// This needs to be done as part of a bootstrap step when the process starts.
// The workers are supposed to be long running.
func startWorkers(h *common.SampleHelper) worker.Worker {
// Configure worker options.
workerOptions := worker.Options{
MetricsScope: h.Scope,
Logger: h.Logger,
}
return h.StartWorkers(h.Config.DomainName, ApplicationName, workerOptions)
}
func startWorkflow(h *common.SampleHelper) client.WorkflowRun {
workflowOptions := client.StartWorkflowOptions{
ID: "greetings_" + uuid.New(),
TaskList: ApplicationName,
ExecutionStartToCloseTimeout: time.Minute,
DecisionTaskStartToCloseTimeout: time.Minute,
}
return h.StartWorkflow(workflowOptions, SampleGreetingsWorkflow)
}
func main() {
// setup the SampleHelper
var h common.SampleHelper
h.SetupServiceConfig()
// Loop:
// - start a worker
// - start a workflow
// - block and wait for workflow result
// - stop the worker
for i := 0; i < 3; i++ {
// start the worker
// execute the workflow
workflowWorker := startWorkers(&h)
workflowRun := startWorkflow(&h)
// create context
// get workflow result
var result string
ctx, cancel := context.WithCancel(context.Background())
err := workflowRun.Get(ctx, &result)
if err != nil {
panic(err)
}
// log the result
h.Logger.Info("Workflow Completed", zap.String("Result", result))
// stop the worker
// cancel the context
workflowWorker.Stop()
cancel()
}
}
Это не проблема блокировки и, вероятно, не появится в производстве.
Фон:
Мы ( Jeff Lill и я) заметили эту проблему во время рабочих процессов модульного тестирования в нашем клиенте.NET Cadence. Когда мы запускаем наши тесты рабочего процесса по отдельности, они все проходят, но когда мы запускаем несколько одновременно (последовательно, а не параллельно), мы видим поведение, описанное выше. Это из-за очистки, выполненной в клиенте.NET Cadence dispose()
метод вызывается после завершения теста (успешно или успешно). Одним из способов утилизации является остановка рабочих, созданных во время теста. Когда запускается следующий тест, новые рабочие создаются с использованием того же клиента службы потока операций, и именно здесь возникает проблема.