Instances

To communicate between instances of one same program


Introduction

Through this integrate API, java program can communicate between instances of the same program.

This feature is enabled by config 'singleinstance custom', so if your java program needs to do the commucation, 'singleinstance custom' must be add to internal or external config.

[since 2.5.5] The sender could pass in a `Reply` instance to get the reply asynchronously. The receiver could get the `Reply` instance during the onReceive callback is being called.


API Class

The API class provides some static methods to get instances and send messages.

public class Instances {
    
    /**
     * Async result
     */
    public static interface Reply {
        /**
         * @param result
         */
        void set(Serializable result);
    }

    /**
     * Interface to receive object from another instance
     */
    public static interface ReceiverInterface {
        /**
         * Callback function when message arrived.
         *
         * You could not block the callback thread, or the communication will be interrupted.
         *
         * @param frominstance pid of the sender instance
         * @param object java object received
         */
        public void onReceive(int frominstance, Serializable object);
    }
    
    /**
     * Get the first (pid) of previous instances
     * @return pid of first instance
     */
    public native static int getFirstInstance();
    
    /**
     * Get current instance (pid)
     * @return pid of current instance
     */
    public native static int getCurrentInstance();
    
    /**
     * Get all instances (pid) of current program
     * @return array of pid, the first one is the first instance, the second is the second, and so on
     */
    public native static int[] getInstances();
    
    /**
     * Send object to the first instance
     * @param object object to send
     */
    public static void sendObject(Serializable object) {
        sendObject(getFirstInstance(), object);
    }
    
    /**
     * Send object to specific instance (pid)
     * @param toinstance pid of target instance
     * @param object object to send
     */
    public static void sendObject(int toinstance, Serializable object) {
        sendObject(toinstance, object, null);
    }
    
    /**
     * Send object to specific instance (pid)
     * @param toinstance pid of target instance
     * @param object object to send
     * @param reply async callback
     */
    public native static void sendObject(int toinstance, Serializable object, Reply reply);
    
    /**
     * The reply should be 3rd parameter of onReceive().
     * But for compatibility, get the reply during running of onReceive(),
     * you can do the reply later asynchronously but you need to get the instance before return of onReceive()
     * @param object
     */
    public native static Reply getReply();
    
    /**
     * Wait the object to be sent by sendObject().
     * Usually it's not required to flush() unless it's going to exit.
     */
    public native static void flush();
    
    /**
     * Set the receiver instance
     * @param thereceiver the receiver instance
     */
    public native static void setReceiver(ReceiverInterface thereceiver);
}

To receive the message from another instance, java program needs to implement the interface ReceiverInterface and set it to the setReceiver().


Demo Code

This is a demo program.

package hello;

import java.io.Serializable;
import java.util.Arrays;

import com.regexlab.j2e.Instances;

/**
 * To control the single instance. The second instance will send its arguments to
 * the first instance and then exits.
 */
public class HelloSingleInstance implements Instances.ReceiverInterface {

	public static void main(String[] args) throws InterruptedException {
		
		// set the Receiver
		Instances.setReceiver(new HelloSingleInstance());
		
		// check whether this is the first instance
		int first   = Instances.getFirstInstance();
		int current = Instances.getCurrentInstance();
		
		if(first == current) {
			System.out.println("This is the first instance");
		}
		
		// else this is NOT the first instance
		else {
			System.out.println("This is NOT the first instance.");
			
			// send the 'args' to the first instance 
			Instances.sendObject(first, args);
			
			// flush() before it's going to exit, usually flush() is not required
			Instances.flush();
			
			// then exit
			System.exit(1);
		}
		
		// your main task of your program
		System.out.print("Sleeping 200 seconds for TESTing ");
		for(int i=0; i<200; i++) {
			System.out.print(".");
			Thread.sleep(1000);
		}
	}

	public void onReceive(int frominstance, Serializable object) {
		String [] args = (String[])object;
		
		// you can do something with the args
		System.out.println("\nAnother instance ("+frominstance+") launched and his args = " + Arrays.asList(args));
	}

}

See Also

Add new comment