About Space Operations

  Search Here
Searching XAP 6.0 Documentation

                                               

Summary: A description of Entries, templates, the four primary kinds of operations – write, read, take, and notify, and the UpdateModifiers.UPDATE_OR_WRITE modifier.

Overview

There are four primary kinds of operations that you can invoke on a JavaSpaces service. Each operation has parameters that are Entries, including some that are templates, which are a kind of Entry. This section describes Entries, templates, and the details of the operations, which are:

  • write – writes the given Entry into this JavaSpaces service.
  • read – reads an Entry from this JavaSpaces service that matches the given template.
  • take – reads an Entry from this JavaSpaces service that matches the given template, removing it from this space.
  • notify – notifies a specified object when Entries that match the given template are written into this JavaSpaces service.

As used in this document, the term "operation" refers to a single invocation of a method; for example, two different take operations may have different templates.

The information in this section is taken from the JavaSpaces Service Specification.

Entries

The types Entry and UnusableEntryException that are used in this specification are from the package net.jini.core.Entry and are described in detail in the About Entries section. In the terminology of that specification write is a store operation; read and take are combination search and fetch operations; and notify sets up repeated search operations as Entries are written to the space.

net.jini.space.JavaSpace

All operations are invoked on an object that implements the JavaSpace interface. For example, the following code fragment would write an Entry of type AttrEntry into the JavaSpaces service referred to by the identifier space:

JavaSpace space = getSpace();
AttrEntry e = new AttrEntry();
e.name = "Duke";
e.value = new GIFImage("dukeWave.gif");
space.write(e, null, 60 * 60 * 1000);	 // one hour
// lease is ignored -- one hour will be enough

The JavaSpace interface is:

package net.jini.space;
import java.rmi.*;
import net.jini.core.event.*;
import net.jini.core.transaction.*;
import net.jini.core.lease.*;

public interface JavaSpace {
    Lease write(Entry e, Transaction txn, long lease)
        throws RemoteException, TransactionException;
    public final long NO_WAIT = 0; // don't wait at all
    Entry read(Entry tmpl, Transaction txn, long timeout)
        throws TransactionException, UnusableEntryException,
               RemoteException, InterruptedException;
    Entry readIfExists(Entry tmpl, Transaction txn,
                       long timeout)
        throws TransactionException, UnusableEntryException,
               RemoteException, InterruptedException;
    Entry take(Entry tmpl, Transaction txn, long timeout)
        throws TransactionException, UnusableEntryException,
               RemoteException, InterruptedException;
    Entry takeIfExists(Entry tmpl, Transaction txn,
                       long timeout)
        throws TransactionException, UnusableEntryException,
               RemoteException, InterruptedException;
    EventRegistration notify(Entry tmpl, Transaction txn,
              RemoteEventListener listener, long lease,
              MarshalledObject handback)
        throws RemoteException, TransactionException;
    Entry snapshot(Entry e) throws RemoteException;
}

The Transaction and TransactionException types in the above signatures are imported from net.jini.core.transaction. The Lease type is imported from net.jini.core.lease. The RemoteEventListener and EventRegistration types are imported from net.jini.core.event.

In all methods that have the parameter, txn might be null, which means that no Transaction object is managing the operation (see Transactions; Section JS.3).

The JavaSpace interface is not a remote interface. Each implementation of a JavaSpaces service exports proxy objects that implement the JavaSpace interface locally on the client, talking to the actual JavaSpaces service through an implementation-specific interface. An implementation of any JavaSpace method may communicate with a remote JavaSpaces service to accomplish its goal; hence, each method throws RemoteException to allow for possible failures. Unless noted otherwise in this specification, when you invoke JavaSpace methods you should expect RemoteExceptions on method calls in the same cases in which you would expect them for methods invoked directly on an RMI remote reference. For example, invoking a snapshot might require talking to the remote JavaSpaces server, and so might get a RemoteException if the server crashes during the operation.

All of the JavaSpace methods are detailed below.

InternalSpaceException

