Summary: Performing space operations with GigaSpaces space-based .NET API.

Overview

GigaSpaces .NET API framework allows .NET users to perform space operations using .NET business objects. The .NET objects are transformed into space Entries, transparently allowing the .NET application to write, read, take, and receive notifications. This section describes the space operations you can perform.

Connecting to Space

To connect to the space, you should first get the space proxy using the SpaceProxyProviderFactory class:

ISpaceProxy proxy = SpaceProxyProviderFactory.Instance.FindSpace(spaceUrl);

The Space URL can represent remote, embedded, or clustered in a single space proxy. For more details, refer to the Space URL section.

Introducing Class to Space

The ISpaceProxy.Snapshot() method can be used to explicitly introduce .NET business classes to the space. It is not mandatory to use it for new objects but it will increase the performance of the first operation on the proxy with a type that wasn't introduced yet.

proxy.Snapshot(new Person());

If the space stores the same class with different attributes or types, an UnusableEntryException is thrown.

Writing Object to Space

A write operation writes a copy the given object to the space, hence, any changes done to the object after the write operation doesn't affect the object in the space.

When writing your objects to the space, construct the object as usual, and use the ISpaceProxy.Write operation:

The Person object:

namespace Examples
{
  class Person
  {
    private string _userId;
    private string _name;
    private int _age;
    private float _weight;

    public string UserId
    {
      get { return _userId; }
      set { _userId = value; }
    }
  
    public string Name
    {
      get { return _name; }
      set { _name = value; }
    }
  
    public int Age
    {
      get { return _age; }
      set { _age = value; }
    }

    public float Weight
    {
      get { return _weight; }
      set { _weight = value; }
    }

    public Person()
    {
    }
  }
}
Person p = new Person();
p.UserId = "011-1111111";
p.Name = "Kermit the frog";
p.Age = 38;
p.Weight = 200.5F;

ISpaceProxy proxy = SpaceProxyProviderFactory.Instance.FindSpace(spaceUrl);
proxy.Write(p);

This call generates a new object inside the space which is a copy of the Person object p.

UpdateModifiers Parameter

The UpdateModifiers modifier is used as a parameter in the ISpaceProxy.Write operation, and includes the following options: PartialUpdate, UpdateOnly, UpdateOrWrite (see About Space Operations), WriteOnly (the same use as in the Java UpdateModifiers class; see Javadoc ).

private void UpdateModifiersDemo()
{
  ISpaceProxy proxy = SpaceProxyProviderFactory.Instance.FindSpace("/./mySpace");
  object objectInstance = new object();

  // UpdateModifiers contains values to customize the behaviour of write/update operations.
  // For example: in this write operation, if entry already exists in space an EntryAlreadyInSpaceException will be thrown.
  proxy.Write(objectInstance, null, long.MaxValue, 0, UpdateModifiers.WriteOnly);
  // More info: /docs/JavaDoc6/com/j_spaces/core/client/UpdateModifiers.html
}

Lease

The space provides a mechanism, called leasing, that keeps the space clean and consistent even if applications disconnect before they erase their temporary data. Leasing is supported both for regular write operations and transactions.

Each time an application writes an object to the space, it must specify the lease time – how long it should remain in memory before the space automatically deletes it.

If the information is of a persistent nature, the lease can be set to FOREVER (and the object is never erased). Otherwise, a limited lease time can be set, such as 5 minutes – after this elapses, if the object is still needed, it is the application's responsibility to renew the lease.

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 object is removed from the space.

To explicitly enable this behavior with the .NET API, initialize a .NET proxy with NoWriteLease = false in the space URL (default is false):

string spaceUrl = "jini://*/./mySpace?NoWriteLease=false"

You can then perform the Renew() or Cancel() methods on the Lease.

ILeaseContextleaseContext =
proxy.Write(new Preson("Ben"));
...
leaseContext.Renew(1000);
...
leaseContext.Cancel();

Template Construction

Templates are used with Read, ReadMultiple, ReadIfExists, Take, TakeMultiple, TakeIfExists, AddListener, GetSpaceIterator, Snapshot, Count, and Clear operations.

If the template object contains fields or properties that are not nullable (Primitives, Structures) they should include a NullValue indication, that should be ignored when matching is performed. The simple way to do this is to decorate the field or property in the class with the [XAP66:SpaceProperty(NullValue = ...)] attribute with a value that represents null, and have this value as the default value for the field when constructing the object.

For more details, refer to the Object Metadata section.

Reading an Object from Space

To get a specific object copy from the space, you should use the ISpaceProxy.Read operation and provide the relevant template. The template should include field values that you would like to use for matching, and NullValue values for all the rest of the fields.


ISpaceProxy proxy = SpaceProxyProviderFactory.Instance.FindSpace("/./mySpace");
Person pTemplate = new Person();
pTemplate.UserId = "011-1111111";
Person resultRead = proxy.Read(pTemplate);

When you would like to get a copy of an object that belongs to a specific class type, regardless of its values, construct a template from the relevant class without specifying any values for its fields:

