tarantool.cr
tarantool.cr copied to clipboard
Queued writes
To avoid bytes mixing from different fibers
Yura Sokolov, [20.05.18 00:04] В кристале socket.write препятсвует другим файберам записывать в этот же сокет? Там ведь ивент луп, и запрос может за один системный врайт не влезть.
Vlad Faust, [20.05.18 00:04] А вот я не знаю
Vlad Faust, [20.05.18 00:04] Там слишком дебри
Yura Sokolov, [20.05.18 00:05] Перепроверь. Будет обидно, если под нагрузкой каша в тарантул полезет.
Vlad Faust, [20.05.18 00:05] Спасибо!
Yura Sokolov, [20.05.18 01:13] Да, похоже что из нескольких файберов нельзя писать в один сокет, не защищая его.
Vlad Faust, [20.05.18 11:35] А можно код, который это воспроизводит?
Yura Sokolov, [20.05.18 11:44] Код я не писал, только сырцы смотрел. Но ты прав, его нужно написать. Не могу обещать, что сегодня, т.к. дел по горло. Если хочешь сам попробовать, пиши из трех файберов в цикле круглое число разных байт: из одного 7000 "a", из другого "b", из третьего "c". А на другом конце сокета проверяй, что пачки по 7000 приходят не перемешанные.
Yura Sokolov, [20.05.18 11:44] Круглое число - чтобы по границу буфера не выровнялось.
Vlad Faust, [20.05.18 11:48] Ты ведь не про порядок экзекуции, мол, параллельные инсерты могут заинсертить не в том порядке, в котором вызваны?
Yura Sokolov, [20.05.18 11:49] Нет, я про перемешивание байт от разных запросов. Это может случиться только если буфера забиты под завязку, так что заметить очень сложно.
Vlad Faust, [20.05.18 11:49] Понял
Vlad Faust, [20.05.18 11:50] С такого тарантул ложится?
Vlad Faust, [20.05.18 11:51] Вчера при написании инсерт бенчей он периодически ложился 🧐 Выдавая невалидные респонсы перед смертью
Yura Sokolov, [20.05.18 11:52] Да, тарантул вполне может от этого лечь. Когда-то он сразу в корку падал.
Vlad Faust, [20.05.18 11:54] Значит, пихать реквесты в очередь?
Yura Sokolov, [20.05.18 11:55] Или брать мьютекс вокруг записи в сокет. (Не знаю, как он в кристале выглядит, если честно). Протестируй оба варианта, сложно сказать, какой из них быстрее.
Yura Sokolov, [20.05.18 11:57] В гошке я хитро пихаю в хитрую очередь, но там многоядерность, и мьютексбудет хуже. В однотредовом кристале, влзможно мьютекс окажется предпочтительнее. Правда, есть еще вопрос с таймауьом реквеста. Если на мьютексе нет таймаута, то он отпадает.
Yura Sokolov, [20.05.18 11:58] Хотя, всегда можно канал использовать как мьютекс.
Vlad Faust, [20.05.18 12:09] Я, честно, не силен во всех этих мьютексах. Вот его исходники, глянь, пожалуйста, сработает ли: https://github.com/crystal-lang/crystal/blob/4f9ed8d03208dd0db33993c5a6fa6753bc1cf91e/src/mutex.cr
Там вообще мало кода
Yura Sokolov, [20.05.18 12:11] Нормальный мьютекс. Но таймаута нет.
Vlad Faust, [20.05.18 12:12] Можно дописать, я так понимаю
Yura Sokolov, [20.05.18 12:13] btw, а как ты хендлишь время, затраченное на запись? write вполне может секунды продолжаться.
Yura Sokolov, [20.05.18 12:14] Т.е. где-то нужно выставлять таймаут на запись, если пишешь в том же файбере
Yura Sokolov, [20.05.18 12:15] А еще флашить сокет периодически, т.к. он в кристале буферизированный. Иначе, если только один файбер послал только один запрос, то ответа можешь не дождаться.
Yura Sokolov, [20.05.18 12:21] В общем, наверное пишущий файбер с реквестами через канал может оказаться проще в написании.
Vlad Faust, [20.05.18 12:21] [In reply to Yura Sokolov] Да, сокету нужно добавить #read_timeout = и #write_timeout =, as seen in https://github.com/crystal-lang/crystal/blob/4f9ed8d03208dd0db33993c5a6fa6753bc1cf91e/src/io/syscall.cr
Vlad Faust, [20.05.18 12:23] [In reply to Yura Sokolov] Flush очищает очереди на инпут/оутпут. Не значит ли это, что неотправленные данные стираются и реквест не удастся?
Yura Sokolov, [20.05.18 12:24] flush делает системный write для еще не записанной части буфера.
Vlad Faust, [20.05.18 12:25] Хорошо, спасибо за новые знания 😊