If you need to map the globals to multiple namespace, you can map them to the virtual namespace %ALL. (see this article: https://community.intersystems.com/post/defining-global-routine-and-pack...).

And yes, you can also explicitly reference globals from another namespace by using the syntax ^["other namespace"]myGlobal. (see in documentation: http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...)

Hi Steve,

It also depends if you are indexing all the sources at once or a bunch per day  : typically, a batch load will grow your database, and will leave it 50% empty at the end, after deleting  temporary storage. This is not a problem if you load new sources regularly, since this empty space will be used the next time.

If these temporary iKnow globals are mapped to cachetemp, dont forget to take this needed disk space into account as well, even if it will be released after restart. (especially since cachetemp is by default installed on the same drive as Caché, and could have less free disk space as other drives where you put your databases)

Global memory works with blocks and not with nodes :

When a global  node is accessed, the block where this global node is stored will be put into memory.

Any routine that needs to access the nodes that are in this block will be served from memory.

So, in your example, if the nodes (1), (1,2) and (1,7) are all stored in the same block, these will all be served from memory after the initial access by routineA.

Blocks are nowadays 8Kb (used to be 2Kb).

Hi Amir,

You should convert all incoming data that is not in your native encoding : you don't want data in your database that is coming from ODBC, Web, Files or other to have different encodings !

I use $ZCONVERT( ... , "I", "UTF8") for all incoming data thru rest, and use $ZCONVERT( ... , "O", "UTF8") for all data that is sent via rest. I also use the "u" format flag when i use %WriteJSONFromSQL.

- If the two directories should have the same classes, you could use class mapping to point the two namespaces to the same code base ...

Beside getting a source code tool, there are several ways to compare  :

- If you want to write your own compare logic, you can use the %Dictionary.* classes (a lot of work,  since there are a lot of classes /properties to compare). Use this to get a list of classes in the two directories and to see which is missing.

- If you want to compare  two classes quick-and-dirty : you can have a look at the global ^oddDEF. It contains the class definition of all classes : methods, properties, indexes, storage etc. are all in this global. You could $ZOrder your way through the global and compare the two namespaces. But since this is internal stuff, it could change in new versions of Caché!

Here is an example, but test before you use it !!!

Class Utils.Classes
{

/// Compare two classes :
/// If ##class(Utils.Classes).Diff("USER","TEST","Data.MyClass", .reason) {
///   Write $List(reason, 1)," = ",$List(reason, 2) ;global from USER
///   Write $List(reason, 3)," = ",$List(reason, 4) ;global from TEST
/// } 
ClassMethod Diff(ns1 As %String, ns2 As %String, class As %String, ByRef reason As %String)
{
   Set diff = ..Diff1way(ns1, ns2, class, .reason)
   If 'diff Set diff = ..Diff1way(ns2, ns1, class, .reason)
   Quit diff
}

ClassMethod Diff1way(ns1 As %String, ns2 As %String, class As %String, ByRef reason As %String)
{
   Set diff = 0
   Set startref1="^["""_ns1_"""]oddDEF("""_class
   Set startref2="^["""_ns2_"""]oddDEF("""_class
   Set global1="^["""_ns1_"""]oddDEF("""_class_""")"
   For {
       Set global1=$ZOrder(@global1) Quit:global1=""  Quit:global1'[startref1
       Set data1=$Get(@global1)
       Set subs=$Piece(global1,class,2,*)
       Set global2=startref2_subs
       Set data2=$Get(@global2)
       If (subs=""",63)")!(subs=""",64)") Continue  ;properties time changed (63) & time created (64) can be different
       If data1'=data2 Set diff=1,reason=$lb(global1,data1,global2,data2) Quit
   }
   Quit diff
}

}

Can you look in the directory r:\data\blabla :

there should be a CACHE.DAT, and it should not be locked by another Caché instance.

You can verify who locked the CACHE.DAT file by looking at the cache.lck file in the same directory, this file contains the mgr directory  of the Caché instance who mounted the CACHE.DAT database :

  • If Caché is not running, there should not be a cache.lck file.
  • If Caché is running, the cache.lck should contain the mgr directory and server name of the Cache instance.

You can stop Caché and delete the cache.lck file if any of the previous conditions are false. After startup and mount, the cache.lck file should automatically be created with the proper mgr directory name. (mount will occur by accessing the database or namespace using the database).

And if you want to make your own prompt, you could even use your own Shell routine :

Shell ;
    For {
        Try {
            Write !,$$Prompt()
            Read cmd Write !
            Xecute cmd
        } Catch {
            Write $ZE,!
        }
        If ($ZCVT($G(cmd),"U")="QUIT") Quit
    }
    Quit

Prompt() ;Create your own prompt here !
    New prompt
    Set prompt = $ZDate($H,4)_" - "_$ZTime($P($H,",",2))_" > "
    Quit prompt

You can put some code in the OnHandleCorsRequest to debug or monitor the CORS handling :

/// This is the CORS request handler. User should override this method in their subclass
/// if they don't want the default behavior
ClassMethod OnHandleCorsRequest(pUrl As %String) As %Status
{
    #; The default implementation is simply to dispatch to the
    #; default handler
    Set tOrigin=$Get(%request.CgiEnvs("HTTP_ORIGIN"))
    Set ip = $Get(%request.CgiEnvs("REMOTE_ADDR"))
    Set method = $Get(%request.CgiEnvs("REQUEST_METHOD"))
    set ^debug($i(^debug))=$lb($ZD($H,8),$ZT($P($H,",",2)),pUrl,tOrigin,ip,method)
    Quit ..HandleDefaultCorsRequest(pUrl)
}