TLDR: в этой статье мы рассмотрим, как можно объединить шаблоны слоев и Temporal.io для эффективного управления рабочими процессами и действиями в приложениях Golang. Этот подход позволяет разделить бизнес-логику и функции доступа к данным, что приводит к более упорядоченной и модульной структуре кода. Мы предоставляем примеры кода и объясняем преимущества этого архитектурного стиля для более надежного и эффективного управления рабочим процессом, уменьшения количества ошибок и оптимизации процесса разработки.
В этой статье мы рассмотрим, как можно интегрировать шаблоны слоев и Temporal.io для создания эффективной оркестровки рабочего процесса для приложений Golang. Такой подход позволяет разделить бизнес-логику и функции доступа к данным, делая код более рациональным, модульным и удобным в сопровождении.
Многоуровневая архитектура
Этот шаблон включает в себя разделение системы на отдельные уровни, отвечающие за различные функции, такие как представление, бизнес-логика и доступ к данным.
Структура:
main.go config/ config.go repository/ database.go service/ service.go workflow/ example_workflow.go activity/ example_activity.go messages/ example_messages.go
Файл main.go — это точка входа приложения. Он импортирует необходимые пакеты и запускает рабочий процесс.
Пакет конфигурации содержит файл config.go, который считывает значения конфигурации из файла или переменных среды для настройки приложения.
Пакет репозитория содержит файл database.go, который взаимодействует с базой данных для извлечения или хранения данных.
Пакет службы содержит файл service.go, который инкапсулирует сложную бизнес-логику и взаимодействует с базой данных через уровень репозитория.
Пакет рабочего процесса содержит файл example_workflow.go, определяющий основную логику рабочего процесса для механизма Temporal.io.
Пакет активности содержит файл example_activity.go, который определяет логику активности, выполняемую движком Temporal.io.
Пакет сообщений содержит файл example_messages.go, который определяет сообщение и его типы.
Вот пример функций ExampleWorkflow и ExampleActivity на сайтах example_workflow.go и example_activity.go соответственно:
// example_workflow.go func ExampleWorkflow(ctx workflow.Context) error { var data []string err := workflow.ExecuteActivity(ctx, ExampleActivity, "example").Get(ctx, &data) if err != nil { return err } // pass the data through the service layer service := NewExampleService() result, err := service.DoSomeComplexBusinessLogic(data) if err != nil { return err } // return the result to the caller return workflow.SetResult(ctx, result) } // example_activity.go func ExampleActivity(ctx context.Context, input string) ([]string, error) { // Try to retrieve data 3 times with 2 seconds between each retry in case of any error retryOptions := temporal.RetryOptions{ InitialInterval: time.Second * 2, BackoffCoefficient: 2.0, MaximumAttempts: 3, DoNotRetry: []error{ErrNonRetryable}, NonRetryableErrorTypes: []reflect.Type{reflect.TypeOf(ErrNonRetryable)}, } data, err := RetrieveDataFromDatabase(ctx, input) if err != nil { return nil, temporal.NewContinueAsNewError(ctx, ExampleActivity, input) } return data, nil } // database.go func RetrieveDataFromDatabase(ctx context.Context, key string) ([]string, error) { // Use the repository to retrieve data from the database repo := NewExampleRepository() data, err := repo.GetDataFromDatabaseByKey(ctx, key) if err != nil { return nil, err } return data, nil }
Эти функции демонстрируют, как многоуровневая архитектура работает с движком Temporal.io для управления рабочими процессами и действиями. Функция ExampleActivity повторяет попытку функции RetrieveDataFromDatabase в случае какой-либо ошибки с экспоненциальной задержкой и передает полученные данные через сервисный уровень для выполнения бизнес-логики. Когда бизнес-логика выполняется без ошибок, функция ExampleWorkflow использует механизм Temporal.io для установки результата рабочего процесса.
Структурируя приложение таким образом, мы можем разделить уровни доступа к данным и бизнес-логики, упрощая поддержку, управление и тестирование приложения.