Welcome to the new Gigaspaces XAP forum. To recover your account, please follow these instructions.

Ask Your Question
0

Space Thread Synchronization

When I tried to use Gigaspaces as a caching solution, I found that it's a bit difficult to ensure that only one thread is retrieving data to fill cache at any point in time. It seems that when I use template to retrieve the data and the data is not in the cache, the second thread that tries to retrieve the data will not be blocked either even it's in the transaction. Therefore, both threads will try to update cache at the same time. Do you have any ways we can simulate a fine grain semaphore/mutex with Gigaspaces? Some other cache providers such as EHCache and Tangosol provide API to lock/unlock any given key in the same cache group to tackle this problem.

Thanks,

{quote}This thread was imported from the previous forum. For your reference, the original is [available here|http://forum.openspaces.org/thread.jspa?threadID=2132]{quote}

asked 2007-05-29 11:26:01 -0500

testy gravatar image

updated 2013-08-08 09:52:00 -0500

jaissefsfex gravatar image
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

The simple solution is the Exclusive Read Lock - see: http://www.gigaspaces.com/wiki/displa...

Shay

answered 2007-05-30 01:54:02 -0500

shay hassidim gravatar image
edit flag offensive delete link more

Comments

I tried it and it didn't work for some reason so I gave up.

testy gravatar imagetesty ( 2007-05-30 09:03:05 -0500 )edit

It must work. Are you using the latest build from the website? Can you submit your code?

Please also make sure the space schema will have this: <lease_manager> <expiration_time_interval>5000</expiration_time_interval> </lease_manager>

Shay

shay hassidim gravatar imageshay hassidim ( 2007-05-30 09:44:05 -0500 )edit

Hi Shay,

I found the problem. Read lock doesn't work if the entry doesn't exist in the space in the first place. You can try the code below. The result will be different if you comment / uncomment the line to put an entry in the map in the second line. I tried to employ read lock mechanism to ensure that I don't have two threads updating the cache at the same time. So my algorithm is to first check the cache. If the entry doesn't exist, it will then try to populate one.

{code} public void testCache() throws Exception { final IMap map = (IMap) CacheFinder.find("/./testCache?schema=mycache&versioned=false&create=true&noCache=false"); //map.put("Test","Test", 30000); Thread thread1 = new Thread() { public void run() { try { TransactionManager trManager = LocalTransactionManager.getInstance(map);

                Transaction.Created created = TransactionFactory.create(trManager, 10000);

                Transaction transaction = created.transaction;

                System.out.println("Thread-1: Start" + System.currentTimeMillis());
                try
                {
                    map.get("Test", transaction, 5000, ReadTakeModifiers.EXCLUSIVE_READ_LOCK);
                } catch (CacheTimeoutException ex)
                {
                    System.out.println("Thread-1: Timeout" + System.currentTimeMillis());
                }
                System.out.println("Thread-1: After lock" + System.currentTimeMillis());

                Thread.sleep(5000);

                transaction.commit();

                System.out.println("Thread-1: End" + System.currentTimeMillis());
                transaction.commit();
            } catch (Exception ex)
            {
            }
        }
    };
    thread1.start();
    Thread thread = new Thread()
    {

        public void run()
        {
            try
            {
                TransactionManager trManager = LocalTransactionManager.getInstance(map);

                Transaction.Created created = TransactionFactory.create(trManager, 10000);

                Transaction transaction = created.transaction;

                System.out.println("Thread-2: Start" + System.currentTimeMillis());
                try
                {
                    map.get("Test", transaction, 5000, ReadTakeModifiers.EXCLUSIVE_READ_LOCK);
                } catch (CacheTimeoutException ex)
                {
                    System.out.println("Thread-2: Timeout" + System.currentTimeMillis());
                }
                System.out.println("Thread-2: After lock" + System.currentTimeMillis());
                Thread.sleep(5000);

                transaction.commit();

                System.out.println("Thread-2: End" + System.currentTimeMillis());
                transaction.commit();
            } catch (Exception ex)
            {
            }
        }
    };
    thread.start();
    thread1.join();
    thread.join();
}{code}
testy gravatar imagetesty ( 2007-08-23 15:06:02 -0500 )edit

