Шаблон транзакции / запрос-ответ в потоковом / реактивном программировании - PullRequest
0 голосов
/ 06 июня 2019

Итак, я читал о программировании на основе потоков (FBP) в последние несколько дней, и я также читал книгу Дж. Пола Моррисона об этом.Однако я чувствую, что все еще не могу обернуть голову вокруг этого.Общая концепция заключается в том, что вы рассматриваете программирование как своего рода сборочную линию, где у вас есть компоненты, которые принимают некоторый пакет на вход и производят несколько пакетов на выходе.Вы можете подключить эти компоненты и пакеты путешествовать по сети.Хотя я полностью понимаю, как это может работать для приложений типа ETL или пакетной обработки, я не имею ни малейшего представления, как вы могли бы обрабатывать такие вещи, как синхронные шаблоны запросов / ответов или транзакции базы данных с ним.

Например, допустим, у меня есть веб-сервер, реализованный как FPB.Этот веб-сервер имеет GET / user / {id}, который должен возвращать JSON с некоторой информацией о пользователе.Он также имеет POST / user / {id}, где вы можете обновить пользователя, отправив часть JSON обратно на сервер.Вот как я мог бы представить себе этот поток:

Example Flow

Я пытался использовать многократно используемые компоненты вместо того, чтобы использовать всю логикуобработка запроса в один компонент.Таким образом, существует компонент HTTP-сервера, который отправляет запросы компоненту диспетчера, который затем отправляет запросы в последующие потоки.В каждом потоке запрос анализируется общим компонентом «Анализатор запросов», который выводит различные части запроса в остальную часть потока.

Верхняя часть довольно проста: я читаю сущность пользователя с заданным идентификатором из БД, сериализую объект в JSON и затем отправляю его обратно.Однако на данный момент у нас больше нет ссылки на HTTP-запрос, так как я узнаю, куда отправить этот запрос?

В нижней части у нас есть некоторые дополнительные сложности, потому что я хотел бы записать в базу данных транзакционным способом.Итак, сначала запускается транзакция (параллельно тело запроса разбирается на некоторый объект), затем пользовательский объект извлекается из базы данных и объединяется с входными данными из запроса.В конце он записывается обратно в базу данных и транзакция фиксируется.Наконец, некоторое состояние «ОК» отвечает вызывающему абоненту.Здесь у меня есть дополнительная проблема, заключающаяся в том, что при фиксации транзакции я действительно не знаю, какую транзакцию зафиксировать.И, конечно, при отправке ответа я не знаю, на какой запрос его отправлять.

Таким образом, обе проблемы, похоже, имеют что-то общее - своего рода «контекст», охватывающий многие компоненты.В одном примере это контекст запроса / ответа HTTP, в другом - транзакционный контекст.В обычном программировании эти контексты обычно обрабатываются на уровне потока.Поскольку запрос выполняется в одном потоке, контексты транзакции и запроса привязаны к локальному потоку, поэтому к ним можно обращаться везде, пока все выполняется в одном потоке.

В программировании на основе потоков каждый компонент работает независимо и в идеале в отдельных потоках.Это на самом деле ключевая вещь, потому что она позволяет распараллеливать и эффективно использовать несколько процессоров.Однако, когда этот локальный контекст протектора больше не существует, как вы можете справиться с этими проблемами в потоковом программировании?Это было бы еще сложнее с правильной обработкой ошибок (которую я пропустил в моем примере).

Я полагаю, что когда вы выполняете программирование в реактивном стиле, где большая часть обработки асинхронна и многопоточна, вы получитетакие же проблемы, поэтому мне интересно, есть ли шаблоны для решения этой проблемы.У вас есть реальный опыт работы с программированием реактивного стиля или программированием на основе потоков, и у вас есть советы о том, как я могу решить эту проблему?

...