elglin: (Default)
elglin ([personal profile] elglin) wrote2020-04-04 06:42 pm

Да здравствует указатель на функцию

В своем текущем поделии как разумный человек я вынес всю работу с базой в отдельный модуль. И фоновые задачи у меня тоже живут в отдельном от вебинтерфейса модуле.
И тут возникла проблема. Как часто бывает, некоторую часть реализации бизнес-логики надо делать в контексте одной SQL-транзакции (SELECT FOR UPDATE + UPDATE). И тут получается, что либо надо затаскивать транзакцию в логику (до свидания, инкапсуляция БД), либо совать сложную логику в контекст работы с базой (нечего ей там делать). И кольцевые импорты опять же.
Но тут, раз все равно работаю с асинхронщиной, решение пришло практически само. При вызове функции работы с БД ей в т.ч. передается коллбэк родом из модуля фоновых задач. Инкапсуляция на месте, кольцевых импортов нет, и пастуху вечная память.

Да, чтобы два раза не вставать. Как только у вас вместо долгого и задумчивого 201 Created появляется быстрый и резкий 202 Accepted, у вас сразу же возникают проблемы с внутренней консистентностью, которую надо решать. Грубо говоря, из двух действий: "сделать что-то" и "записать, что сделал что-то" вы всегда сначала делаете одно, а потом другое, и вот если панночка померла аккурат между ними, то у вас неконсистентность. В сколь-нибудь распределенной системе, в которой есть сколь-нибудь долгие процессы, панночка будет регулярно помирать именно в этой позе.
beldmit: (Программизм)

[personal profile] beldmit 2020-04-04 04:23 pm (UTC)(link)
У меня в последнем проекте каждая операция с точки зрения бизнеса - одна транзакция. В начале функции проверяем, что мы внутри таковой. Да, SELECT FOR UPDATE внутри этого модуля там, где нужен.

С внутренней консистентностью проблема возникает, если надо как-то провзаимодействовать с внешним миром (письмо отправить или к сервису стукнуться). Да, неконсистентность тут запросто вылезет, ну а дальше вопрос про частоту отвала того сервиса. Может, проще ручками устранить раз в неделю, что мы запрос послали, сервер его отработал, а коннект оторвался. Ну а пользователь всяко перетопчется, если получит 2 письма вместо одного.
beldmit: (Default)

[personal profile] beldmit 2020-04-05 11:14 am (UTC)(link)
Ну да, к этому все и приходят :)