Share via


Доступность appl.globalCache() для всех сессий DAX

С любезного разрешения моего коллеги Григория Верного, публикую этот текст и файл экспорта.

Q : Есть ли возможность доступа к appl.globalCache() для каждой сессии DAX или каждая сессия имеет свой globalcache()?

A : Каждая сессия создает два экземпляра globalChache(): Infolog.globalCache() и Appl.globalCache().

Эти экземпляры независимы и не имеют доступа к данным друг друга. Это означает, что при добавлении объекта в infolog.globalCache(), к нему нет доступа из appl.globalCache().

Tip: Также важно, что

запросы RPC к globalCache с клиента на сервер, или наоборот, порождают безумное количество запросов по перадаче данных (мне очень нравится английский термин – chattiness).

Следующий код дает возможность обращаться только к "своему" кэшу и избежать увеличения трафика обмена между клиентом и сервером.

SysGlobalCache cache;

if(Global::IsRunningOnServer())

{

     cache = appl.globalCache();

}

else

{

     cache = infolog.globalCache();

}

Почему же не использовать classFactory() для замены такой конструкции?

Следующий пример делает практически тоже самое: 2 независимых кэша, созданных с помощью classFactory на клиенте и сервере. Прилагаемый файл содержит экспорт данного кода. Пример показывает, что classFactory не использует кэши infolog и appl повторно.

   

class GlobalCacheTest

{

public void printCaches()

{

    print "Appl ", appl.globalCache().isSet("Appl", null); // expected true – no surprise here

    print "Infolog ", infolog.globalCache().isSet("Infolog", null); // expected true – no surprise here

    print "CF_Server ", classfactory.globalCache().isSet("ClassFactory_Server", null);

    print "CF_Client ", classfactory.globalCache().isSet("ClassFactory_Client", null);

    print "";

    print "CF_Server_Appl ", classfactory.globalCache().isSet("Appl", null); // this is to verify if classFactory re-uses appl's cache or not

    print "CF_Client_Infolog ", classfactory.globalCache().isSet("Infolog", null); // this is to verify if classFactory re-uses infolog's cache or not

}

   

client server static void addAppl() // actually no matter from where we insert into appl's cache – it's always on Server side

{

    ;

    appl.globalCache().set("Appl", null, "Added from " + funcName());

}

client server static void addInfolog() // actually no matter from where we insert into infolog's cache – it's always on Client side

{

    ;

    infolog.globalCache().set("Infolog", null, "Added from " + funcName());

}

client static void addClassFactory_Client()

{

    ;

    classfactory.globalCache().set("ClassFactory_Client", null, "Added from " + funcName());

}

server static void addClassFactory_Server()

{

    ;

    classfactory.globalCache().set("ClassFactory_Server", null, "Added from " + funcName());

}

client static void print_Client()

{

    print " === Client: ===";

   

    new GlobalCacheTest().printCaches();

   

}

server static void print_Server()

{

    print " === Server: ===";

   

    new GlobalCacheTest().printCaches();

}

public static void main(Args _args)

{

    ;

    GlobalCacheTest::addAppl();

    GlobalCacheTest::addInfolog();

    GlobalCacheTest::addClassFactory_Client();

    GlobalCacheTest::addClassFactory_Server();

   

    GlobalCacheTest::print_Client();

    GlobalCacheTest::print_Server();

   

    pause;

}

}

   

Заключение: поскольку создаются 2 экземпляра classFactory с независимыми кэшами, как равноценную замену можно использовать следующий код (см. Inside Dynamics AX, глава 15):

Оригинал

Эквивалент

if(Global::IsRunningOnServer())

{

    cache = appl.globalCache();

}

else

{

    cache = infolog.globalCache();

}

cache = classFactory.globalCache()

 

Class_GlobalCacheTest.xpo