The exception InternalSpaceException might be thrown by a JavaSpaces service that encounters an inconsistency in its own internal state or is unable to process a request because of internal limitations (such as storage space being exhausted). This exception is a subclass of RuntimeException. The exception has two constructors: one that takes a String description and another that takes a String and a nested exception; both constructors simply invoke the RuntimeException constructor that takes a string argument.

package net.jini.space;

public class InternalSpaceException extends RuntimeException {
    public final Throwable nestedException;
    public InternalSpaceException(String msg) {...}
    public InternalSpaceException(String msg, Throwable e) {...}
    public printStackTrace() {...}
    public printStackTrace(PrintStream out) {...}
    public printStackTrace(PrintWriter out) {...}
}

The nestedException field is the one passed to the second constructor, or null if the first constructor was used. The overridden printStackTrace methods print out the stack trace of the exception and, if nestedException is not null, print out that stack trace as well.

write

A write places a copy of an Entry into the given JavaSpaces service. The Entry passed to the write is not affected by the operation. Each write operation places a new Entry into the specified space, even if the same Entry object is used in more than one write.

Each write invocation returns a Lease object that is lease milliseconds long. If the requested time is longer than the space is willing to grant, you will get a lease with a reduced time. When the lease expires, the Entry is removed from the space. An IllegalArgumentException is thrown if the lease time requested is negative and not equal to Lease.ANY. It is possible to renew a lease by calling Lease.renew – updates the lease time of the Entry, or cancel a lease by calling Lease.cancel – removes the Entry from the space.

When renewing or cancelling a lease in a replicated clustered space, and the source space has already failed, or fails at the exact time the operation is being performed, the renew/cancel operation (like any other operation) is automatically routed to the target spaces.


If a write returns without throwing an exception, that Entry is committed to the space, possibly within a transaction. If a RemoteException is thrown, the write may or may not have been successful. If any other exception is thrown, the Entry was not written into the space.

Writing an Entry into a space might generate notifications to registered objects (see below).

readIfExists and read

The two forms of the read request search the JavaSpaces service for an Entry that matches the template provided as an Entry. If a match is found, a copy of the matching Entry is returned. If no match is found, null is returned. Passing a null reference as the template matches any Entry.

Successive read requests with the same template in the same JavaSpaces service may or may not return equivalent objects, even if no intervening modifications have been made to the space. Each invocation of read may return a new copy even if the same Entry is matched in the JavaSpaces service.

The timeout parameter specifies how long the client is willing to wait until a matching Entry is found. If the only possible matches for the template have conflicting locks from one or more transactions, the client waits until either it times out, or the transaction state settles. null is returned if no match is found in the specified period.

readIfExists acts like read, except that it only waits if a matching Entry is locked under one or more transactions. Otherwise, it returns immediately ?- disregarding the timeout parameter. In either case, null is returned if no match is found.

Calling readIfExists on an Entry (using a UID), matches one and only one Entry. null is returned if this specific Entry is locked during the specified timeout period. An EntryNotInSpaceException is thrown if this Entry is not found.

Note that due to the remote nature of JavaSpaces services, read and readIfExists may throw a RemoteException if the network or server fail prior to the timeout expiration.

In both read methods, a timeout of NO_WAIT means to return immediately, without waiting, which is equivalent to using a zero timeout. An IllegalArgumentException is thrown if a negative timeout value is used.

Using POJOs, redIfExists never throws an EntryNotInSpaceException (this will be fixed in future versions). Except for this difference, the behaviour of redIfExists with POJOs is the same.

takeIfExists and take

The take requests perform exactly like the corresponding read requests (see above), except that the matching Entry is removed from the space. Two take operations never return copies of the same Entry, although if two equivalent Entries exist in the JavaSpaces service the two take operations can return equivalent Entries.

If a take returns a non-null value, the Entry has been removed from the space, possibly inside a transaction. This modifies the claims to once-only retrieval: A take is considered to be successful only if all enclosing transactions commit successfully. If a RemoteException is thrown, the take may or may not have been successful. If an UnusableEntryException is thrown, the take removed the unusable Entry from the space (see About Entries). If any other exception is thrown, the take did not occur, and no Entry was removed from the space.

