Krishnamuthu Ve... · Sep 12, 2020

Calling a classmethod of an instance from another instance via native method

Dear Folks,

I am looking for a native approach to call a ClassMethod of an instance from another instance (Instances are running in different servers).  I can still do this via API over Http or any other communication method but I believe it would be better if I communicate via IRIS native methods(If exists).


0 654
Discussion (14)5
Log in or sign up to continue

It's not clear what you mean by "native".
This is one option. Background Jobs over ECP.

But as IRIS Servers also talk to each other over TCP I don't see any advantage over using a SOAP service or WebSockets or similar.

If you're using IRIS 2020.2.0 or above (both target and source instances must be ^2020.2.0), you can try to leverage %Net.DB.Iris. It's an implementation of IRIS Native for Java/.NET/Python/Node except for Objectscript. If there is enough interest for features like %Net.DB.Iris, @Bob Kuszewski would love to hear about it and communicate that interest over to the development teams!


As per my understanding "Native API" in IRIS is useful for cross platform like JAVA,Dot Net and Python technologies to exchange the data from IRIS instance,but I do not think any advantage of calling a class method of one IRIS instance from different instance of IRIS by using Native API.

Fully with you.
There are so many variants to let talk them to each other. 
And on the same server there are enough other options. 

Can you elaborate? How else can a session running on one IRIS instance invoke a class method on some other IRIS instance?

some ideas from the hip:

  • classic SOAP service
  • running a background job over ECP
  • having a listening job that triggers whatever you need
  •  using WebSocket communications

They all run over TCP as there is nothing else between separated servers.
At the bottom line, you rely on some code expecting a request.
"Native API" for various languages, or Studio, or CSP do the same over Super Server Port (1972) 
the quality is different, not the principle.

Let me focus on the last two items in your list. IRIS Native for Java, Node.js, DotNet, Python - these are all consistent implementations of the IRIS Native API and the communication is over TCP or shared memory. IRIS Native for ObjectScript is just another - consistent - implementation of the IRIS Native API.

To get a connection to an IRIS server, the command is similar across all implementations of IRIS Native API:

set connection = ##class(%Net.DB.DataSource).CreateConnection(host, port, namespace, user, pwd)

Once you have a connection, you can get an IRIS object.

set iris = connection.CreateIris()

and from an iris object, you can invoke class methods, code implemented in routines, set/get globals, and so on.

Hi, @Dan Pasco 
Since what release does this exist.?
It never crossed my way and obviously nobody else reacted to these questions.

I found a  first trace showing up in Class References of 2020.1 but it is even invisible in IRISlatest docbooks.
Big THANKS for uncovering this secret. yes

That is a good question! I checked the internal change logs and found my changes were in 2020.1. Maybe earlier but I installed 2020.1 build 215 and tested a simple case.

IRIS for UNIX (Apple Mac OS X for x86-64) 2020.1 (Build 215U) Mon Mar 30 2020 20:24:45 EDT

The test is simple - I am running in the 2020R1 instance, namespace USER and there are no classes runnable in this namespace - just a clean, new install. I have several other instances running, all different versions/build numbers. I am testing against my XDBC instance which is currently labeled as 2020.4 (obviously not yet released but the IRIS Native code is essentially the same as in 2020.1). The XDBC instance is listening on port 51780. First, proof this doesn't work locally.

USER>write ##class(Sample.Person).CurrentAge($h-35000)                 

WRITE ##CLASS(Sample.Person).CurrentAge($H-35000)

And then, attempt the same function using the IRIS Native connection to the XDBC instance.

USER>set host="localhost",port=51780,namespace="USER",user="_SYSTEM",pwd="SYS" 

USER>set connection = ##class(%Net.DB.DataSource).CreateConnection(host, port, namespace, user, pwd)

USER>set iris = connection.CreateIris()                                                             

USER>write iris.ClassMethodValue("Sample.Person","CurrentAge",$h-35000)                             

This is just a sample. Browse the classes in the SMP Explorer, look at the class docs for %Net.DB.Iris.cls.

This functionality might also be present in a 2019 kit but I didn't test it.

Thank you @Dan Pasco 
I just did a summary on the Class Ref.
I'll take a copy of your reply as an example for the audience.

Thank you so much ! this is exactly what I was looking for.

If the servers can 'see' each other . Lets call then Server A with Namespace A and Server B with Namespace B. You do the following:

1) From the Management Portal on Server A use the System->Configuration->ECP Settings->ECP Data Servers and Add a new Server connection to Server B

2) Then within the System Configuration use the Add Remote Database to create a Database definition of the Database or Databases that Namespace B uses (Typically a namespace will be linked to one database that contains both the Application Code (Classes and Routines) and the Application Data (Globals). However it is also possible that the Application Classes and Routines live in one database and the data in another. 

3) On Server A create a new Namespace that links to the Database(s) you have mapped in step (2)

4) In the Namespace Definition of Namespace A on Server A use the Package Mapping to Map the class, selection of classes or class package into Namespace A. If the class you want to interact with is linked to an underlying Global Definition (Data, Index and Stream) then use the Global Mapping to Map the Globals used by the class into Namespace A

5) The Class (call it {PackageB}.[ClassNameB} will now appear as a class in Namespace A and if you run the methods in {PackageB}.{ClassNameB} then the code will execute in the Cache Job on Server A but any data retrievals or saves will be executed in the global(s) in the Global Database of Namespace B on Server B

There may be licensing implications to use ECP but I am not an expert on current InterSystems licensing models

The other way would be to expose the methods of Class B in Namespace B on Server B in the form of a Web Service on Server B and then invoke the methods from Server A by invoking HTTP calls to the Web Service.


I don't see any performance disavantages in using SOAP or REST to call classmethods of other IRIS instances compared to ECP.
And SOAP/REST is available in all IRIS license types, in contrast with ECP.