Реалізація Function Composition (Step Functions / Durable Functions)
Function Composition — це організація кількох безсерверних функцій у робочий процес з управлінням станом, розгалуженням, паралелізмом та обробкою помилок. Прямий виклик однієї Lambda/Function з іншої — це антипаттерн: втрачається історія, обробка помилок стає складною, немає видимості прогресу. Оркестратори вирішують ці проблеми.
Коли потрібна Function Composition
- Бізнес-процес складається з кількох кроків зі станом
- Потрібне умовне розгалуження (якщо крок_A успішний, то крок_B, інакше крок_C)
- Паралельне виконання кількох функцій з очікуванням результату
- Довгоживучі процеси (> 15 хвилин для Lambda)
- Людське затвердження на якомусь кроці (очікування callback)
AWS Step Functions
State Machine Language (ASL) описує робочий процес декларативно:
{
"Comment": "Обробка замовлення",
"StartAt": "ValidateOrder",
"States": {
"ValidateOrder": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123:function:validate-order",
"Next": "CheckInventory",
"Retry": [{"ErrorEquals": ["Lambda.ServiceException"], "MaxAttempts": 3}],
"Catch": [{
"ErrorEquals": ["ValidationError"],
"Next": "NotifyInvalidOrder"
}]
},
"CheckInventory": {
"Type": "Parallel",
"Branches": [
{"StartAt": "ReserveItems", "States": {"ReserveItems": {"Type": "Task", "Resource": "arn:...:reserve-items", "End": true}}},
{"StartAt": "CalculateShipping", "States": {"CalculateShipping": {"Type": "Task", "Resource": "arn:...:calc-shipping", "End": true}}}
],
"Next": "ProcessPayment"
},
"ProcessPayment": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke.waitForTaskToken",
"Parameters": {
"FunctionName": "arn:...:process-payment",
"Payload": {
"taskToken.$": "$$.Task.Token",
"orderId.$": "$.orderId"
}
},
"Next": "FulfillOrder",
"TimeoutSeconds": 300
},
"FulfillOrder": {"Type": "Task", "Resource": "arn:...:fulfill-order", "End": true},
"NotifyInvalidOrder": {"Type": "Task", "Resource": "arn:...:notify-invalid", "End": true}
}
}
.waitForTaskToken дозволяє Step Functions чекати callback від зовнішньої системи (платіжний шлюз) без polling. Платіжний шлюз викликає SendTaskSuccess з токеном, коли транзакція завершена.
Terraform для Step Functions
resource "aws_sfn_state_machine" "order_processing" {
name = "order-processing"
role_arn = aws_iam_role.sfn_role.arn
definition = templatefile("${path.module}/state_machine.json", {
validate_lambda_arn = aws_lambda_function.validate_order.arn
reserve_lambda_arn = aws_lambda_function.reserve_items.arn
payment_lambda_arn = aws_lambda_function.process_payment.arn
fulfill_lambda_arn = aws_lambda_function.fulfill_order.arn
})
logging_configuration {
log_destination = "${aws_cloudwatch_log_group.sfn.arn}:*"
include_execution_data = true
level = "ERROR"
}
tracing_configuration {
enabled = true # X-Ray tracing
}
}
Azure Durable Functions
Оркестратор на базі Azure Functions (.NET / Node.js / Python):
# функція оркестратора
import azure.durable_functions as df
def orchestrator_function(context: df.DurableOrchestrationContext):
# Паралельне виконання
parallel_tasks = [
context.call_activity("ReserveItems", context.get_input()),
context.call_activity("CalculateShipping", context.get_input())
]
results = yield context.task_all(parallel_tasks)
# Очікування зовнішньої події (людське затвердження)
approval = yield context.wait_for_external_event("ApprovalReceived")
if approval:
return (yield context.call_activity("FulfillOrder", context.get_input()))
else:
return (yield context.call_activity("CancelOrder", context.get_input()))
main = df.Orchestrator.create(orchestrator_function)
Durable Functions використовують Azure Storage для зберігання стану. Оркестратор може безмежно довго чекати зовнішню подію.
Обробка помилок та компенсуючі транзакції
У розподілених процесах немає вбудованих транзакцій. Паттерн Saga використовує компенсуючі дії при откату:
"ProcessPayment": {
"Type": "Task",
"Resource": "...",
"Catch": [{
"ErrorEquals": ["PaymentFailed"],
"Next": "CompensateReservation"
}]
},
"CompensateReservation": {
"Type": "Task",
"Resource": "arn:...:release-reservation",
"Next": "NotifyPaymentFailed"
}
Кожен крок, який потрібно откатити при помилці, має компенсуючу функцію.
Видимість та моніторинг
Step Functions надає візуальний робочий процес у консолі — кожне виконання можна переглянути крок за кроком. CloudWatch Metrics: ExecutionsStarted, ExecutionsSucceeded, ExecutionsFailed, ExecutionThrottled.
Інтеграція X-Ray забезпечує трейсинг через усі Lambda функції у робочому процесі.
Express vs Standard Workflows
| Standard | Express | |
|---|---|---|
| Тривалість | До 1 року | До 5 хвилин |
| Історія виконання | Повна | CloudWatch Logs |
| Ціна | $0.025/1k transitions | $0.00001/state transition |
| Найкраще для | Бізнес-процеси | High-volume, short workflows |
Графік впровадження
- Проектування state machine + специфікація ASL — 2-3 дні
- Lambda функції для кожного кроку — 3-7 днів
- Step Functions state machine + IAM — 2-3 дні
- Обробка помилок + компенсації — 2-3 дні
- Моніторинг + алерти + тестування — 2-3 дні







