AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 05.09.2013, 21:11   #1  
b_nosoff is offline
b_nosoff
Читатель
Аватар для b_nosoff
MCP
MCBMSS
 
197 / 143 (5) +++++
Регистрация: 01.12.2004
Адрес: Msk
Записей в блоге: 13
? Долгий запуск AX2012 R2
Мгновенный старт приложения новейшей версии любимой ERP поражает воображение у всех, кто когда-либо был этому свидетелем. В процессе выяснения причин, почему же так долго, наткнулся на такую вещь - при запуске клиента идут множественные вызовы метода Global\isRunningMode, и каждый вызов тянется несколько секунд. Стек вызова выглядит подобным образом
X++:
\Classes\SysModelStore\isInstallMode
\Classes\SysCheckList_SetupPartition\isSetupMode
\Classes\Application\isRunningMode
\Classes\Global\isRunningMode
Наконец, в методе isInstallMode вызывается функция axutil.RetrieveInstallModeState(), которая в свою очередь выполняет хранимку XU_GetDirtyFlag, которая в свою очередь нафиг зашифрована.
И есть у меня обоснованное подозрение, что именно ее вызов отнимает порой час-другой моего рабочего дня. Кто-нибудь что-нибудь знает об этой процедуре?
И еще вопрос - есть ли у кого предположения, почему isRunningMode не кэшируется?
__________________
Axapta non erubescit

Последний раз редактировалось b_nosoff; 05.09.2013 в 21:23. Причина: вопрос на засыпку
За это сообщение автора поблагодарили: Logger (3).
Старый 05.09.2013, 22:02   #2  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Я думаю, кэширование не приделали, чтобы не морочиться с работоспособностью SysCheckList_SetupPartition в момент, когда все шаги по контрольному списку выполнены, и установку можно считать завершенной (т.е. надо переключиться в RunningMode). Собственно, ничто не мешает сделать кэширование избирательным: если RunningMode - кэшировать, а если SetupMode - не кэшировать. Ведь маловероятно, что система вдруг в процессе работы клиента перейдёт обратно в SetupMode.
За это сообщение автора поблагодарили: b_nosoff (1).
Старый 05.09.2013, 22:39   #3  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,311 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
А вот я смотрю в метод isRunningMode() на Global и там у меня такой код:
X++:
client server static boolean isRunningMode()
{
    SysGlobalCache cache = classfactory.globalCache();
    boolean        mode;

    if (cache.isSet(classStr(Global), funcName()))
        return cache.get(classStr(Global), funcName());

    if (! appl)
    {
        return false;
    }

    mode = appl.isRunningMode();
    cache.set(classStr(Global), funcName(), mode);
    return mode;
}
Вопрос: Это кеширование не отрабатывает на запуске?
Версия ядра и приложения 6.2.1000.1437
__________________
Возможно сделать все. Вопрос времени
Старый 05.09.2013, 23:17   #4  
b_nosoff is offline
b_nosoff
Читатель
Аватар для b_nosoff
MCP
MCBMSS
 
197 / 143 (5) +++++
Регистрация: 01.12.2004
Адрес: Msk
Записей в блоге: 13
Lightbulb
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
А вот я смотрю в метод isRunningMode() на Global и там у меня такой код
Я немного поторопился, показав только первый вызов. На самом деле, в дальнейшем вызывается непосредственно appl.isRunningMode(), который не кэширован.

UPD: с селективным кэшем клиент запускается менее чем за 10 секунд, AOS менее чем за 3 минуты

X++:
boolean isRunningMode()
{
    // fix -->
    SysGlobalCache cache;
    ;    
   
    cache = this.globalCache();

    if (cache
        && cache.isSet(classStr(Application), funcName())
        && cache.get(classStr(Application), funcName()))
    {    
        return true;
    }
    // fix <--
    
   /* original code goes here */

    // fix -->
    if (cache)
    {
        cache.set(classStr(Application), funcName(), true); 
    }
    // fix <--
    
    return true;
}
__________________
Axapta non erubescit

Последний раз редактировалось b_nosoff; 06.09.2013 в 00:14. Причина: Замечание sukhanchik-а
За это сообщение автора поблагодарили: mazzy (2), trud (3), sukhanchik (5), Logger (3), SRF (5).
Старый 05.09.2013, 23:42   #5  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,311 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Спасибо за интересное наблюдение. Действительно - ускорение налицо (особенно разработческой части). Единственное - что я думаю - что можно использовать globalCache прямо из класса Application, а не обращаться к classFactory. В классе Global я думаю такое обращение сделано для того, чтобы кеширование было на клиенте (переменная classFactory - клиентская), хотя в конкретно этом случае вполне можно делать кеширование на уровне аоса, а не клиента конкретного пользователя
__________________
Возможно сделать все. Вопрос времени
За это сообщение автора поблагодарили: b_nosoff (3).
Старый 06.09.2013, 09:47   #6  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
В классе Global я думаю такое обращение сделано для того, чтобы кеширование было на клиенте (переменная classFactory - клиентская)
Справедливости ради надо отметить, что classFactory - не клиентская переменная. Сугубо клиентский кэш - это info.globalCache(), а объектов classFactory в каждой сессии существует два: клиентский и серверный, с одинаковыми названиями Использование classFactory.globalCache() позволяет использовать всегда "локальный" кэш независимо от того, где работает вызывающий код. Правда, разумеется, физически кэшей в таком случае получается два.
Старый 06.09.2013, 13:28   #7  
b_nosoff is offline
b_nosoff
Читатель
Аватар для b_nosoff
MCP
MCBMSS
 
197 / 143 (5) +++++
Регистрация: 01.12.2004
Адрес: Msk
Записей в блоге: 13
Наблюдения показали, что axutil.RetrieveInstallModeState() не всегда долго работает. От чего это зависит, пока понять не удалось.

В общем, окончательный вариант - реализовать кэширование непосредственно в SysModelStore.isInstallMode(), так как нашлось еще куча разных путей его вызова.

Ну и для надежности еще сделать этот кэш с таймаутом, т.е. сохранять в кэш время, на пять минут большее, чем сейчас, и потом сравнивать полученное из кэша значение с текущим временем, на случай, если вдруг в процессе работы была залита модель.
__________________
Axapta non erubescit
Теги
ax2012, isrunningmode, xu_getdirtyflag, долгий запуск клиента

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
goshoom: AX2012 R2 Demo V3.0 Blog bot DAX Blogs 0 31.07.2013 03:41
Я хочу поставить AX2012 R2 с Российским функционалом и с нуля. Ошибка при установке Sarvan DAX: Администрирование 21 28.06.2013 20:24
axtools: AX2012 R2 hotfix available to improve compile speed Blog bot DAX Blogs 1 01.05.2013 03:53
Axilicious:Running AX2012 R2 locally on Windows 2012 Server booted directly from VHD Blog bot DAX Blogs 0 16.04.2013 08:13
ukax: Dynamics AX2012 R2 Launches!!!! Blog bot DAX Blogs 0 04.12.2012 19:11

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 22:42.