In order to use the space in a stand alone fashion in your java code, just obtain a reference to it, and use it. You will need to use threading in order to benefit from it, as you typically will have an application thread and a worker thread:
SemiSpaceInterface space = SemiSpace.retrieveSpace();
In order to insert an element into the space, use write:
Element element = new Element(); element.setName(args[0]); element.setValue(args[1]); SemiSpaceInterface space = SemiSpace.retrieveSpace(); // Life time of 5 minutes. space.write( element, 1000*5*60); System.out.println("Element inserted successfully: "+element.getName()+"="+element.getValue());
Similarly, in order to read an element in the space, use:
Element searchFor = new Element(); searchFor.setName(args[0]); SemiSpaceInterface space = SemiSpace.retrieveSpace(); // reading with a timeout of 60 seconds Element read = space.read(searchFor, 60000); if ( read == null ) { System.out.println("Could not find an element with name "+searchFor.getName()); } else { System.out.println("Element found: "+read.getName()+"="+read.getValue()); }
In order to remove an element from the space do:
Element read = space.take(searchFor, 60000);
The essential difference, is the read statement. Read can be performed repeatedly, whereas take will remove the object from the space.
Notify gives you an event containing the XML source of the element which matched the registration.
A simple example of this is the following. First you need to register a notification:
SemiSpaceInterface space = SemiSpace.retrieveSpace(); SemiEventRegistration eventRegistration = space.notify(new Element(), this, 60 * 1000 * 60); // If this comment is seen in the doc, it is because mavens apt book generator has // become confused with the code snippets. for ( int i=0 ; i < 10 ; i++) { try { Thread.sleep(1000 * 10); } catch (InterruptedException e) { // Ignore } } /* If you like to cancel the notification, perform the following: */ eventRegistration.getLease().cancel(); } catch (RuntimeException e) { e.printStackTrace(); } } }
In the notification method itself, you perform whatever you want in case of notification. The following just prints a statement that explains that an object matching the template is found in the space.
public void notify(SemiEvent theEvent) { if ( theEvent instanceof SemiAvailabilityEvent) { System.out.println("Incoming element which concurs with template has arrived."); Element element = (Element) SemiSpace.retrieveSpace().takeIfExists( new Element()); if ( element ==null ) { System.out.println("Could not take element that was flagged as available"); } else { System.out.println("Read element from space: "+element.getName()+"="+element.getValue()); } } }
Sometimes, you will try to take the Object that has been transported with the notification. Be aware that the object may already have disappeared (for instance if it has already been taken). Therefore you always need to test your taken object for null.
You may think that a long living notification may be a problem if the instance falls down when being distributed with Terracotta. This is not the case. The notification lives only within the server instance in question, and if it disappears, it does not matter - the notification just disappears with it. However, the statistics will become wrong - in the count of number of listeners, as the listener is not de-registered correctly. This is inconsequential.
If you like to cancel the registration, you can do this on the registration lease.