Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2008-2020, Hazelcast, Inc. 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.cp.internal.datastructures.spi.blocking;
import com.hazelcast.cp.CPGroupId;
import com.hazelcast.cp.internal.RaftNodeLifecycleAwareService;
import com.hazelcast.cp.internal.RaftService;
import com.hazelcast.cp.internal.datastructures.spi.RaftManagedService;
import com.hazelcast.cp.internal.datastructures.spi.RaftRemoteService;
import com.hazelcast.cp.internal.datastructures.spi.blocking.operation.ExpireWaitKeysOp;
import com.hazelcast.cp.internal.raft.SnapshotAwareService;
import com.hazelcast.cp.internal.raft.impl.RaftNode;
import com.hazelcast.cp.internal.raft.impl.RaftNodeImpl;
import com.hazelcast.cp.internal.session.SessionAccessor;
import com.hazelcast.cp.internal.session.SessionAwareService;
import com.hazelcast.cp.internal.session.SessionExpiredException;
import com.hazelcast.cp.internal.util.Tuple2;
import com.hazelcast.logging.ILogger;
import com.hazelcast.nio.Address;
import com.hazelcast.spi.ExecutionService;
import com.hazelcast.spi.LiveOperations;
import com.hazelcast.spi.LiveOperationsTracker;
import com.hazelcast.spi.NodeEngine;
import com.hazelcast.spi.exception.DistributedObjectDestroyedException;
import com.hazelcast.spi.impl.NodeEngineImpl;
import com.hazelcast.util.Clock;
import com.hazelcast.util.collection.Long2ObjectHashMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static com.hazelcast.cp.internal.session.AbstractProxySessionManager.NO_SESSION_ID;
import static com.hazelcast.util.Preconditions.checkNotNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
/**
* Base class for services that maintain blocking resources.
* Contains common behaviour that will be needed by service implementations.
*
* @param concrete type of the WaitKey
* @param concrete type of the resource
* @param concrete ty;e lf the resource registry
*/
public abstract class AbstractBlockingService, RR extends ResourceRegistry>
implements RaftManagedService, RaftNodeLifecycleAwareService, RaftRemoteService, SessionAwareService,
SnapshotAwareService, LiveOperationsTracker {
public static final long WAIT_TIMEOUT_TASK_UPPER_BOUND_MILLIS = 1500;
private static final long WAIT_TIMEOUT_TASK_PERIOD_MILLIS = 500;
protected final NodeEngineImpl nodeEngine;
protected final ILogger logger;
protected volatile RaftService raftService;
private final ConcurrentMap registries = new ConcurrentHashMap();
private volatile SessionAccessor sessionAccessor;
protected AbstractBlockingService(NodeEngine nodeEngine) {
this.nodeEngine = (NodeEngineImpl) nodeEngine;
this.logger = nodeEngine.getLogger(getClass());
}
@Override
public final void init(NodeEngine nodeEngine, Properties properties) {
this.raftService = nodeEngine.getService(RaftService.SERVICE_NAME);
ExecutionService executionService = nodeEngine.getExecutionService();
executionService.scheduleWithRepetition(new ExpireWaitKeysPeriodicTask(),
WAIT_TIMEOUT_TASK_PERIOD_MILLIS, WAIT_TIMEOUT_TASK_PERIOD_MILLIS, MILLISECONDS);
initImpl();
}
/**
* Subclasses can implement their custom initialization logic here
*/
protected void initImpl() {
}
@Override
public void reset() {
}
@Override
public void onCPSubsystemRestart() {
registries.clear();
}
@Override
public final void shutdown(boolean terminate) {
registries.clear();
shutdownImpl(terminate);
}
/**
* Subclasses can implement their custom shutdown logic here
*/
protected void shutdownImpl(boolean terminate) {
}
/**
* Returns name of the service.
*/
protected abstract String serviceName();
/**
* Creates a registry for the given Raft group.
*/
protected abstract RR createNewRegistry(CPGroupId groupId);
/**
* Creates the response object that will be sent for a expired wait key.
*/
protected abstract Object expiredWaitKeyResponse();
protected void onRegistryRestored(RR registry) {
}
@Override
public boolean destroyRaftObject(CPGroupId groupId, String name) {
Collection keys = getOrInitRegistry(groupId).destroyResource(name);
if (keys == null) {
return false;
}
List commitIndices = new ArrayList();
for (W key : keys) {
commitIndices.add(key.commitIndex());
}
completeFutures(groupId, commitIndices, new DistributedObjectDestroyedException(name + " is destroyed"));
return true;
}
@Override
public final RR takeSnapshot(CPGroupId groupId, long commitIndex) {
RR registry = getRegistryOrNull(groupId);
return registry != null ? (RR) registry.cloneForSnapshot() : null;
}
@Override
public final void restoreSnapshot(CPGroupId groupId, long commitIndex, RR registry) {
RR prev = registries.put(registry.getGroupId(), registry);
// do not shift the already existing wait timeouts...
Map, Tuple2> existingWaitTimeouts =
prev != null ? prev.getWaitTimeouts() : Collections., Tuple2>emptyMap();
Map, Long> newWaitKeys = registry.overwriteWaitTimeouts(existingWaitTimeouts);
for (Entry, Long> e : newWaitKeys.entrySet()) {
scheduleTimeout(groupId, e.getKey().element1, e.getKey().element2, e.getValue());
}
registry.onSnapshotRestore();
onRegistryRestored(registry);
}
@Override
public void setSessionAccessor(SessionAccessor accessor) {
this.sessionAccessor = accessor;
}
@Override
public final void onSessionClose(CPGroupId groupId, long sessionId) {
ResourceRegistry registry = registries.get(groupId);
if (registry == null) {
if (logger.isFineEnabled()) {
logger.fine("Resource registry of " + groupId + " not found to handle closed Session[" + sessionId + "]");
}
return;
}
List expiredWaitKeys = new ArrayList();
Long2ObjectHashMap