/*
* Copyright (c) 2008-2012, Hazel Bilisim Ltd. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.impl;
import com.hazelcast.cluster.AbstractRemotelyProcessable;
import com.hazelcast.cluster.ClusterImpl;
import com.hazelcast.config.Config;
import com.hazelcast.config.MapStoreConfig;
import com.hazelcast.config.XmlConfigBuilder;
import com.hazelcast.core.*;
import com.hazelcast.impl.CMap.InitializationState;
import com.hazelcast.impl.executor.ParallelExecutor;
import com.hazelcast.jmx.ManagementService;
import com.hazelcast.logging.ILogger;
import com.hazelcast.logging.LoggingService;
import com.hazelcast.nio.DataSerializable;
import com.hazelcast.nio.SerializationHelper;
import com.hazelcast.partition.PartitionService;
import com.hazelcast.util.ResponseQueueFactory;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import static com.hazelcast.core.LifecycleEvent.LifecycleState.STARTED;
import static com.hazelcast.core.LifecycleEvent.LifecycleState.STARTING;
@SuppressWarnings("SynchronizationOnStaticField")
public class FactoryImpl implements HazelcastInstance {
final static ConcurrentMap<String, FactoryImpl> factories = new ConcurrentHashMap<String, FactoryImpl>(5);
private static final AtomicInteger factoryIdGen = new AtomicInteger();
private static final Object INIT_LOCK = new Object();
final ConcurrentMap<String, HazelcastInstanceAwareInstance> proxiesByName = new ConcurrentHashMap<String, HazelcastInstanceAwareInstance>(1000);
final ConcurrentMap<ProxyKey, HazelcastInstanceAwareInstance> proxies = new ConcurrentHashMap<ProxyKey, HazelcastInstanceAwareInstance>(1000);
final MProxy locksMapProxy;
final ConcurrentMap<String, ExecutorService> executorServiceProxies = new ConcurrentHashMap<String, ExecutorService>(2);
final CopyOnWriteArrayList<InstanceListener> lsInstanceListeners = new CopyOnWriteArrayList<InstanceListener>();
final String name;
final ProxyFactory proxyFactory;
final HazelcastInstanceProxy hazelcastInstanceProxy;
final ManagementService managementService;
final ILogger logger;
final LifecycleServiceImpl lifecycleService;
public final Node node;
volatile boolean restarted = false;
public static Set<HazelcastInstance> getAllHazelcastInstanceProxies() {
final Collection<FactoryImpl> factoryColl = factories.values();
final Set<HazelcastInstance> instanceSet = new HashSet<HazelcastInstance>(factoryColl.size());
for (FactoryImpl factoryImpl : factoryColl) {
if (factoryImpl.getLifecycleService().isRunning()) {
instanceSet.add(factoryImpl.hazelcastInstanceProxy);
}
}
return instanceSet;
}
public static HazelcastInstanceProxy getHazelcastInstanceProxy(String instanceName) {
synchronized (INIT_LOCK) {
final FactoryImpl factory = factories.get(instanceName);
return factory != null ? factory.hazelcastInstanceProxy : null;
}
}
public static HazelcastInstanceProxy newHazelcastInstanceProxy(Config config) {
if (config == null) {
config = new XmlConfigBuilder().build();
}
String name = config.getInstanceName();
if (name == null || name.trim().length() == 0) {
name = "_hzInstance_" + factoryIdGen.incrementAndGet() + "_" + config.getGroupConfig().getName();
return newHazelcastInstanceProxy(config, name);
} else {
synchronized (INIT_LOCK) {
if (factories.containsKey(name)) {
throw new DuplicateInstanceNameException("HazelcastInstance with name '" + name + "' already exists!");
}
return newHazelcastInstanceProxy(config, name);
}
}
}
private static HazelcastInstanceProxy newHazelcastInstanceProxy(Config config, String instanceName) {
FactoryImpl factory = null;
try {
factory = new FactoryImpl(instanceName, config);
factories.put(instanceName, factory);
boolean firstMember = (factory.node.getClusterImpl().getMembers().iterator().next().localMember());
int initialWaitSeconds = factory.node.groupProperties.INITIAL_WAIT_SECONDS.getInteger();
if (initialWaitSeconds > 0) {
try {
Thread.sleep(initialWaitSeconds * 1000);
if (firstMember) {
final ConcurrentMapManager concurrentMapManager = factory.node.concurrentMapManager;
concurrentMapManager.enqueueAndReturn(new Processable() {
public void process() {
concurrentMapManager.partitionManager.firstArrangement();
}
});
} else {
Thread.sleep(4 * 1000);
}
} catch (InterruptedException ignored) {
}
}
int initialMinClusterSize = factory.node.groupProperties.INITIAL_MIN_CLUSTER_SIZE.getInteger();
while (factory.node.getClusterImpl().getMembers().size() < initialMinClusterSize) {
try {
//noinspection BusyWait
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
}
if (initialMinClusterSize > 0) {
if (firstMember) {
final ConcurrentMapManager concurrentMapManager = factory.node.concurrentMapManager;
concurrentMapManager.enqueueAndReturn(new Processable() {
public void process() {
concurrentMapManager.partitionManager.firstArrangement();
}
});
} else {
Thread.sleep(4 * 1000);
}
factory.logger.log(Level.INFO, "HazelcastInstance starting after waiting for cluster size of "
+ initialMinClusterSize);
}
factory.lifecycleService.fireLifecycleEvent(STARTED);
return factory.hazelcastInstanceProxy;
} catch (Throwable t) {
if (factory != null) {
factory.logger.log(Level.SEVERE, t.getMessage(), t);
}
Util.throwUncheckedException(t);
return null;
}
}
public int hashCode() {
return name.hashCode();
}
public boolean equals(Object o) {
if (o == null) return false;
return o == this || name.equals(((FactoryImpl) o).getName());
}
public HazelcastInstanceProxy getHazelcastInstanceProxy() {
return hazelcastInstanceProxy;
}
public static class HazelcastInstanceProxy extends HazelcastInstanceAwareObject implements HazelcastInstance {
public HazelcastInstanceProxy() {
}
public HazelcastInstanceProxy(FactoryImpl factory) {
this.hazelcastInstance = factory;
}
public FactoryImpl getFactory() {
return (FactoryImpl) hazelcastInstance;
}
public String getName() {
return hazelcastInstance.getName();
}
public void shutdown() {
hazelcastInstance.shutdown();
}
public void restart() {
hazelcastInstance.restart();
}
public Collection<Instance> getInstances() {
return hazelcastInstance.getInstances();
}
public ExecutorService getExecutorService() {
return hazelcastInstance.getExecutorService();
}
public ExecutorService getExecutorService(String name) {
return hazelcastInstance.getExecutorService(name);
}
public Cluster getCluster() {
return hazelcastInstance.getCluster();
}
public IdGenerator getIdGenerator(String name) {
return hazelcastInstance.getIdGenerator(name);
}
public AtomicNumber getAtomicNumber(String name) {
return hazelcastInstance.getAtomicNumber(name);
}
public Transaction getTransaction() {
return hazelcastInstance.getTransaction();
}
public <K, V> IMap<K, V> getMap(String name) {
return hazelcastInstance.getMap(name);
}
public <E> IQueue<E> getQueue(String name) {
return hazelcastInstance.getQueue(name);
}
public <E> ITopic<E> getTopic(String name) {
return hazelcastInstance.getTopic(name);
}
public <E> ISet<E> getSet(String name) {
return hazelcastInstance.getSet(name);
}
public <E> IList<E> getList(String name) {
return hazelcastInstance.getList(name);
}
public <K, V> MultiMap<K, V> getMultiMap(String name) {
return hazelcastInstance.getMultiMap(name);
}
public ILock getLock(Object key) {
return hazelcastInstance.getLock(key);
}
public ICountDownLatch getCountDownLatch(String name) {
return hazelcastInstance.getCountDownLatch(name);
}
public ISemaphore getSemaphore(String name) {
return hazelcastInstance.getSemaphore(name);
}
public void addInstanceListener(InstanceListener instanceListener) {
hazelcastInstance.addInstanceListener(instanceListener);
}
public void removeInstanceListener(InstanceListener instanceListener) {
hazelcastInstance.removeInstanceListener(instanceListener);
}
public Config getConfig() {
return hazelcastInstance.getConfig();
}
public PartitionService getPartitionService() {
return hazelcastInstance.getPartitionService();
}
public ClientService getClientService() {
return hazelcastInstance.getClientService();
}
public LoggingService getLoggingService() {
return hazelcastInstance.getLoggingService();
}
public LifecycleService getLifecycleService() {
return hazelcastInstance.getLifecycleService();
}
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (obj instanceof HazelcastInstanceProxy) {
HazelcastInstanceProxy that = (HazelcastInstanceProxy) obj;
return hazelcastInstance.equals(that.hazelcastInstance);
}
return false;
}
public int hashCode() {
return hazelcastInstance.hashCode();
}
}
public String getName() {
return name;
}
public static void shutdownAll() {
Collection<FactoryImpl> colFactories = factories.values();
for (FactoryImpl factory : colFactories) {
factory.shutdown();
}
factories.clear();
shutdownManagementService();
ThreadContext.shutdownAll();
}
public static void kill(HazelcastInstanceProxy hazelcastInstanceProxy) {
FactoryImpl factory = hazelcastInstanceProxy.getFactory();
factory.managementService.unregister();
factory.proxies.clear();
for (ExecutorService esp : factory.executorServiceProxies.values()) {
esp.shutdown();
}
factory.node.shutdown(true, true);
factories.remove(factory.getName());
if (factories.size() == 0) {
shutdownManagementService();
}
}
public static void shutdown(HazelcastInstanceProxy hazelcastInstanceProxy) {
FactoryImpl factory = hazelcastInstanceProxy.getFactory();
factory.managementService.unregister();
factories.remove(factory.getName());
if (factories.size() == 0) {
shutdownManagementService();
}
factory.proxies.clear();
factory.node.shutdown(false, true);
for (ExecutorService esp : factory.executorServiceProxies.values()) {
esp.shutdown();
}
}
private static void shutdownManagementService() {
ManagementService.shutdown();
}
public FactoryImpl(String name, Config config) {
this.name = name;
node = new Node(this, config);
proxyFactory = node.initializer.getProxyFactory();
logger = node.getLogger(FactoryImpl.class.getName());
lifecycleService = new LifecycleServiceImpl(FactoryImpl.this);
hazelcastInstanceProxy = new HazelcastInstanceProxy(this);
locksMapProxy = proxyFactory.createMapProxy(Prefix.MAP_HAZELCAST + "Locks");
lifecycleService.fireLifecycleEvent(STARTING);
node.start();
if (!node.isActive()) {
throw new IllegalStateException("Node failed to start!");
}
final Set<Member> members = node.getClusterImpl().getMembers();
if (members.size() > 1) {
Member target = null;
for (Member member : members) {
if (!member.isLiteMember() && !member.localMember()) {
target = member;
break;
}
}
if (target != null) {
DistributedTask task = new DistributedTask(new GetAllProxyKeysCallable(), target);
Future f = getExecutorService().submit(task);
try {
final Set<ProxyKey> proxyKeys = (Set<ProxyKey>) f.get(10, TimeUnit.SECONDS);
for (final ProxyKey proxyKey : proxyKeys) {
if (!proxies.containsKey(proxyKey)) {
node.clusterService.enqueueAndReturn(new Processable() {
public void process() {
createProxy(proxyKey);
}
});
}
}
} catch (Exception e) {
logger.log(Level.WARNING, e.getMessage(), e);
}
}
}
managementService = new ManagementService(this);
managementService.register();
}
public Set<String> getLongInstanceNames() {
return proxiesByName.keySet();
}
@Override
public String toString() {
return "HazelcastInstance {name='" + name + "'}";
}
public Config getConfig() {
return node.getConfig();
}
public Collection<Instance> getInstances() {
return new ArrayList<Instance>(proxies.values());
}
public Collection<HazelcastInstanceAwareInstance> getProxies() {
initialChecks();
return proxies.values();
}
public ExecutorService getExecutorService() {
initialChecks();
return getExecutorService("default");
}
public ExecutorService getExecutorService(String name) {
if (name == null) throw new IllegalArgumentException("ExecutorService name cannot be null");
initialChecks();
name = Prefix.EXECUTOR_SERVICE + name;
ExecutorService executorServiceProxy = executorServiceProxies.get(name);
if (executorServiceProxy == null) {
executorServiceProxy = proxyFactory.createExecutorServiceProxy(name);
ExecutorService old = executorServiceProxies.putIfAbsent(name, executorServiceProxy);
if (old != null) {
executorServiceProxy = old;
}
}
return executorServiceProxy;
}
public ClusterImpl getCluster() {
initialChecks();
return node.getClusterImpl();
}
public IdGenerator getIdGenerator(String name) {
return (IdGenerator) getOrCreateProxyByName(Prefix.IDGEN + name);
}
public AtomicNumber getAtomicNumber(String name) {
return (AtomicNumber) getOrCreateProxyByName(Prefix.ATOMIC_NUMBER + name);
}
public ICountDownLatch getCountDownLatch(String name) {
return (ICountDownLatch) getOrCreateProxyByName(Prefix.COUNT_DOWN_LATCH + name);
}
public ISemaphore getSemaphore(String name) {
return (ISemaphore) getOrCreateProxyByName(Prefix.SEMAPHORE + name);
}
public Transaction getTransaction() {
initialChecks();
ThreadContext threadContext = ThreadContext.get();
threadContext.setCurrentFactory(this);
TransactionImpl txn = threadContext.getCallContext().getTransaction();
if (txn == null) {
txn = proxyFactory.createTransaction();
threadContext.getCallContext().setTransaction(txn);
}
return txn;
}
public PartitionService getPartitionService() {
return node.concurrentMapManager.partitionServiceImpl;
}
public ClientService getClientService() {
return node.clientService;
}
public LoggingService getLoggingService() {
return node.loggingService;
}
public LifecycleService getLifecycleService() {
return lifecycleService;
}
public void restart() {
lifecycleService.restart();
}
public void shutdown() {
lifecycleService.shutdown();
}
public <K, V> IMap<K, V> getMap(String name) {
return (IMap<K, V>) getOrCreateProxyByName(Prefix.MAP + name);
}
public <E> IQueue<E> getQueue(String name) {
return (IQueue) getOrCreateProxyByName(Prefix.QUEUE + name);
}
public <E> ITopic<E> getTopic(String name) {
return (ITopic<E>) getOrCreateProxyByName(Prefix.TOPIC + name);
}
public <E> ISet<E> getSet(String name) {
return (ISet<E>) getOrCreateProxyByName(Prefix.SET + name);
}
public <E> IList<E> getList(String name) {
return (IList<E>) getOrCreateProxyByName(Prefix.AS_LIST + name);
}
public <K, V> MultiMap<K, V> getMultiMap(String name) {
return (MultiMap<K, V>) getOrCreateProxyByName(Prefix.MULTIMAP + name);
}
public ILock getLock(Object key) {
return (ILock) getOrCreateProxy(new ProxyKey("lock", key));
}
public Object getOrCreateProxyByName(final String name) {
Object proxy = proxiesByName.get(name);
if (proxy == null) {
proxy = getOrCreateProxy(new ProxyKey(name, null));
}
checkInitialization(proxy);
return proxy;
}
public Object getOrCreateProxy(final ProxyKey proxyKey) {
initialChecks();
Object proxy = proxies.get(proxyKey);
if (proxy == null) {
proxyFactory.checkProxy(proxyKey);
proxy = createInstanceClusterWide(proxyKey);
}
return proxy;
}
private void checkInitialization(Object proxy) {
if (proxy instanceof MProxy) {
MProxy mProxy = (MProxy) proxy;
CMap cmap = node.concurrentMapManager.getMap(mProxy.getLongName());
if (cmap == null) {
logger.log(Level.WARNING, "CMap[" + mProxy.getLongName() + "] has not been created yet! Initialization attempt failed!");
return;
}
if (!cmap.isMapForQueue() && cmap.initState.notInitialized()) {
while (!node.concurrentMapManager.partitionServiceImpl.allPartitionsOwned()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
}
synchronized (cmap.getInitLock()) {
if (cmap.initState.notInitialized()) {
final MapStoreConfig mapStoreConfig = cmap.mapConfig.getMapStoreConfig();
if (mapStoreConfig != null && mapStoreConfig.isEnabled()) {
cmap.initState = InitializationState.INITIALIZING;
try {
ExecutorService es = getExecutorService();
final Set<Member> members = new HashSet<Member>(getCluster().getMembers());
members.remove(node.localMember);
final MultiTask task = new MultiTask(new InitializeMap(mProxy.getName()), members);
es.execute(task);
if (cmap.loader != null) {
Set keys = cmap.loader.loadAllKeys();
if (keys != null) {
int count = 0;
Queue<Set> chunks = new LinkedList<Set>();
Set ownedKeys = new HashSet();
PartitionService partitionService = getPartitionService();
for (Object key : keys) {
Member owner = partitionService.getPartition(key).getOwner();
if (owner == null || owner.localMember()) {
ownedKeys.add(key);
count++;
if (ownedKeys.size() >= node.groupProperties.MAP_LOAD_CHUNK_SIZE.getInteger()) {
chunks.add(ownedKeys);
ownedKeys = new HashSet();
}
}
}
chunks.add(ownedKeys);
loadChunks(mProxy, cmap, chunks);
logger.log(Level.INFO, node.address + "[" + mProxy.getName() + "] loaded " + count + " in total.");
}
}
task.get();
} catch (Throwable e) {
if (node.isActive()) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
}
}
cmap.initState = InitializationState.INITIALIZED;
}
}
}
}
private void loadChunks(final MProxy mProxy, final CMap cmap, final Queue<Set> chunks) throws InterruptedException {
if (chunks.size() > 0) {
ParallelExecutor es = node.executorManager.getMapLoaderExecutorService();
final CountDownLatch latch = new CountDownLatch(chunks.size());
for (final Set chunk : chunks) {
es.execute(new Runnable() {
public void run() {
if (chunk == null) return;
try {
loadKeys(mProxy, cmap, chunk);
} catch (Exception e) {
logger.log(Level.SEVERE, "Initial loading failed.", e);
} finally {
latch.countDown();
}
}
});
}
latch.await();
}
}
private void loadKeys(MProxy mProxy, CMap cmap, Set keys) {
if (keys.size() > 0) {
Map map = cmap.loader.loadAll(keys);
if (map != null && map.size() > 0) {
Set<Map.Entry> entries = map.entrySet();
for (Map.Entry entry : entries) {
mProxy.putTransient(entry.getKey(), entry.getValue(), 0, null);
}
}
}
}
public static class InitializeMap implements Callable<Boolean>, DataSerializable, HazelcastInstanceAware {
String name;
private transient FactoryImpl factory = null;
public InitializeMap(String name) {
this.name = name;
}
public InitializeMap() {
}
public Boolean call() throws Exception {
factory.getMap(name).getName();
return Boolean.TRUE;
}
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
this.factory = (FactoryImpl) hazelcastInstance;
}
public void writeData(DataOutput out) throws IOException {
out.writeUTF(name);
}
public void readData(DataInput in) throws IOException {
name = in.readUTF();
}
}
public void initialChecks() {
ThreadContext.get().setCurrentFactory(FactoryImpl.this);
while (node.isActive() && lifecycleService.paused.get()) {
try {
//noinspection BusyWait
Thread.sleep(100);
} catch (InterruptedException e) {
return;
}
}
if (!node.isActive()) throw new IllegalStateException("Hazelcast Instance is not active!");
}
public void destroyProxy(final ProxyKey proxyKey) {
proxiesByName.remove(proxyKey.name);
Instance proxy = proxies.remove(proxyKey);
if (proxy != null) {
String name = proxyKey.name;
if (name.startsWith(Prefix.QUEUE)) {
node.blockingQueueManager.destroy(name);
} else if (name.startsWith(Prefix.MAP)) {
node.concurrentMapManager.destroy(name);
} else if (name.startsWith(Prefix.MAP_BASED)) {
node.concurrentMapManager.destroy(name);
} else if (name.startsWith(Prefix.TOPIC)) {
node.topicManager.destroy(name);
}
logger.log(Level.FINEST, "Instance destroyed " + proxyKey);
fireInstanceDestroyEvent(proxy);
}
}
// should only be called from service thread!!
public Object createProxy(ProxyKey proxyKey) {
node.clusterManager.checkServiceThread();
boolean created = false;
HazelcastInstanceAwareInstance proxy = proxies.get(proxyKey);
if (proxy == null) {
created = true;
String name = proxyKey.name;
if (name.startsWith(Prefix.QUEUE)) {
proxy = proxyFactory.createQueueProxy(name);
node.blockingQueueManager.getOrCreateBQ(name);
} else if (name.startsWith(Prefix.TOPIC)) {
proxy = proxyFactory.createTopicProxy(name);
node.topicManager.getTopicInstance(name);
} else if (name.startsWith(Prefix.MAP)) {
proxy = proxyFactory.createMapProxy(name);
node.concurrentMapManager.getOrCreateMap(name);
} else if (name.startsWith(Prefix.AS_LIST)) {
proxy = proxyFactory.createListProxy(name);
} else if (name.startsWith(Prefix.MULTIMAP)) {
proxy = proxyFactory.createMultiMapProxy(name);
node.concurrentMapManager.getOrCreateMap(name);
} else if (name.startsWith(Prefix.SET)) {
proxy = proxyFactory.createSetProxy(name);
} else if (name.startsWith(Prefix.ATOMIC_NUMBER)) {
proxy = proxyFactory.createAtomicNumberProxy(name);
} else if (name.startsWith(Prefix.IDGEN)) {
proxy = proxyFactory.createIdGeneratorProxy(name);
} else if (name.startsWith(Prefix.SEMAPHORE)) {
proxy = proxyFactory.createSemaphoreProxy(name);
} else if (name.startsWith(Prefix.COUNT_DOWN_LATCH)) {
proxy = proxyFactory.createCountDownLatchProxy(name);
} else if (name.equals("lock")) {
proxy = proxyFactory.createLockProxy(proxyKey.key);
}
final HazelcastInstanceAwareInstance anotherProxy = proxies.putIfAbsent(proxyKey, proxy);
if (anotherProxy != null) {
created = false;
proxy = anotherProxy;
}
if (proxyKey.key == null) {
proxiesByName.put(proxyKey.name, proxy);
}
}
if (created) {
logger.log(Level.FINEST, "Instance created " + proxyKey);
fireInstanceCreateEvent(proxy);
}
return proxy;
}
public void addInstanceListener(InstanceListener instanceListener) {
lsInstanceListeners.add(instanceListener);
}
public void removeInstanceListener(InstanceListener instanceListener) {
lsInstanceListeners.remove(instanceListener);
}
void fireInstanceCreateEvent(Instance instance) {
if (lsInstanceListeners.size() > 0) {
final InstanceEvent instanceEvent = new InstanceEvent(InstanceEvent.InstanceEventType.CREATED, instance);
for (final InstanceListener instanceListener : lsInstanceListeners) {
node.executorManager.executeLocally(new Runnable() {
public void run() {
instanceListener.instanceCreated(instanceEvent);
}
});
}
}
}
void fireInstanceDestroyEvent(Instance instance) {
if (lsInstanceListeners.size() > 0) {
final InstanceEvent instanceEvent = new InstanceEvent(InstanceEvent.InstanceEventType.DESTROYED, instance);
for (final InstanceListener instanceListener : lsInstanceListeners) {
node.executorManager.executeLocally(new Runnable() {
public void run() {
instanceListener.instanceDestroyed(instanceEvent);
}
});
}
}
}
Object createInstanceClusterWide(final ProxyKey proxyKey) {
final BlockingQueue<Object> result = ResponseQueueFactory.newResponseQueue();
node.clusterService.enqueueAndWait(new Processable() {
public void process() {
try {
result.put(createProxy(proxyKey));
} catch (InterruptedException ignored) {
}
}
}, 10);
Object proxy = null;
try {
proxy = result.take();
} catch (InterruptedException e) {
}
node.clusterManager.sendProcessableToAll(new CreateOrDestroyInstanceProxy(proxyKey, true), false);
return proxy;
}
void destroyInstanceClusterWide(String name, Object key) {
final ProxyKey proxyKey = new ProxyKey(name, key);
if (proxies.containsKey(proxyKey)) {
if (name.equals("lock")) {
locksMapProxy.remove(key);
}
node.clusterManager.sendProcessableToAll(new CreateOrDestroyInstanceProxy(proxyKey, false), true);
} else {
logger.log(Level.WARNING, "Destroying unknown instance name: " + name);
}
}
public static class CreateOrDestroyInstanceProxy extends AbstractRemotelyProcessable {
private ProxyKey proxyKey;
private boolean create;
public CreateOrDestroyInstanceProxy() {
}
public CreateOrDestroyInstanceProxy(final ProxyKey proxyKey, final boolean create) {
this.proxyKey = proxyKey;
this.create = create;
}
public void process() {
if (create) {
node.factory.createProxy(proxyKey);
} else {
node.factory.destroyProxy(proxyKey);
}
}
public void readData(final DataInput in) throws IOException {
super.readData(in);
create = in.readBoolean();
proxyKey = new ProxyKey();
proxyKey.readData(in);
}
public void writeData(final DataOutput out) throws IOException {
super.writeData(out);
out.writeBoolean(create);
proxyKey.writeData(out);
}
}
public static class ProxyKey extends SerializationHelper implements DataSerializable {
String name;
Object key;
public ProxyKey() {
}
public ProxyKey(String name, Object key) {
this.name = name;
this.key = key;
}
public void writeData(DataOutput out) throws IOException {
out.writeUTF(name);
boolean keyNull = (key == null);
out.writeBoolean(keyNull);
if (!keyNull) {
writeObject(out, key);
}
}
public void readData(DataInput in) throws IOException {
name = in.readUTF();
boolean keyNull = in.readBoolean();
if (!keyNull) {
key = readObject(in);
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ProxyKey pk = (ProxyKey) o;
return (name != null ? name.equals(pk.name) : pk.name == null)
&& (key != null ? key.equals(pk.key) : pk.key == null);
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (key != null ? key.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "ProxyKey {name='" + name + "', key=" + key + '}';
}
public String getName() {
return name;
}
public Object getKey() {
return key;
}
}
public static class GetAllProxyKeysCallable extends HazelcastInstanceAwareObject implements Callable<Set<ProxyKey>> {
public Set<ProxyKey> call() throws Exception {
final FactoryImpl factory = (FactoryImpl) hazelcastInstance;
return new HashSet<ProxyKey>(factory.proxies.keySet());
}
}
}