With a RemoteException, an Entry can be removed from a space and yet never returned to the client that performed the take, thus losing the Entry in between. In circumstances in which this is unacceptable, the take can be wrapped inside a transaction that is committed by the client when it has the requested Entry in hand.

snapshot

The process of serializing an Entry for transmission to a JavaSpaces service will be identical if the same Entry is used twice. This is most likely to be an issue with templates that are used repeatedly to search for Entries with read or take. The client-side implementations of read and take cannot reasonably avoid this duplicated effort, since they have no efficient way of checking whether the same template is being used without intervening modification.

The snapshot method gives the JavaSpaces service implementor a way to reduce the impact of repeated use of the same Entry. Invoking snapshot with an Entry will return another Entry object that contains a snapshot of the original Entry. Using the returned snapshot Entry is equivalent to using the unmodified original Entry in all operations on the same JavaSpaces service. Modifications to the original Entry will not affect the snapshot. You can snapshot a null template; snapshot may or may not return null given a null template.

The Entry returned from snapshot is guaranteed equivalent to the original unmodified object only when used with the space. Using the snapshot with any other JavaSpaces service will generate an IllegalArgumentException unless the other space can use it because of knowledge about the JavaSpaces service that generated the snapshot. The snapshot is a different object from the original, might or might not have the same hash code, and equals might or might not return true when invoked with the original object, even if the original object is unmodified.

A snapshot is guaranteed to work only within the virtual machine in which it was generated. If a snapshot is passed to another virtual machine (for example, in a parameter of an RMI call), using it – even with the same JavaSpaces service – may generate an IllegalArgumentException.

We expect that an implementation of JavaSpaces technology will return a specialized Entry object that represents a pre-serialized version of the object, either in the object itself or as an identifier for the Entry that has been cached on the server. Although the client may cache the snapshot on the server, it must guarantee that the snapshot returned to the client code is always valid. The implementation may not throw any exception that indicates that the snapshot has become invalid because it has been evicted from a cache. An implementation that uses a server-side cache must therefore guarantee that the snapshot is valid as long as it is reachable (not garbage) in the client, such as by storing enough information in the client to be able to re-insert the snapshot into the server-side cache.

No other method returns a snapshot. Specifically, the return values of the read and take methods are not snapshots and are usable with any implementation of JavaSpaces technology.

notify

A notify request registers interest in future incoming Entries to the JavaSpaces service that match the specified template. Matching is done as it is for read. The notify method is a particular registration method under the Jini Technology Core Platform Specification; Distributed Events. When matching Entries are written, the specified RemoteEventListener is eventually be notified. When you invoke notify you provide an upper bound on the lease time, which is how long you want the registration to be remembered by the JavaSpaces service. The service decides the actual time for the lease. You get an IllegalArgumentException if the lease time requested is not Lease.ANY and is negative. The lease time is expressed in the standard millisecond units, although actual lease times will usually be of much larger granularity. A lease time of Lease.FOREVER is a request for an indefinite lease; if the service chooses not to grant an indefinite lease, it will return a bounded (non-zero) lease. The final argument to the notify request is a MarshaledObject called the handback.

Each notify returns a net.jini.core.event.EventRegistration object. When an object is written that matches the template supplied in the notify invocation, the listener's notify method is eventually invoked, with a RemoteEvent object. The RemoteEvent object's getID method will return the same value returned by the EventRegistration object's getID method. This value, the event ID, are unique at least with respect to all other active event registrations on this JavaSpaces service with different templates or transactions. The RemoteEvent object's getSource method returns a reference to the JavaSpaces service. If the handback associated with the registration was non-null, the RemoteEvent object's getRegistrationObject method returns an object that is equivalent (in the sense of the equals method) to the handback, otherwise this method returns null. The RemoteEvent object's getSequenceNumber method returns the sequence number assigned to this event. Sequence numbers for a given event ID are strictly increasing. If there is no gap between two sequence numbers, no events have been missed; if there is a gap, events might (but might not) have been missed. For example, a gap might occur if the JavaSpaces service crashes, even if no events are lost due to the crash.

