с каким-то id для того, чтоб обеспечить отсутствие race condition между actions при запросах в бд?
Тебе нужно партицирование для того, чтобы экшны пользователя выстраивались в цепочку? Да, нормально А как ты будешь реализовывать это?
в принципе нормально, но по хорошему у тебя юай не должен разрешать юзеру делать что-то, что может нарушить инвариант в базе, ну т.е. если второй экшон имеет смысл только после первого, то и давать пользователю делать второй экшон нужно только после отработки первого, правда тут может появится желание сделать оптимистичное изменение стейта, но это уже на клиентской стороне задача, по-идее
можешь создать только фронт этому не будет особо рад так как все запросы с фронта будут возращать чтото типа status: 200 message: "action queued" и все результаты отработки бд тебе придется отдельно слать как то клиенту (например через сокет)
у меня проблема с тем, что в рамках этих actions я иду в бд проверять, а может ли конкретный action быть совершен для данного пользователя, и это зависит от актуальных данных. И ведь придёт несколько actions одновременно, будет нагрузка или ещё что, может случиться race condition. Например: пользователь инициировал 2 actions, один action начал выполняться раньше, и там запрос в бд с получением какого-то поля. И в этот момент, пока мы ждём ответ от бд в первом action, начинает выполняться второй action, который тоже идет в бд проверять то же поле, например. Теперь, скажем, что мы получили ответ в первом action, и там происходит ещё какая-та асинхронщина, и после этого тот же ответ мы получаем и во втором action. Следующие действия в обоих action будут происходить исходя из того, что полученное там значение поля равно N, но это будет неверно, поскольку один из action может это поле изменить, а другой action об этом уже не узнает поэтому я подумал просто сделать Queue, в который добавляются таски, и если для конкретного пользователя их ещё нет, то таска сразу запускается, а если есть — таска будет запущена как только предыдущая выполнилась и вот насколько такой подход — это норм? тут, правда, тогда всплывает ещё проблема, а что если поле этого пользователя может модифицироваться в action, которое инициировано другим пользователем (допустим, какой-то администратор вносит изменения)
То, что ты описываешь, может решить проблему. Но, кажется, ты исходишь из того, что процесс только один, то есть горизонтального масштабирования нет. Когда оно появится, нужно будет обеспечить очередь и Локи, разделяемые разными процессами. А можно сразу это сделать. Вариант решения - с помощью redlock и партицирования (например, kafka отлично подходит для задачи). Надо обеспечить выстраивание экшнов пользователя в очередь, разбор этой очереди одним процессом, и лок по айдишнику пользователя на время обработки
Проблему с горизонтальным масштабированием в этой ситуации думал решать через балансировщик, который на уровне nginx через nginx upstream на основании хэша, который сгенерирован, скажем, на основе user_id, отправляет обработку actions того или иного юзера на соответствующий сервер, где его очередь уже инициирована. Мне тут в целом-то не очень и страшно, если какие-то actions потеряются в случае падения одного из серверов, ведь пользователю придётся только лишь повторить действие, которое приводит к этому action. Хотя, наверное, этого бы всё-таки хотелось избежать, как я понимаю, тут Kafka действительно подходит хорошо. Так а как быть с тем, что другой пользователь, скажем, что администратор, выполняет какое-то действие над пользователем, которое модифицирует его данные в бд? Я просто тогда создаю какие-то дополнительные actions, которые будут выполнены как только основной action (скажем, списание баланса пользователю, инициированное администратором) выполнен? И тогда, например, в случае, если в рамках админского action модифицируются данные сразу нескольких юзеров, то я просто этот дополнительный action добавляю им всем в их Action Queue?
Да, дополнительные действия надо класть в очереди пользователей, к которым эти действия относятся
Обсуждают сегодня