ermouth: (Default)
ermouth ([personal profile] ermouth) wrote2016-03-04 01:42 am
Entry tags:

Replication race

У нас недавно в процессе тестовых прогонов одного проекта нашёлся удивительного свойства баг, такой очень хитрый race. Race этот прожил в глубинах CloudWall-а два года никак не проявляясь ни в тестах, ни в реальной жизни.

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

История такая.

Мы гоняли репликацию тестового working set-а с бэкэнда на клиент, проверяя как это работает при разных условиях сети и как нагружается бэкэнд фильтрацией потока репликации.

И я внезапно заметил, что на медленной сети как-то непропорционально долго всё. А приглядевшись, увидел что и данных передаётся кратно больше чем нужно – причём чем медленнее сеть, тем больше кратность. И на совсем-совсем медленной сети процесс вообще никогда не заканчивается.

Никаких 4хх, 5хх или обрывов по пути нет, то есть оно не рестартует на ошибку, оно просто много раз качает одно и то же.

Дело оказалось вот в чём.

CloudWall устроен так, что не даёт никакой репликации длиться дольше определённого промежутка времени, если она вышла за таймслот, она завершается на той точке, до куда дошла, и через некоторое время рестартует.

Это сделано для того, чтобы ни один процесс репликации не мог надолго монопольно захватить каналы передачи. Типичный браузер не поддерживает больше 10 одновременно открытых XHR-соединений на вкладку, остальные стоЯт и ждут освобождения слота.

Так как CloudWall партиционирует локальную базу и может поддерживать связь сразу с несколькими удалёнными БД, такой подход оправдан. Беда только, что он даёт race на медленных каналах – потому что PouchDB старой версии, что используется, иногда не закрывает соединение при отмене репликации.

То-есть оно продолжает качать себе дальше, если там что-то длинное.

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

Пока не наступает одно из пограничных условий (а они довольно искуственные), рэйс так или иначе рассасывается – потому и не заметно было. Тесты то проходят.

Интересно, что починилось в ~10 строк кода, но доставило невообразимо, да.

[identity profile] morfizm.livejournal.com 2016-03-03 11:33 pm (UTC)(link)
Неплохой вопрос для интервью, чтобы поговорить о тестировании, мониторинге и логгинге.