Оберните Postgres в специальное приложение Phoenix - PullRequest
0 голосов
/ 27 мая 2018

Цель : иметь приложение Phoenix (# 1) с пустыми (без таблиц) Postgres и при первой загрузке ожидает дальнейшей настройки.Как только он получает файлы миграции и модели / схемы через http от другого приложения phoenix (# 2), он запускает миграции, запускает supervisor(App1.Repo, []), и все полученные модели / схемы из приложения # 2 переводят в состояние в worker(App1.Models, []), так что приложение# 1 может обрабатывать запросы типа Repo.all(User).Затем приложение № 1 прослушивает запросы от приложения № 2 и выполняет изменения в Postgres.

Причина : Идея состоит в том, чтобы полностью изолировать БД от приложения №2, чтобы при необходимости чего-то из базы данных просто отправлять Ecto запросов приложению № 1 и приложению № 1может выполнить этот запрос и вернуть результат.Однако копия приложения № 1 может создаваться для разных приложений, то есть приложений № 2, № 3, № 4, которые имеют разные модели / схемы и при первом подключении предоставляют свои настройки БД (модели / миграции) приложению № 1,который подготавливает свой Postgres с этими настройками, а затем просто принимает запросы БД.


Пример:

Шаг 1 : Приложение № 1 получает модель User и соответствующий файл миграции из приложения № 2.

Шаг 2 : Приложение № 1 запускает файл миграции для подготовки Postgres.

Шаг 3 : Приложение № 1 запускает GenServer (процесс?)с Ecto, Repo и недавно полученной User моделью из приложения № 2 и прослушивает входящие запросы.

Шаг 4 : Приложение № 1 получает запрос, выполняет запрос и возвращает список всехпользователи в своей дб.

%{
  query: 'User',
  command: 'all'
 } 
 # Should run by app #1 as Repo.all(User)

Проблемы:

  1. Прежде всего, возможно ли вообще сделать что-то подобное?Или в этой идее есть фундаментальная проблема?
  2. Как приложение № 1 может запускать полученные миграции динамически, без запуска / остановки своего сервера?Можем ли мы поместить файлы миграции (полученные из приложения № 2) в какой-то каталог, а затем запустить что-то вроде Mix.Tasks.Ecto.Migrate.run(), чтобы запустить все миграции?
  3. Решено Может ли приложение № 1 скомпилировать модели / схемы (полученные из приложения № 2), запустить GenServer с этими моделями и сделать их доступными для запуска команд, таких как Repo.all(User)?Или мы можем использовать полученные модели / схемы для динамического создания модулей и передачи этих модулей в App1.Repo, чтобы выполнять запросы, подобные Repo.all(User), где User - динамически генерируемый модуль? Решение: Используя логику из здесь , я смог динамически создавать модули, а затем использовать их для выполнения запросов.

Я мог бы запутать некоторые вещи, но я верю, что решение этих проблем поможет достичь цели ...?Любая помощь приветствуется!

1 Ответ

0 голосов
/ 27 мая 2018
  1. Хотя я вряд ли мог представить себе преимущество этой архитектуры, это, безусловно, возможно.

  2. Конечно, почему бы и нет?

Использование Ecto.Migrator:

def migrate! do
  path = Application.app_dir(:my_app, "priv/repo/migrations")
  Ecto.Migrator.run(MaApp.Repo, path, :up, all: true)
end
Я бы воспользовался преимуществом использования ErlangVM, запуска удаленных функций на разных узлах с Node.spawn/* вместо того, чтобы заново изобретать колесо.

Таким образом, можно было быиспользуйте код из App2 из App1 для работы с моделями / схемами.Возможно, я неправильно понял цель здесь, но, поскольку она уже помечена как решенная, я бы оставил свой комментарий в качестве дополнительного предложения.

...