/* * 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.core.LifecycleEvent; import com.hazelcast.core.LifecycleEvent.LifecycleState; import com.hazelcast.core.LifecycleListener; import com.hazelcast.core.LifecycleService; import com.hazelcast.impl.executor.ParallelExecutor; import com.hazelcast.logging.ILogger; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import static com.hazelcast.core.LifecycleEvent.LifecycleState.*; public class LifecycleServiceImpl implements LifecycleService { final FactoryImpl factory; final Node node; final ILogger logger; final AtomicBoolean paused = new AtomicBoolean(false); final CopyOnWriteArrayList<LifecycleListener> lsLifecycleListeners = new CopyOnWriteArrayList<LifecycleListener>(); final Object lifecycleLock = new Object(); public LifecycleServiceImpl(FactoryImpl factory) { this.factory = factory; this.node = factory.node; logger = node.getLogger(LifecycleServiceImpl.class.getName()); } public void addLifecycleListener(LifecycleListener lifecycleListener) { lsLifecycleListeners.add(lifecycleListener); } public void removeLifecycleListener(LifecycleListener lifecycleListener) { lsLifecycleListeners.remove(lifecycleListener); } public void fireLifecycleEvent(LifecycleState lifecycleState) { fireLifecycleEvent(new LifecycleEvent(lifecycleState)); } public void fireLifecycleEvent(LifecycleEvent lifecycleEvent) { logger.log(Level.INFO, node.getThisAddress() + " is " + lifecycleEvent.getState()); for (LifecycleListener lifecycleListener : lsLifecycleListeners) { lifecycleListener.stateChanged(lifecycleEvent); } } public boolean pause() { synchronized (lifecycleLock) { if (!paused.get()) { fireLifecycleEvent(PAUSING); } else { return false; } paused.set(true); fireLifecycleEvent(PAUSED); return true; } } public boolean resume() { synchronized (lifecycleLock) { if (paused.get()) { fireLifecycleEvent(RESUMING); } else { return false; } paused.set(false); fireLifecycleEvent(RESUMED); return true; } } public boolean isRunning() { synchronized (lifecycleLock) { return node.isActive(); } } public void shutdown() { synchronized (lifecycleLock) { fireLifecycleEvent(SHUTTING_DOWN); FactoryImpl.shutdown(factory.getHazelcastInstanceProxy()); fireLifecycleEvent(SHUTDOWN); } } public void kill() { synchronized (lifecycleLock) { fireLifecycleEvent(SHUTTING_DOWN); FactoryImpl.kill(factory.getHazelcastInstanceProxy()); fireLifecycleEvent(SHUTDOWN); } } public void restart() { synchronized (lifecycleLock) { fireLifecycleEvent(RESTARTING); paused.set(true); List<Record> lsOwnedRecords = new ArrayList<Record>(); for (CMap cmap : node.concurrentMapManager.getCMaps().values()) { if (cmap.isUserMap()) { lsOwnedRecords.addAll(cmap.getMapIndexService().getOwnedRecords()); } } node.onRestart(); node.clientHandlerService.restart(); node.connectionManager.onRestart(); node.clusterManager.onRestart(); node.concurrentMapManager.onRestart(); node.rejoin(); final CountDownLatch latch = new CountDownLatch(lsOwnedRecords.size()); final ParallelExecutor executor = node.executorManager.newParallelExecutor(16); for (final Record ownedRecord : lsOwnedRecords) { executor.execute(new Runnable() { public void run() { try { ConcurrentMapManager.MPut mput = node.concurrentMapManager.new MPut(); mput.merge(ownedRecord); // invalidate record now (skipped invalidation on restart) ownedRecord.invalidate(); latch.countDown(); } catch (Exception e) { logger.log(Level.WARNING, e.getMessage(), e); } } }); } try { latch.await(60, TimeUnit.SECONDS); } catch (InterruptedException ignored) { } paused.set(false); fireLifecycleEvent(RESTARTED); } } }