Entry tags:
Да здравствует указатель на функцию
В своем текущем поделии как разумный человек я вынес всю работу с базой в отдельный модуль. И фоновые задачи у меня тоже живут в отдельном от вебинтерфейса модуле.
И тут возникла проблема. Как часто бывает, некоторую часть реализации бизнес-логики надо делать в контексте одной SQL-транзакции (SELECT FOR UPDATE + UPDATE). И тут получается, что либо надо затаскивать транзакцию в логику (до свидания, инкапсуляция БД), либо совать сложную логику в контекст работы с базой (нечего ей там делать). И кольцевые импорты опять же.
Но тут, раз все равно работаю с асинхронщиной, решение пришло практически само. При вызове функции работы с БД ей в т.ч. передается коллбэк родом из модуля фоновых задач. Инкапсуляция на месте, кольцевых импортов нет, и пастуху вечная память.
Да, чтобы два раза не вставать. Как только у вас вместо долгого и задумчивого 201 Created появляется быстрый и резкий 202 Accepted, у вас сразу же возникают проблемы с внутренней консистентностью, которую надо решать. Грубо говоря, из двух действий: "сделать что-то" и "записать, что сделал что-то" вы всегда сначала делаете одно, а потом другое, и вот если панночка померла аккурат между ними, то у вас неконсистентность. В сколь-нибудь распределенной системе, в которой есть сколь-нибудь долгие процессы, панночка будет регулярно помирать именно в этой позе.
И тут возникла проблема. Как часто бывает, некоторую часть реализации бизнес-логики надо делать в контексте одной SQL-транзакции (SELECT FOR UPDATE + UPDATE). И тут получается, что либо надо затаскивать транзакцию в логику (до свидания, инкапсуляция БД), либо совать сложную логику в контекст работы с базой (нечего ей там делать). И кольцевые импорты опять же.
Но тут, раз все равно работаю с асинхронщиной, решение пришло практически само. При вызове функции работы с БД ей в т.ч. передается коллбэк родом из модуля фоновых задач. Инкапсуляция на месте, кольцевых импортов нет, и пастуху вечная память.
Да, чтобы два раза не вставать. Как только у вас вместо долгого и задумчивого 201 Created появляется быстрый и резкий 202 Accepted, у вас сразу же возникают проблемы с внутренней консистентностью, которую надо решать. Грубо говоря, из двух действий: "сделать что-то" и "записать, что сделал что-то" вы всегда сначала делаете одно, а потом другое, и вот если панночка померла аккурат между ними, то у вас неконсистентность. В сколь-нибудь распределенной системе, в которой есть сколь-нибудь долгие процессы, панночка будет регулярно помирать именно в этой позе.
no subject
С внутренней консистентностью проблема возникает, если надо как-то провзаимодействовать с внешним миром (письмо отправить или к сервису стукнуться). Да, неконсистентность тут запросто вылезет, ну а дальше вопрос про частоту отвала того сервиса. Может, проще ручками устранить раз в неделю, что мы запрос послали, сервер его отработал, а коннект оторвался. Ну а пользователь всяко перетопчется, если получит 2 письма вместо одного.
no subject
Так оно получится как dynamic sql, что геморойно, но вполне реализуемо
no subject
1. Записал конфиг для сервиса.
2. Дернул сервис.
3. Получил коллбэк от сервиса.
4. Записал, что сервис рапортовал о завершении.
И вот если на п.3 приклад был по какой-то причине мертвенький, то все плохо. Значит, надо на стороне внешнего сервиса городить ретраи.
Вообще, конечно, логика at least once и at most once реализуется тривиально (пнул, записал и записал, пнул). Вот exactly once - это сложнее.
Правда, на этом этапе мы вполне переживаем ситуацию: "когда приклад сдох, у него три задачи висело в неконсистентном состоянии; оператор, сходи в логи внешних сервисов и руками закрой или поретрай".
no subject
no subject
no subject