![]() |
Copyright © TIBCO Software Inc. All Rights Reserved |
Your application can store data into a space by using the space’s put method and passing it a tuple as its argument. Once the tuple is in the space, it can be accessed by any other application using that space. Existing entries are replaced with new ones, which means that if there was already a tuple with the same key field values stored in the space, it is overwritten by the new tuple.
• Fields marked as nullable need not be present in the tuple, but if they are present, their type must match or be able to be upcasted.
• Get Method A tuple space implements the associative memory paradigm and allows the application to get a complete copy of the tuple associated with specific values of it's key fields.This is done by using the spaces’s get method and passing a tuple containing appropriate key field values for that space. If a tuple with matching values for its key fields is currently stored in the space, the value of the status in the result object returned by the get method is equal to OK. If no tuple in the space has matching values for the key fields, the value of the status in the result object is NULL.
• Callback Query Method You can create listeners on a space that invoke a user query callback function as filtered initial data and new data are pushed from the space to the listeners. For more information on listeners, see Listening to Changes.
• Space Browser Query Method You can also create space browsers on the space that let users retrieve filtered data initially stored in the space and retrieve new data tuple by tuple and on demand. For more information on space browsers, see Using Space Browsers.
• You can remove tuples from a space by using the space’s take method and passing a tuple containing the appropriate key fields for that space. The take method behaves exactly like an atomic get-and-remove: If a tuple with matching values for its key fields is currently stored in the space:
• The status value of the result passed to the take operation is be equal to OK.Otherwise (if there is no tuple with matching values for its key fields currently stored in the space), there is nothing to take, and the result's status is equal to NULL. Since ActiveSpaces provides immediate consistency, you have a guarantee that if two separate applications issue a take for the same entry at the same time, only one of them will see its take operation succeed; the other one will see its result's status be equal to NULL.You can also perform a take operation on all or a filtered subset of the tuples contained in a space by using a space browser. For more information on space browsers, see Using Space Browsers.
1. An optimistic approach is best when the likelihood of having a collision is low. In this case, you should make use of the space’s update method, which is an atomic compare and set operation.This operation takes two parameters, one representing the old data that was retrieved from the space, and another one representing the new version of that data. If the old data is still in the space at the time this operation is invoked, then the operation will succeed. However, if the data in the space was changed in any way, the operation will fail, which indicates that your application should refresh its view of the data and re-apply the change.
2. A pessimistic approach to the concurrent update problem is best when there is a high likelihood of more than one process trying to update the same tuple at the same time. In this case, application programmers should first attempt to lock the tuple, and only apply their update to it after having obtained the lock. Locking is described in the following section.The space's lock function takes a tuple representing the key as an input parameter and can optionally return what is stored in the space at that key (if there is anything) just as a get operation allows you to lock tuples in the space. The space’s lock method is an atomic get and lock, and takes the same argument as the get method.A locked key is read-only for all space members except the member that has locked it. Only one member can lock a specific key at any given time. If a member other than the lock owner tries to overwrite, take, update, or lock a locked key, that operation may block until the lock is cleared. If you want to implement this behavior, set a lock wait value using the space's LockWait attribute.Finally, you can specify a maximum time to leave for locks in a space: if a lock is held for longer than the value specified in the space's LockTTL attribute, it is then automatically cleared. Locks are also automatically cleared when the application that has created the lock leaves the metaspace or crashes.ActiveSpaces provides another method of interacting with spaces—space browsers. You can use space browsers when working with groups of tuples, rather than with the single tuple key lookup of the space’s get method. Space browsers allow you to iterate through a series of tuples by invoking the space browser’s next method. However, unlike a traditional iterator that works only on a snapshot of the data to be iterated through, the space browser is continuously updated according to the changes in the data contained in the space being browsed.
• Space Browsers Allow your application to not only retrieve the next tuple in a series of tuples, but also to operate directly on the tuple. You can implement: three types of space browser:
− Get Browser Retrieves the next tuple in a series of tuples.
− Take Browser Retrieves the next tuple in a series of tuples and consumes it.
− Lock Browser Retrieves the next tuple in a series of tuples and locks it.
• Event Browsers Allow you to iterate through the stream of events (changes) occurring in the space.
• Space browsers and event browsers both have two methods, next() and stop(). However, a space browser's next() method returns a SpaceEntry, while the event browser's next() method returns a SpaceEvent.
• A space browser also has a getType() method, which the event browser does not have.
• A space browser's next method will do a get, take, or lock, according to the browser's type: GetBrowser, TakeBrowser, or LockBrowser.
− The Get Browser’s next() method does a get on the next tuple to browse (very much like a regular iterator).
− The Take Browser’s next() method atomically retrieves and removes the next tuple currently available to take from the space.
− The Lock Browser’s next() method atomically retrieves and locks the next tuple currently available to lock in the space).
•
• The SpaceEvent objects returned by the event browser’s next method optionally include the initial values, that is, what was in the space at the time the event browser was created.
• The initial values are presented as a continuously updated string of PUT events preceding the stream of events that happen after the creation of the event browser. Event browsers allow you to see deletions and expirations of tuples they have already iterated through.Since a space browser is continuously updated, it does not have a next() method; instead, it has a timeout: the amount of time the user is willing for the next call to block in the event that there is nothing to get, take, or lock at the time it is invoked (but there may be in the future).Continuously updating tuples means that if multiple take browsers created on the same space are used to take tuples from the space using next, a particular tuple is only taken by one of the space browsers, effectively allowing the use of a space as a tuple queue.A space browser can have either time scope or distribution scope, which are defined by setting the values of fields in the browser’s BrowserDef object:Time Scope The time scope can be used to narrow the period of time of interest.
• snapshot means that the browser starts with all the tuples in the space at the time the browser is created (or initial values), but is not updated with new tuples that are put into the space after that moment.
Note that the browser's timeout value is ignored when the time scope is snapshot, because in this case the browser will only iterate through a finite set of tuples (only those that are present in the space at the time of the browser's creation).
• new means that the browser starts empty, and is updated only with tuples (or associated events) put into the space after the moment of the browser’s creation.
• all means that the browser starts with all the tuples in the space, and is continuously updated with new tuples.
• new_events is applicable only to event browsers, and means that the browser starts empty and is updated with all the events generated by the space after the moment of the browser's creation (unlike new, which would only deliver events associated with entries put in the space after the browser's creation time)Distribution Scope The distribution scope can be used to narrow down the set of tuples or events being browsed.
• all is used to browse over all the tuples (or associated events) in the space
• seeded is used to browse only over the tuples (or associated events) actually distributed to the member creating the browserActiveSpaces can proactively notify applications of changes to the tuples stored in a space. Users can invoke the metaspace or space’s listen method to obtain a listener on spaces for receiving event notifications. There are five types of listeners:
1. PutListener The PutListener’s onPut method is invoked whenever a SpaceEntry is inserted, updated, or overwritten in the space.
2. TakeListener The PutListener’s onTake method is invoked whenever a SpaceEntry is removed from the space.
3. ExpireListener The PutListener’s onExpire method is invoked whenever a SpaceEntry in the space has reached its time to live (TTL) and has expired.
4. SeedListener The PutListener’s onSeed method is invoked whenever there is redistribution after an existing seeder leaves the space and now the local node is seeding additional entries. This is only applicable if the listener distribution scope is SEEDED.
5. UnseedListener The PutListener’s onUnseed method is invoked whenever there is redistribution after a new seeder joins the space and now the local node stops seeding some of the entries. Only applicable if the listener distribution scope is SEEDED.In the ActiveSpaces Java API, listeners must implement at least one of the listener interfaces shown above. Listeners are activated using the listen method of the Metaspace or Space class.
•
•
•
•
• In the C API, you must call the tibasListener_Create function and specify a single callback function that is invoked for all event types. The new tibasListener object created by tibasListenerCreate is then activated using the tibasMetaspace_Listen or tibasSpace_Listen functions. The callback function is passed a tibasSpaceEvent object whose type can be determined by invoking the tibasSpaceEvent_GetType function.
• TIBAS_EVENT_PUT when a tuple is inserted, overwritten, or updated.
• TIBAS_EVENT_TAKE when a tuple is taken or removed.
• TIBAS_EVENT_EXPIRE when a tuple reaches the end of its time to live and expires from the space.
• TIBAS_EVENT_SEED when there is redistribution after a seeder joins or leaves, and the local node is seeding or unseeding. This is only applicable if the listener distribution scope is SEEDED.
• TIBAS_EVENT_UNSEED when there is redistribution after a seeder joins or leaves, and the local node is seeding or unseeding. This is only applicable if the listener’s distribution scope is SEEDED.You can also specify that a current snapshot of the entries stored in the space (sometimes referred to as initial values) is prepended to the stream of events. In this case, the initial values of all the tuples contained in the space at the listener’s creation time are seen as space events of type PUT preceding the current stream of events.A filter string can be seen as what would follow the where clause in a select * from Space where… statement.Table 5 shows the operators that are supported in the ActiveSpaces filters:
nor, as in “age NOT 30 NOR 40“ See ASQuery (Java Only) for examples of filter queries that utilize strings enclosed within double quotes.Table 5 indicates several filter formats for regular expressions (regex values). For regular expressions, ActiveSpaces uses the syntax for Perl Compatible Regular Expressions (PCRE).Table 6 shows the formats for values used in filters.
Table 6 Formats for Filter Values
Compare the two approaches to updating the value of a field on all of the entries stored in a space.
• One approach is to create a browser of distribution scope all on the node to serially retrieve and update each entry in the space one entry at a time.
• Another approach is to use remote invocation to invoke a function on all of the Space seeders in parallel. The remote function creates a browser of distribution scope seeded, to iterate only over the entries that it seeds and, therefore, avoid incurring a network round-trip.Remote space invocation is available for all language bindings. It only takes care of function or method invocation and does not take care of distributing the code to the space members; for example, the function or method being invoked must be available in the CLASSPATH of all space members.
• invoke Invokes a method only on the member seeding the key passed as an argument to the call.
• invokeMember Invokes a method only on the Space member being specified as an argument to the call.
• invokeMembers Invokes a method on all of the Space members.
• InvokeSeeders Invokes a method on all of the seeder members of the Space.The invoke method takes a key tuple, which gets passed to the method implementing the Invocable (rather than MemberInvocable) interface in the class; the method gets invoked regardless whether an entry has been stored in the space at that key.Both the Invocable and the MemberInvocable interfaces return a tuple, but the remote space invocation methods return either an InvokeResult (invoke and invokeMember) or an InvokeResultList (invokeMembers and invokeSeeders), from which the Tuple can be retrieved using the getResult (or getResults) method.
ActiveSpaces Enterprise Edition allows you to atomically perform sets of space operations using transactions. Transactions can span multiple spaces, but not multiple metaspaces. A transaction starts when an individual thread in an application creates a transaction, and terminates when either commit or rollback is invoked, at which point all space operations performed by that thread are either validated or canceled. Pending transactions may be rolled back automatically if they exceed an optional TTL (time-to-live) threshold, or when the member creating them leaves the metaspace.Transactions can also be moved from one thread to another using the releaseTransaction() and takeTransaction() methods.In ActiveSpaces 2.0, the only supported read isolation level is READ_COMMITTED. This isolation level applies only to your view of data modified by the transactions of other applications and threads. This means that whether in a transaction or not, you will not see uncommitted data from other transactions, but if you yourself are in a transaction you will see your own uncommitted data.ActiveSpaces has an implied write isolation level of UNCOMMITTED, meaning that any entry potentially modified by a pending transactional operation appears to be locked for other users of the space (in which case the space’s LockWait attribute will apply).ActiveSpaces is a peer-to-peer distributed in-memory tuple space. This means that the tuples are stored in the memory of a cluster of machines working together to offer the storage of tuples. There is no central server used for the coordination of operations, but rather any number of peers working together to offer a common service.To store tuples, ActiveSpaces uses a distributed hashing algorithm applied on the values of the key fields of the tuple to distribute the seeding of the tuples as evenly as possible (that is, their storing and management) over a set of peers. This means that:
• Given the current set of seeders (any process joined to a particular space as a seeder), any participating member of the space knows where to find the tuple associated with a particular set of key field values.
• A single application can only connect once to the same metaspace. In other words, you cannot invoke connect on the same metaspace twice and have two connections to the same metaspace from the same process. However, you can connect simultaneously to several different metaspaces, and it is possible to get a copy of a currently connected metaspace object by using the ASCommon object's methods.
• When a process joins a space through its metaspace connection, it will only join a space once. If you call getSpace twice, the process will join the space the first time you call it, but the second getSpace call will return to you a new reference to the previously created space object. If you specify a different role the second time you call getSpace, then it will adjust your role on that space, but this does not mean that you have joined the same space twice.
• The space object is reference-counted and the space will actually be left by the process only when the space object's leave method is invoked an equal number of times to the Metaspace's getSpace method for that particular space.
![]() |
Copyright © TIBCO Software Inc. All Rights Reserved |