Комментарии 50
А зачем вам вообще база? Что вы там храните и для каких сценариев?)
Просто на мой взгляд ваш главный сценарий — зашёл, выбрал, оплатил, закрыл.
вероятно, это сделано как холодный кэш, чтобы постоянно не дергать бэкенд запросами
Ну и чего там можно такого накешировать, чтобы база загружалась СЕКУНДЫ?
Также мы кешируем, чтобы не делать лишних запросов на сервер. Например, взять что-то из закешированного меню.
Какой смысл это кешировать, если время актуальности этих данных околонулевое?
Кажется, у вас неправильное представление об условиях работы мобильных приложений. Допустим, заходит человек в метро на пути домой и хочет заказать пиццу. Он открывает приложение, оно подгружает актуальные данные. Далее, пока пользователь едет между станциями, он может бродить по приложению, выбирать, что он хочет. Также может отвлечься на другое приложение. И если на этом этапе приложение выгрузится с памяти (как пример причины потери данных из in-memory кэша) и человек не сможет дальше делать выбор до следующего доступа к сети, он может просто плюнуть и зайти в супермаркет по дороге, вместо того, чтобы по второму кругу искать нужные продукты в приложении, когда оно снова соизволит загрузить данные. Вряд ли за эти полчаса меню изменится настолько, что пользователю уже не сделают пиццу, которую он выбрал из закэшированных.
И речь здесь не только о данном приложении, или о любом приложении для заказа еды, а в принципе о мобильных приложениях, которые немного думают о пользователях.
agent10 это тоже касается.
Есть и другие примеры. Badoo. Кол-во пользователей многократно больше. Можете поискать инфу, они её тут и писали на Хабре, что почти ничего не кэшируют вообще в приложении.
И вы и мы немного о разном. Мы не спрашиваем о сохранении состояния в целом(что в целом важно). Мы говорим о наличии целой базы данных для этого. В которую как мы видим сохраняется чуть ли не всё вообще)
Бизнес-требования и сценарии использования у Badoo и приложения для заказа пиццы разные, как по мне. Тот же Badoo — станцию метро проехал, и вот уже список людей рядом серьезно изменился. Хотя, честно говоря, такого рода приложениями пользоваться не приходилось, поэтому утверждать ничего не берусь. Но то же меню в Додо вряд ли обновляется каждые 10 минут.
Мы не спрашиваем о сохранении состояния в целом(что в целом важно).
Мы говорим о наличии целой базы данных для этого.
Вот не вижу проблем, судя по скриншотам структуры базы и фрагментам кода, ничего криминального не кэшируется. Особых альтернатив и нет. Не в файлы, право, писать же, если нужны минимальные query по кэшу.
Что-то типа redux-persist могло бы быть интересным вариантом для простых кейсов, но держать в памяти весь кэш тоже не всегда адекватно. В ощутимом количестве случаев база как single source of truth только упрощает жизнь. Другое дело, что Realm — это своеобразная штука, которую надо уметь готовить. И как видно, ребята из Додо изначально это не совсем умели.
Мне вот интересно, а как вы данные кэшируете в своих приложениях?
Не соглашусь) Потерять "потенциального" партнёра из-за того, что-то там не закэшировалось может быть значительно хуже сорвавшейся пиццы))
Опять же, статья изначально вышла из того, что приложение стартовало до 15-20 секунд из-за БД. Сколько клиентов/заказов они потеряли при этом за всё время существования проблемы? Судя по графикам из статьи — сопоставимо больше, чем происходят редкие случаи system-kill приложения во время заказа в фоне…
Мой посыл в том, что важнее закрыть критичные для бизнеса вещи, но простыми и безопасными средствами, чем неумело использовать танк сразу для всего:)
Потерять "потенциального" партнёра из-за того, что-то там не закэшировалось может быть значительно хуже сорвавшейся пиццы
Не знаю, к сожалению или к счастью, но подобные приложения вряд ли об этом очень переживают.
неумело использовать танк сразу для всего:)
Ну, тут как бы статья вся вышла о том, как люди не разобрались в матчасти изначально. Realm не умеет апдейтить вложенные объекты, если у них нет primary key, issue об этом уже много лет. Что, в принципе, звучит логично, потому что непонятно что делать с объектами без primary key и как понять, где ещё они используются. Не знаю, насколько просто это понять из документации, но мой посыл в том, что проблемы с Realm, возникшие в ключе использования базы как кэша, не дискредитируют использование (любой) базы в таком виде как таковое.
происходят редкие случаи system-kill приложения во время заказа в фоне…
Эту ситуацию я привёл как пример, могут быть и другие причины, зачем кэш
Как верно заметили ниже — "но зачем?") При этом в одном из предыдущих постов вы указали, что не делает поддержку планшетов "ибо нет необходимости", но зато делаете кучу работы с базой данных и сами решаете проблемы с ней?) Overengineering в Dodo?:)
@RealmClass
class DataPizzeriaEntity(
@PrimaryKey
var id: String? = null,
var name: String? = null,
var coordinates: CoordinatesEntity? = null,
var deliverySchedule: ScheduleEntity? = null,
var restaurantSchedule: ScheduleEntity? = null,
...
) : RealmObject(), NestedEntityAware {
Почему всё optional? Какая польза от объекта, у которого всё null?
Но мы решили не отказываться от идеи кеширования как таковой, а просто сделать, чтобы это всё работало правильно.
Но это не так важно в вопросе «нужно ли нам кешировать всё». Потому что даже быстро изменяющиеся данные мы тоже хотим брать из кеша при старте приложения.
даже быстро изменяющиеся данные мы тоже хотим брать из кеша при старте приложения
Я пытаюсь понять – чтобы что? Чтобы не было пустого экрана? Это проблема? По-моему это не проблема.
Но это немного другая тема, нежели о чем данная статья. На тему «а нужна ли кеш база данных в мобильном приложении», наверное, можно написать не одну, а ряд статей.
Я вижу, что проделана какая-то работа по реализации кеша, по интеграции и поддержке стороннего решения (Realm), по решению проблем с чужой библиотекой, – и всё это выглядит зря потраченными усилиями, потому что не имея никакого кеша можно было уничтожить целый класс проблем, и в то же время не потерять в UX, а возможно даже улучшить его.
Отсюда вопрос: что за проблема решалась внедрением кеша, ради чего были испытаны все эти страдания?
Издержки — это отсутствие удобного каскадного удаления. На которое, да, нам пришлось потратить усилия и время.
Зря они потрачены или нет? На мой взгляд, на этот вопрос нет объективного ответа. Мы не можем померить, как вел бы себя наш продукт на наших масштабах с или без базы. Какие бы были показатели, и на сколько сильно они бы повлияли на пользовательский опыт? У меня нет ответа на этот вопрос.
Почему бы просто не назначить cache-control на запрос меню, и не позволить системе самой разобраться с кешированием этого ответа? И вместо использования Realm, их модели данных, сабклассов их классов просто не парсить каждый раз этот ответ от сервера (закешированный системой) в свои маленькие объектики?
Таких кейсов пока очень мало, а меню пока только на языке своей страны. Переделаем когда это станет значимым.
Главная проблема была такой: приложение поддерживает n языков, потому что работает в n стран. Чтобы в приложении не было двух разных языков у интерфейса меню для каждой страны меню надо тоже заводить для n языков? Или только на родном и английском? Тогда в приложении тоже может быть только родной и английский? Кароч вопросы и сложность, а ценности этому пока нет.
Чисто на платформе язык умеет менять динамически, остальное лишь вопрос времени и запроса от пользователей.
Большие расходы на поддержку меню всех стран на всех языках.
Зачем Додо Пицце 250 разработчиков?
О каких расходах на поддержку меню на 5 языках (русский, английский, эстонский, литовский, румынский) идёт речь?
Можно было бы сделать такой приоритет: Язык системы – язык региона – base (английский).
На этот счет, я буду рад поделиться очень интересной мыслью от Эрика Бернардсона (бывший СТО Спотифая), именно вот этой мыслью. Грубо говоря она говорит о том, что какую-либо недоработку или нереализованную фичу стоит в первую очередь рассматривать с точки зрения оценки упущенной выгоды. Если говорить проще, то если какой-то функционал еще где-то не сделали, то это не значит что это не важно. Наиболее вероятно это значит, что до этого делали более приоритетный функционал. Как-то так.
Мы потратили на это не так много, может часов 40-60 на обе платформы. Это ничто в сравнении с расходами, когда для добавления каждого нового продукта надо дернуть партнеров из разных стран, поддерживать многоязыковое меню и писать фолбеки не те случаи когда меню еще не переведено.
Ну и технически сделано довольно ок, подменяем бандл в рантайме.
Room, на момент проектирования приложения, был еще довольно новым инструментом.
Если бы мы проектировали приложение сейчас, то, возможно, выбрали бы другой инструмент.
1) Конкретно мне кажется оч странным то, что в каком потоке создали объект, в том с ним и работайте)))
2) Ужасный Realm studio, который многим уступает клиентам для sql. Элементарно не сделать выборку из базы c разными условиями, как это можно с sql.
3) Еще и тянуть за собой несколько мегабайт нативных .sошек
>Room, на момент проектирования приложения, был еще довольно новым инструментом. — Ну, понятное дело, но кроме него много альтернатив)))
Конечно, я не пытаюсь разубедить что это плохой инструмент. Если вам подошло, то я только рад за Вас)
Ладно бы это все было ради какого-то развесистого офлайн-режима как в Фейсбук-мессенджере, но тут все явно можно на уровне json-ов закешировать. Какие преимущества базы в вашем случае?
Второй вопрос, почему рост кеша настолько замедляет старт приложения. Вы его в память весь при старте загружаете до показа интерфейса? Тогда ещё раз встаёт вопрос о необходимости базы.
Если нет, может каких-то индексов не хватает. 160 тысяч строк в таблице базы не звучит как что-то огромное, откуда 25 секунд нужно искать сущности для показа стартового интерфейса.
Мы в память загружаем при старте не так много. Меню и еще кое каки вещи. И это довольно компактный объем данных. Но когда база распухшая на много сотен тысяч строк, то запросы в нее идут медленнее. Особенно когда надо запрашивать всё меню, а не по индексам что-то.
У нас речь о вложенных объектах без
Primary Key
. У нас много вложенных объектов и для них сервер не присылает id. Для них Primary Key
, который уникальный и не особо имеет смысл.Если посмотрите, как пример в статье, объект с расписанием
ScheduleEntity
. У него нет Primary Key
. У него вложенные объекты, у которых тоже нет Primary Key
.Почему-то вспоминаются современные подкасты:
— Realm не удаляет каскадно зависимости автоматом;
— О, есть о чем поговорить 1.5 часа
<joke-off-cut/>
Тем не менее, статья хорошая. Олеся — спасибо!
Сказ о том, как каскадное удаление в Realm долгий запуск победило