Person pTemplate = new Person();
Person resultRead = proxy.Read(pTemplate);

ReadModifiers Parameter

The ReadModifiers modifier is used as a parameter in the ISpaceProxy.Read operation, and includes the following options: RepeatableRead, ReadCommitted, DirtyRead, and ExclusiveReadLock - the same use as in the Java ReadModifiers class; see

Javadoc

.

private void ReadModifiersDemo()
{
  ISpaceProxy proxy = SpaceProxyProviderFactory.Instance.FindSpace("/./mySpace");
  // ReadTakeModifiers contains values to customize the behaviour of read/take operations.
  // Use proxy.ReadModifiers to control the space default behaviour.
  // For example:
  proxy.ReadModifiers = ReadModifiers.DirtyRead;
  object objectInstance = proxy.Read(new object());
  // More info: docs/JavaDoc/com/j_spaces/core/client/ReadModifiers.html
  // Or you can explcitly specify the ReadModifier passing a parameter to the Read method
  objectInstance = proxy.Read(new object(), null, 0, ReadModifiers.DirtyRead);
}

Taking an Object from Space

The Take() method reads an object that matches the given template from the space, and removes it.

To take a copy of your object from the space:

ISpaceProxy proxy = SpaceProxyProviderFactory.Instance.FindSpace("/./mySpace");
Person pTemplate = new Person();
pTemplate.UserId = "011-1111111";
Person resultTake = proxy.Take(pTemplate);

Updating Object in Space

To update an object in the space, you should use the ISpaceProxy.Update operation:

ISpaceProxy proxy = SpaceProxyProviderFactory.Instance.FindSpace("/./mySpace");
Person template = new Person();
template.Age = 38;
Person person_read = proxy.Read(template);
person_read.Age = 41;
Person previousPerson = proxy.Update(person_read);

The update method returns the object that was updated in its previous state.

Subscribing to Space Events

You can register for notifications via the AddListener method.

The AddListener is generic, meaning it is defined per specific type, where the type given is the name of the object you want to define the AddListener for.

For example:

public void NotifyDemo()
{
  ISpaceProxy proxy = SpaceProxyProviderFactory.Instance.FindSpace("/./mySpace");

  // DataEventSession provides a way to receive event notifications.
  // More info: docs/JavaDoc/com/gigaspaces/events/DataEventSession.html

  // Create a listener:
  proxy.DefaultDataEventSession.AddListener(new Person(), MyNotifyDemoListener.Space_PersonChanged, DataEventType.All);

  // This write operation will trigger a notification of type write to occur on listener.
  proxy.Write(new Person());
}

The AddListener includes a listener (a callback method invoked by the space). Furthermore, the object data field is included in the event argument, which holds the object that triggered the event.

Example for a .NET listener method:

public class MyNotifyDemoListener
{
  public static int Count = 0;
  public static void Space_PersonChanged(object sender, SpaceDataEventArgs e)
  {
    long notificationTime = DateTime.Now.Ticks;
    Console.WriteLine("MyDelegator.notify started.");
    Person p = e.Object;
    System.Threading.Interlocked.Increment(ref Count);
  }
  public MyNotifyDemoListener()
  {
    Count = 0;
  }
}

For more details, refer to the Session Based Messaging API section.

Transactions

Use the ITransaction interface to create a local transaction:

ITransaction txn = proxy.CreateLocalTransaction();
proxy.Write(person1, txn);
txn.Commit(1000);

To create a Jini transaction, use the ITransactionManager, which creates and manages the distributed Jini transaction:

ITransactionManager jiniTxnManager =
                       proxy.Factory.FindJiniTransactionManager();
//Creates the transaction with a timeout of 60000 miliseconds                       
txn = jiniTxnManager.Create(60000);
proxy.Write(person1, txn);
txn.Commit(1000);

For more details on GigaSpaces transactions, refer to the [JavaSpaces Transaction Support] section.

Committing and Aborting the Jini Transaction

When using the Jini Transaction Manager, you should consider using the ITransaction.Commit(long timeout) and ITransaction.Abort(long timeout) methods.

These return an acknowledgement to the caller application only after the transaction commit or abort operation has been fully completed by all transaction participants, or until the timeout period expired.

When using the ITransaction.Abort() and ITransaction.Commit(), the client gets the acknowledgement immediately after the abort or commit call, without waiting for all transaction participants to be completed. This might lead to inconsistency.

The timeout parameter allows you to choose the maximum amount of time you would like to wait for the transaction to be completed by all participants.

Make sure you do not define a large number (in milliseconds), because one of the transaction participants might hang without returning to the caller. This results in client hang.

This does not occur when using the Local Transaction Manager, because the client gets the acknowledgement for the commit or abort operation only after the space has completed the commit or abort processing.

For more details, refer to:

Batch operations

You can perform batch operations using WriteMultiple, ReadMultiple, TakeMultiple, or UpdateMultiple.

ReadMultiple

