AWS, история четвертая. Когда null не совсем null
Все статьи из цикла AWS
- Амазон
- AWS, история первая. Внезапный мегабайт
- AWS, история вторая. Афина прекрасная
- AWS, история третья. Разрывы
- AWS, история четвертая. Когда null не совсем null
Еще одна история о том, как Амазон может попить крови.
Напомню особенности нашей архитектуры. Сервисы записывают в S3 сущности разных типов. Их может быть много, например, полтора миллиона такого-то типа. Чтобы выгрести сущности разом, мы используем чудо-оружие Амазона — сервис Athena. Он собирает файлы из бакета и склеивает в один CSV.
Среди сущностей встречаются выбракованные, и при обходе CSV их нужно
игнорировать. Один из признаков брака — вложенное поле attrs
, которое равно
null
. Не проблема: получаю ленивую коллекцию сущностей и накладываю на нее
фильтр:
(->> csv
(get-lazy-seq ...)
(filter
(fn [entity]
(-> entity :attrs nil?))))
На проде, по различным логам и эксепшенам, вижу, что битые сущности просочились в обработку. Как так?
А вот как: в оригинальном JSON поле attrs было null
, все верно. Но при
агрегации в CSV Амазон экранирует null
кавычками и получается \"null\"
. При
этом его не волнует, что null
находится в середине JSON-строки, которая уже
экранирована. Какой-то парсер доходит до null
и пишет его с кавычками.
В результате при чтении JSON получается {"attrs": "null"}
, то есть строка с
буквами n, u, l, l. Чтобы выкинуть эту запись, я переписал фильтр так:
(or (-> aggregate :attrs nil?)
(-> aggregate :attrs (= "null")))
Спрашивается, зачем я оставил первый вариант с чистым nil?
Потому что, если
однажды мы перейдем на другое хранилище, поле опять станет null вместо "null"
,
и фикс придется откатывать. А так оба случая покрыты: и нормальный, и кривой.
Разумеется, прикол с null
нигде не описан, в Гугле ничего нет. Счастливой
отладки, уважаемые коллеги!
Вот так я потерял еще один день. Каждый раз, распутав новый квест от Амазона, откидываюсь в кресле и тихо матерюсь. А затем иду дальше.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter