I made a bug once, and I need to tell you about it. So, in 2001, I wrote a reference library for JSON, in Java, and in it, I had this line
private int index
that created a variable called "index" which counted the number of characters in the JSON text that we were parsing, and it was used to produce an error message. Last year, I got a bug report from somebody. It turns out that they had a JSON text which was several gigabytes in size, and they had a syntax error past two gigabytes, and my JSON library did not properly report where the error was — it was off by two gigabytes, which, that's kind of a big error, isn't it? And the reason was, I used an int.
Now, I can justify my choice in doing that. At the time that I did it, two gigabytes was a really big disk drive, and my use of JSON still is very small messages. My JSON messages are rarely bigger than a couple of K. And — a couple gigs, yeah that's about a thousand times bigger than I need, I should be all right. No, turns out it wasn't enough.
You might think well, one bug in 12 years you're doing pretty good. And I'm saying no, that's not good enough. I want my programs to be perfect. I don't want anything to go wrong. And in this case it went wrong simply because *Java gave me a choice that I didn't need, and I made the wrong choice*.
tfw кто-то для позиции использовал не long и валит на java. специально для таких нужно оставить один тип BigDecimal и пусть ебутся с ним как хотят
@krkm и? java не должна была ему позволять выбирать тип для какой-то там переменной?
@krkm k
@mugiseyebrows у меня один демон как-то раз в проде сгенерил из письма (rfc822) размером 15 МБ json размером 1.3 ГБ.
@hirthwork и это — expected behaviour. просто в тот раз успел сработать вотчдог и прибит бэкэнд. с тех пор я стал умнее и теперь такие json'ы обрабатываются быстрее и аккуратнее, поэтому при прилёте таких данных вотчдог ничего не заподозрит
@hirthwork мой секрет успеха в том что я нигде не отсчитываю позицию в json. мне влом репортить подробные ошибки, когда кто-то присылает говно вместо json'а — проблемы негров шерифа не ебут
@mugiseyebrows считать текущую позицию при парсинге не обязательно
@mugiseyebrows нет, не нужно. что я с ней сделаю? пофикшу что ли?
@hirthwork отправитель сам может взять свой json и загнать в jq. или python -m json.tool. а вообще у меня там выводится вроде кусок текста, на котором парсинг обломился. и позиция известна внутри куска текста (который не можеть быть больше 2ГБ)
@mugiseyebrows > таким образом который не приходил в голову создателями парсеров
на бэкэнде стоит json парсер который я сам написал за две ночи. все остальные парсеры просто охуевают от наших объёмов данных. а те что не охуевают — тормозят. поэтому приходится писать свои парсеры
нам не надо модифаить. один сервер по мере парсинга rfc822 генерит охуительного размера json и поточно высирает его в сокет, над сервером стоит nginx, который жмёт его в gzip, этот gzip улетает на другой сервер, тот его распаковывает, извлекает пару нужных полей для себя и посылает в бэкэнд. бэкэнд вычитывает этот json, парсит и при помощи хитровыебанных алгоритмов превращает в свои структуры данных, которые флашит на HDD. Но надо признаться, что бэкэнд тоже целиком в памяти вынужден держать этот json в памяти в течении нескольких миллисекунд — это обоснованный tradeoff
@mugiseyebrows годы назад мы использовали protobuf, но потом поняли что при работе с бинарными данными крайне неудобно дебажить. к тому же нужно всем клиентам оперативно обновлять *.proto-файл, что тоже является геморроем. json удобнее и в плане дебага и в плане работы с другими командами