Блокировать или расширять автоматическую загрузку метаданных Breeze

Текущее приложение - Angular приложение с Breeze. Приложение имеет ~ 7 менеджеров сущностей и разные домены данных (метаданные). Когда приложение запускается, мы пытаемся получить менеджеры сущностей, например:

app.run(['$rootScope', 'datacontext1', ... ], function($rootScope, datacontext1, ...) {
   datacontext1.loadMetadata();
...
   datacontext7.loadMetadata();
}

У каждого контекста данных есть собственный менеджер сущностей, а loadMetadata:

function loadMetadata() {
  manager.fetchMetadata().then(function(mdata) {
       if (mdata === 'already fetched') {
          return;
       }
       ...
       applyCustomMetadata(); // Do some custom job with metadata/entity types
  });
}

Метаданные поступают с сервера асинхронно. Немногие модули имеют действительно большие метаданные, например 200 КБ, и им требуется некоторое время для загрузки и применения к диспетчеру сущностей. Вполне возможно, что первый запрос данных Breeze, выполненный в том же диспетчере сущностей, будет запущен до завершения этой операции loadMetadata, и, как я понимаю, Breeze снова автоматически получит метаданные. Обычно это не проблема, конечная точка метаданных кэшируется на сервере, но иногда это приводит к очень странному поведению Breeze - EntityManager.fetchMetadata resolve обещание как «уже получено», и в этом случае операция applyCustomMetadata () не может быть выполнена.

Насколько я понимаю, проблема находится внутри Breeze, и подход к нему используется для разрешения обещания метаданных (похоже, что http-адаптер является одноэлементным, и второй запрос переопределяет метаданные с «уже полученной» строкой, а операция applyCustomMetadata () никогда не выполняется).

Необходимо найти способ решить проблему без существенных изменений в приложении.

Логически необходимо отложить полное приложение от использования менеджеров сущностей во время выполнения loadMetadata. Ищете способ на уровне Breeze отключить автоматическую выборку метаданных, если он уже выполняется (но не прерывание запроса, просто подождите и повторите попытку через некоторое время). Любые другие идеи тоже подойдут.


person Grigorii    schedule 22.01.2016    source источник


Ответы (1)


Почему вы разрешаете выполнение запросов до загрузки метаданных? В этом твоя проблема.

У меня есть загрузчик приложения, который я открываю через глобальную переменную; ни одна из моих прикладных операций, зависящих от Entity Manager, не запускается до завершения предварительных процессов:

var bootstrapper = {
    pageReady: ko.observable(false)
};

initBootstrapper();
return bootstrapper;

function initBootstrapper() {
    window.MyApp.entityManagerProvider.initialize() // load metadata, lookups, etc
        .then(function () {
            window.MyApp.router.initialize(); // setup page routes, home ViewModel, etc
            bootstrapper.pageReady(true); // show homepage
        });
};

Кроме того, в зависимости от частоты изменений базы данных, происходящих в вашей организации, вы можете захотеть доставлять метаданные клиенту синхронно на странице page_load. См. Эту документацию для получения дополнительных сведений:

http://breeze.github.io/doc-js/metadata-load-from-script.html

person Jonathan    schedule 22.01.2016
comment
Да, оба эти способа являются вариантами решения проблемы, но, к сожалению, оба они повлияют на взаимодействие с пользователем. Первый способ - блокировка запуска приложения (выполнение первого маршрута) добавит 1-2 секунды анимации ожидания пользователя (есть 7 менеджеров сущностей с большими метаданными). Во-вторых, синхронная загрузка метаданных может привести к тому, что приложение не будет отвечать на запросы в течение длительного времени (несколько секунд). Самая большая проблема - приложение, уже используемое многими пользователями, и решение не должны снижать UX, но в то же время приложение не было разработано с высокой масштабируемостью (домены данных действительно слишком велики). - person Grigorii; 24.01.2016