Size: a a a

GraphQL — русскоговорящее сообщество

2021 August 13

a

alexalexalex in GraphQL — русскоговорящее сообщество
и единственный способ который я вижу - поменять в бд все как нужно, получить нормализированный респонз, а потом сразу как-то откатить бд через papertrail (version tables для rails)
источник

t

toriningen in GraphQL — русскоговорящее сообщество
а что происходит с черновиком, если человек бросает его редактировать, не отменяя явно и не сохраняя?
источник

t

toriningen in GraphQL — русскоговорящее сообщество
т.е. просто закрывает страницу, например
источник

t

toriningen in GraphQL — русскоговорящее сообщество
(я имею в виду не в нынешней реализации, а в планируемой)
источник

a

alexalexalex in GraphQL — русскоговорящее сообщество
Данные не сохраняются
Т.е. он превьюит свои изменения (результат которых - ТОЛЬКО результат запроса на бекенд, как если бы он сохранял их), и если он закрывает страницу то ничего не происходит по возврату
источник

t

toriningen in GraphQL — русскоговорящее сообщество
т.е. после возврата загружается не черновик, а исходная версия?
источник

a

alexalexalex in GraphQL — русскоговорящее сообщество
да
источник

t

toriningen in GraphQL — русскоговорящее сообщество
менять бд, а потом откатывать - идея, которая на корню убивает конкурентные обновления и транзакционность

потому что пока данные обновлены, но еще не откачены, конкуретное обновление может их использовать. нарушается изоляция, это плохо

если же вы будете создавать долгоживущие транзакции, вы столкнетесь с блокировками обновленных строк, которые будут удерживать другие транзакции, меняющие эти же строки... тоже плохо
источник

t

toriningen in GraphQL — русскоговорящее сообщество
есть возможность ремоделлинга бд, чтобы добавить к строкам "метку черновика", некий уникальный ID, на который будут опираться запросы в рамках live preview?

тогда, например, вы могли бы не изменять строку, а склонировать ее, добавив в нее метку черновика

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

а вот гранулярность этой копии и способ ее достижения - это открытый вопрос
источник

a

alexalexalex in GraphQL — русскоговорящее сообщество
суть в том, что юзер-то и обновляет черновик. Т.е. у нас есть веб-конструктор, и есть панель управления для него. Изначально юзер меняет черновик сайта, если все ок - он его паблишит. Мне кажется это overkill создавать черновик для черновика
источник

a

alexalexalex in GraphQL — русскоговорящее сообщество
то - что меняется это и есть черновик. а лайв апдейты требуются для черновика
источник

t

toriningen in GraphQL — русскоговорящее сообщество
нет, я не говорил про черновик для черновика. возможно, произошел конфликт терминлогий

под черновиком я имел в вид неподтвержденные изменения, которые вносит пользователь, но которые еще не видны снаружи - как если бы это была долгоживущая транзакция

фактически, именно транзакции на уровне приложения вы и реализуете - вам нужна возможность вносить изменения в свои данные так, чтобы эти изменения не были видны снаружи

и иметь возможность отменить эти изменения массово и консистентно, если пользователь передумает
источник

a

alexalexalex in GraphQL — русскоговорящее сообщество
но в бд слишком много сущностей которые либо меняют друг друга, либо вложены друг в друга. И создавать черновик пришлось бы для многих таблиц
источник

t

toriningen in GraphQL — русскоговорящее сообщество
если предположить, что у каждой строки есть NULLABLE колонка draftId,
и если предположить, что у черновика есть точка во времени, когда он создается
то можно смоделировать запросы так, чтобы при выборе связанных таблиц они отдавали предпочтение строке, где other.draftId == this.draftId

и каждый раз, когда мы хотим изменить строку - если мы пытаемся изменить строку без draftId, то мы создаем копию существующей строки с draftId = NULL, назначаем копии draftId из текущего черновика, в дальнейшем мутируем эту копированную строку

получаем консистентный вид всех связанных таблиц и отсутствие оверхеда на копирование таблиц

и связанных проблем с транзакциями

коммит черновика происходит путем того, что изначальная строка без draftId удаляется, а в строке с draftId сам draftId очищается

отмена черновика происходит просто удалением всех строк с draftId, равным текущему черновику
источник

a

alexalexalex in GraphQL — русскоговорящее сообщество
это слишком большой ремоделлинг дб)
источник

t

toriningen in GraphQL — русскоговорящее сообщество
отмена черновика по таймауту происходит путем сборки мусора по крону раз в какое-то время. когда у клиента нет идентификатора черновика, которыми он может сопроводить свои запросы, для него строки с нужным идентификатором становятся недосягаемы
источник

a

alexalexalex in GraphQL — русскоговорящее сообщество
у менять есть грубо говоря
{title: string, subtitle: string, menus: *можеть иметь в себе что-то еще что и появлятся в результате основного запроса.*} И если обычные не graphql типы я могу менять просто на фронтенде, то все что посложнее требует запроса
источник

t

toriningen in GraphQL — русскоговорящее сообщество
жаль

но в любом случае, если вы не можете все вычисления выполнить только на клиенте, вам нужно придумать способ обеспечения транзакционности без блокировок. это один из таких способов

ваша бд поддерживает copy-on-write таблиц?

если да, вы можете создать легковесные копии всех таблиц, которые могут участвовать в черновике, и выделить их во временный неймспейс. копии практически не занимают места, пока их не начинают менять. добавить всем таблица колонку с флагом dirty, равным false по-умолчанию

отмена черновика - удаление неймспейса
коммит черновика - поиск всех строк с dirty = true, перезапись строк в изначальном неймспейсе, удаление неймспейса
источник

a

alexalexalex in GraphQL — русскоговорящее сообщество
не совсем знаком с термином
источник

t

toriningen in GraphQL — русскоговорящее сообщество
можно копировать таблицы очень топорно, типа CREATE TABLE foo_copy AS (SELECT * FROM foo) - это создаст полную копию таблицы, но займет много места и ресурсов на копирование

некоторые бд позволяют делать легковесные клоны - они выглядят, как копии таблиц, но хранят в себе только разницу между копией и оригиналом
источник