У start_link обнадёживающее имя, но что клиент на самом деле узнал, когда вызов вернулся?
Здесь init возвращает {:ok, state, {:continue, :warm_cache}}. Вызов запуска ждёт только возврата из init. Прогрев идёт потом, в handle_continue. Значит, подтверждение говорит, что процесс существует, а не что кэш прогрет. Запросы клиентов внутри этого GenServer не выполняются параллельно с продолжением. Они просто встают за ним в очередь.
Теперь примерим к этому слово ready. Клиент видит признак успешного запуска и сразу просит значение из кэша. Если признак означает только возврат из init, ready обещает слишком много.
Честных вариантов два. Задержать готовность до конца прогрева. Или показать Warming и ограничить число запросов, которым разрешено ждать, и тогда придётся решить, что тайм-аут убирает из ожидающей работы.
С перезапуском под супервизором та же история. Перезапуск процесса и восстановление пригодного кэша остаются двумя разными обещаниями. Пусть ready называет то, за чем пришёл клиент. Для остального вполне годится started.