If the transaction parameter is null, the listener is notified when matching Entries are written either under a null transaction or when a transaction commits. If an Entry is written under a transaction and then taken under that same transaction before the transaction is committed, listeners registered under a null transaction are not notified of that Entry.

If the transaction parameter is not null, the listener is notified of matching Entries written under that transaction in addition to the notifications it would receive under a null transaction. A notify made with a non-null transaction is implicitly dropped when the transaction completes.

The request specified by a successful notify is as persistent as the Entries of the space. They are remembered as long as an untaken Entry would be, until the lease expires, or until any governing transaction completes, whichever is shorter.

The service makes a "best effort" attempt to deliver notifications. The service retries at most until the notification request's lease expires. Notifications can be delivered in any order.

For details on the event types, refer to: Jini Technology Core Platform Specification; Distributed Events].

Operation Ordering

Operations on a space are unordered. The only view of operation order can be a thread's view of the order of the operations it performs. A view of inter-thread order can be imposed only by cooperating threads that use an application-specific protocol to prevent two or more operations being in progress at a single time on a single JavaSpaces service. Such means are outside the purview of this specification.

For example, given two threads T and U, if T performs a write operation and U performs a read with a template that would match the written Entry, the read may not find the written Entry even if the write returns before the read. Only if T and U cooperate to ensure that the write returns before the read commences would the read be ensured the opportunity to find the Entry written by T (although it still might not do so because of an intervening take from a third entity).

update

Single Update Semantics

The update methods obey the same JavaSpaces semantics as read or take with timeout. The return value is null, in case a timeout occurs after waiting for a transactional proper matching Entry.

When the UpdateModifiers.UPDATE_OR_WRITE modifier is applied to an update call, the return value behaves differently to account for the ambiguity of a null result – returning:

  • null – if write was successful.
  • previous value – if update was successful.
  • OperationTimeoutException - thrown if a timeout occurred.

The latter, OperationTimeoutException is thrown where null would have otherwise been returned.

null is an indication that a write operation was performed.

Note that the operation modifier means to write if absent, or to update an existing entity.

Batch Update Semantics

Batch updates (updateMultiple) return an array of objects which correspond to the input Entries array.

The returns array elements can be:

  • null – if write was successful.
  • previous value - if update was successful.
  • OperationTimeoutException – if a timeout occurred.

If the lease of the first write operation is desired, it is obtainable using the LeaseContext object. A LeaseContext is a usable lease only when returned after a successful write.

To distinguish between a write and an update, the LeaseContext.getObject() returns:

  • null – if write was successful.
  • previous value - if update was successful.
  • OperationTimeoutException – if a timeout occurred.

These semantics are consistent and are relevant only when the UPDATE_OR_WRITE modifier is applied.

The UPDATE_OR_WRITE modifier is currently supported by:

  • write (of a POJO).
  • update (of an Entry or a POJO).
  • updateMultiple (of Entries or POJOs).

Currently, the modifier doesn't support write (of an Entry) and writeMultiple.

Read/take with Timeout > 0 behavior with Persistent spaces and External data source implementations

The JavaSpace specification does not talk in details about persistent spaces or integration with External data sources. There is no specific description about the behavior of the space/client with read/take operation with timeout > 0 when the space is persistent and interact with 3rd party products to read data back from the persistent media or persist data (take operations involves data removal operation).

Once GigaSpaces cross the boundary of the space engine and hand the control to a 3rd party, it cannot guaranty the wait period. If the External data source implementation performs for example a long sleep when a request to load data called (read), the space engine would not interrupt the operation once the timeout expires and would not return back to the client with null return value. The same behavior applies for complex query or connecting to a remote database over a slow network.

Workaround/Solutions:


IMPORTANT: This is an old version of GigaSpaces XAP. Click here for the latest version.
GigaSpaces 6.0 Documentation Contents (Current Page in Bold)

    Java

    C++

    .NET

    Middleware Capabilities

    Configuration and Management

Add GigaSpaces wiki search to your browser search engines!
(works on Firefox 2 and Internet Explorer 7)

Labels