Person templateAge = new Person();
templateAge.age = 38;
// Executes ReadMultiple requesting 100 objects to be returned
Person[] persons_read = proxy.ReadMultiple(templateAge, 100);

ReadMultiple returns an array of objects that matches the given template, the size of the array is determained by the parameters passed to the method, in this case, the given size is 100 which means that only 100 objects will be returned by this method or less if there aren't 100 objects that matches the given template. If no size is given, all the objects that matches the given template will be returned.

TakeMultiple

Person templateAge = new Person();
templateAge.age = 38;
// Executes ReadMultiple requesting 100 objects to be returned
Person[] persons_read = proxy.TakeMultiple(templateAge, 100);

TakeMultiple has the same semantics as ReadMultiple, except that the object returned by it are also removed from the space.

WriteMultiple

When using WriteMultiple you should construct an array of objects that you would like to store inside the space.

Person[] persons = new Person[10] ;
for (int i = 0; i < 10; i++)
{
  persons[i] = new Person();
  persons[i].UserId = "011-1111111_" +i;
  persons[i].Name = "Kermit the frog" + i;
  persons[i].Age = 38 ;
  persons[i].BirthDay = "01/01/1967";
  persons[i].Height = 6.2 + i;
  persons[i].Phone = 9783698583L + i;
  persons[i].Weight = 200.5F + i;
}
Lease[] leases = proxy.WriteMultiple(persons);

UpdateMultiple

When using UpdateMultiple you should construct an array of objects that you would like to update inside the space.

Person templateAge = new Person();
templateAge.age = 38;
Person[] persons_read = proxy.ReadMultiple(templateAge);
for (int i = 0; i < persons_read.Length; i++)
{
  persons[i].Age = 41;
}
proxy.UpdateMultiple(persons_read);

The UpdateMultiple methods returns an array of updated objects in their previous state.

Iterating the Space

You can iterate the space using the GetSpaceIterator method. The GetSpaceIterator method can take a collection of templates as an argument.

object iteratorTemplate = new Person();
ISpaceIteratoriterator = proxy.GetSpaceIterator(iteratorTemplate, IteratorScope.ExistingAndFutureEntries);
foreach (Person person in iterator)
{
  Console.WriteLine("Height=" + person.height);
}

Querying the Space

You can query the space using a SQL query or an IPreparedTemplate as well. The query should be constructed and passed as the template argument to the Read, Take, ReadMultiple, TakeMultiple, Count, or Clear operations.

SqlQuery

Person personTemplate = new Person();
personTemplate.age = 21;
SqlQuery query = new SqlQuery(personTemplate, "age >= ?");
Person[] persons_read = proxy.ReadMultiple(query);

It is recommended to use a parameter-based query as seen above (?). Using a static value might reduce performance.

IPreparedTemplate

An IPreparedTemplate is an object that is constructed by the ISpaceProxy.Snapshot method and can be used to query the space as a template. This template increase the performance of the query and should be used when a repeatative query is done that uses the same template, otherwise doing Snapshot for each template will decrease performance.

Person personTemplate = new Person();
personTemplate.age = 21;
IPreparedTemplate<Person> preparedTemplate = proxy.Snapshot(personTemplate);
for(int i = 0; i < 1000000; i++)
{
  Person person = proxy.Take(preparedTemplate);
  if (person != null)
    Console.WriteLine(person.Name);
}

Clean Method

To clean all space Entries and notify templates, call the ISpaceProxy.Clean() method.

When the space is persistent using the JDBC Storage Adapter or using an indexed file, data is removed.

proxy.Clean()

Clean(Type type) Method

You can drop a class and all its instances, including its notify templates, using the proxy.Clean(Type type) method:

proxy.Clean(person.GetType());

Clear Method

To remove Entries based on a given template with or without transactions, use the ISpaceProxy.Clear() method:

proxy.Clear(new Person())

Master-Local Space

You can run the master-local topology using a local cache initialized in the .NET API proxy with the useLocalCache parameter as part of the space URL:

string spaceUrl = "jini://*/*/mySpace?useLocalCache"
ISpaceProxy proxy = SpaceProxyProviderFactory.Instance.FindSpace(spaceUrl);

For more details, refer to the Master-Local Space section.

Local View Support

You can create an object Local View using the IReadOnlySpaceProxy interface.

Construct the PONO local view as follows:

Person template = new Person();
template.name = "Kermit";
View view = new View(template, "name=?");
IReadOnlySpaceProxy localView = proxy.CreateLocalview(view);
int count = localView.Count();

For more details on Local View, refer to the Space Local View section.

Space Administration

It is possible to perform administrative tasks on the space: getting cluster member names, connecting directly to specific cluster member, retrieving or changing space state, and retrieving information regarding space types.

For more details, refer to the Space Administration using .NET section.

More in this Section

GigaSpaces.com - Legal Notice - 3rd Party Licenses - Site Map - API Docs - Forum - Downloads - Blog - White Papers - Contact Tech Writing - Gen. by Atlassian Confluence