We will be releasing soon 6.0.1. (in few weeks) the following as part of Open Spaces.
Please note GigaMap allrady exists as part of 6.0 1855 - the new methods as part of 6.0.1 are lock , unlock , isLocked, putAndUnlock:

package org.openspaces.core;
import com.j_spaces.javax.cache.Cache;
import com.j_spaces.map.IMap;
import net.jini.core.transaction.Transaction;
import org.openspaces.core.map.LockHandle;
import org.openspaces.core.transaction.TransactionProvider;
import java.util.Map;
/**
 * Provides a simpler interface on top of {@link com.j_spaces.map.IMap} and
 * {@link com.j_spaces.javax.cache.Cache} implementation.
 *
 * <p>Though this interface has a single implementation it is still important to work against the
 * interface as it allows for simpler testing and mocking.
 *
 * <p>Transaction management is implicit and works in a declarative manner. Operations do not accept a
 * transaction object, and will automatically use the {@link TransactionProvider} in order to acquire
 * the current running transaction. If there is no current running transaction the operation will be
 * executed without a transaction.
 *
 * @author kimchy
 */
public interface GigaMap extends Map, Cache {
    /**
     * Returns the <code>IMap</code> used by this GigaMap implementation to delegate
     * different space operations.
     *
     * <p>Allows to execute map operations that are not exposed by this interface, as well as using
     * it as a parameter to other low level GigaSpace components.
     *
     * <p>If a transaction object is required for low level operations (as low level operations do not
     * have declarative transaction ex) the {@link #getTxProvider()} should be used to acquire the
     * current running transaction.
     */
    IMap getMap();
    /**
     * Returns the transaction provider allowing to access the current running transaction. Allows
     * to execute low level {@link IMap} operations that requires explicit
     * transaction object.
     */
    TransactionProvider getTxProvider();
    /**
     * Returns the current running transaction. Can be <code>null</code> if no transaction is in progress.
     */
    Transaction getCurrentTransaction();
    /**
     * Returns the object that is associated with <code>key</code> in this cache.
     * Client will wait at most <code>waitForResponse</code> milliseconds for
     * get call to return.
     *
     * @param key             key whose associated value is to be returned.
     * @param waitForResponse time to wait for response
     * @return Returns the object that is associated with the key
     */
    Object get(Object key, long waitForResponse);
    /**
     * Returns the object that is associated with <code>key</code> in this cache.
     * Client will wait at most <code>waitForResponse</code> milliseconds for
     * get call to return.
     *
     * @param key             key whose associated value is to be returned.
     * @param waitForResponse time to wait for response
     * @param modifiers       one or a union of {@link com.j_spaces.core.client.ReadModifiers}.
     * @return Returns the object that is associated with the key
     */
    Object get(Object key, long waitForResponse, int modifiers);
    /**
     * Puts <code>value</code> to the cache with specified <code>key</code> for
     * <code>timeToLive</code> milliseconds to live in the cache.
     *
     * @param key        key for the <code>value</code>
     * @param value      object(~ entry)
     * @param timeToLive time to keep object in this cache, in milliseconds
     * @return previous value associated with specified key, or <tt>null</tt>
     *         if there was no mapping for key ...
(more)
shay hassidim gravatar imageshay hassidim ( 2007-08-23 15:24:05 -0500 )edit

Awesome. That's exactly what I need. It will make the API closer to Tangosol API. Nice! Can't wait for it. :)

How will the lock work? Will it has reentrant feature? Will the lock apply to the whole cluster (if I ever change to cluster mode :P)

testy gravatar imagetesty ( 2007-08-23 15:31:02 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2007-05-29 11:26:01 -0500

Seen: 51 times

Last updated: May 30 '07