All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.terracotta.modules.ehcache.concurrency.TCCacheLockProvider Maven / Gradle / Ivy

/*
 * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
 */
package org.terracotta.modules.ehcache.concurrency;

import net.sf.ehcache.CacheException;
import net.sf.ehcache.concurrent.CacheLockProvider;
import net.sf.ehcache.concurrent.LockType;
import net.sf.ehcache.concurrent.Sync;
import net.sf.ehcache.terracotta.TerracottaNotRunningException;

import org.terracotta.modules.ehcache.store.ValueModeHandler;
import org.terracotta.toolkit.cache.ToolkitCache;
import org.terracotta.toolkit.concurrent.locks.ToolkitLock;
import org.terracotta.toolkit.concurrent.locks.ToolkitLockType;
import org.terracotta.toolkit.concurrent.locks.ToolkitReadWriteLock;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class TCCacheLockProvider implements CacheLockProvider {

  private final ToolkitCache     backend;
  private final ValueModeHandler valueModeHandler;

  public TCCacheLockProvider(ToolkitCache backend, ValueModeHandler valueModeHandler) {
    this.backend = backend;
    this.valueModeHandler = valueModeHandler;
  }

  @Override
  public Sync getSyncForKey(Object key) {
    ToolkitReadWriteLock lock = createLock(key);
    return new TCSync(lock.writeLock(), lock.readLock());
  }

  private ToolkitReadWriteLock createLock(Object key) {
    try {
      Object portableKey = valueModeHandler.createPortableKey(key);
      return backend.createLockForKey(portableKey);
    } catch (IOException e) {
      throw new CacheException(e);
    }
  }

  private static class TCSync implements Sync {

    private final ToolkitLock writeLock;
    private final ToolkitLock readLock;

    public TCSync(ToolkitLock writeLock, ToolkitLock readLock) {
      this.writeLock = writeLock;
      this.readLock = readLock;
      if (writeLock.getLockType() != ToolkitLockType.WRITE) { throw new AssertionError(); }
      if (readLock.getLockType() != ToolkitLockType.READ) { throw new AssertionError(); }
    }

    private ToolkitLock getLockForType(LockType type) {
      switch (type) {
        case READ:
          return readLock;
        case WRITE:
          return writeLock;
      }
      throw new AssertionError("Unknown lock type - " + type);
    }

    @Override
    public void lock(LockType type) {
      try {
        getLockForType(type).lock();
      } catch (RuntimeException e) {
        handleTCNotRunningException(e);
      }
    }

    @Override
    public boolean tryLock(LockType type, long msec) throws InterruptedException {
      try {
        return getLockForType(type).tryLock(msec, TimeUnit.MILLISECONDS);
      } catch (RuntimeException e) {
        return handleTCNotRunningException(e);
      }

    }

    @Override
    public void unlock(LockType type) {
      try {
        getLockForType(type).unlock();
      } catch (RuntimeException e) {
        handleTCNotRunningException(e);
      }
    }

    @Override
    public boolean isHeldByCurrentThread(LockType type) {
      try {
        return getLockForType(type).isHeldByCurrentThread();
      } catch (RuntimeException e) {
        return handleTCNotRunningException(e);
      }
    }

    private boolean handleTCNotRunningException(RuntimeException e) {
      if (e.getClass().getSimpleName().equals("TCNotRunningException")) { throw new TerracottaNotRunningException(
                                                                                                                  "Clustered Cache is probably shutdown or Terracotta backend is down.",
                                                                                                                  e); }
      throw e;
    }


  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy