Моно это жесть. Она падает в какие-то непонятные моменты, не умеет в кучу того, что умеет дотнет (например, в вебсокеты, а это как бы необходимая штука для чата и уведомлений в реальном времени), грузится от любого чиха и непостижима в принципе.
Решением этой проблемы стал уже к тому моменту стабилизировавшийся NETCore. Это новая версия рантайма дотнета, которая умеет запускаться на юникс-системах. Сначала мы пессимистичничали и думали, что перевести ДМ3 на неткор будет очень долго и муторно, но в итоге оказалось, что глаза боятся, а руки делают - и чуть ли не за выходные мы перенесли все на новые рельсы, что оно стало компилиться и запускаться. И в рамках этой версии теперь и ведется разработка. В частности, оптимизация счетчика непрочитанных.
Счетчик непрочитанных писали мы оба в разные моменты жизни, и вот как он развивался:
0. На дм2 - хранимки, вуху.
1. Хранили в монге абстрагированные данные типа на горячее чтение с инфой по каждому юзеру о том, когда он читал какую штуку. Вычитывали из монги, затем строили запросы, чтобы посчитать, сколько с момента последнего чтения появилось новых сообщений. Ну очень тяжелая фигня, это понятно. Как минимум, что нам необходимо делать два запроса - из монги и из постгри, и второй запрос еще и с агрегациями, уфф.
2. Накинули на это все зверский кеш, который не инвалидировался, а обновлялся. Сначала зашуршало просто поразительно быстрее, на нагрузках беты-то. Но когда вывалили в релиз, увидели, что это черте что. Во-первых, кеш сжирал память и ронял аппул. Во-вторых, кеш был в памяти приложения и не синхнонизировался с API. В-третьих, даже когда мы кеш вынесли из памяти приложения в инстанс монги (который тоже в памяти), он все равно вычитывался в рантайме в память приложения и все сжирал и ронял аппул.
3. Теперь, в спокойной обстановке дичайших дедлайнов на работе и семейных трудностей, мы наконец-то придумали новую реализацию, которая вроде как должна быть побыстрее? Ну, мы проверим на каком-нибудь jmeter'е, все как обещали. Ее идея состоит в совмещении двух подходов: мы храним все опять в монге, но теперь помимо дат, на основе которых потом надо как-то считать посты, мы храним и сами счетчики. Когда кто-то пишет новый комментарий, у всех счетчики по данной сущности инкрементятся. Когда кто-то удаляет комментарий, счетчики декрементятся у тех, кто его еще не читал, а у остальных остаются как были. Благодаря еще одному полю "ParentId" сильно-сильно оптимизированы запросы по счетчикам форума и личных сообщений (которые на ДМ3 представляют не количество сообщений, а количество тем/диалогов с непрочитанными сообщениями).
Ну и наконец, тяжёленькие запросы на главной. Уфф, это позорище, конечно. Но - нашли уж когда нашли, теперь будем править. Если коротко перецитировать последнего "Безумного Макса": "Не надо привыкать к ОРМ, она поработит вас и вы будете по ней тосковать". В частности, сейчас мы выяснили, что у EFCore (старой версией которой мы пользовались на ДМ3) очень большие проблемы с запросами чуть сложнее чем select * from table, и мы с ними боремся в свободное время. Вроде временное решение нашли, хотя оно и мерзкое, а дальше поглядим.