com.hazelcast.spi.CallsPerMember Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hazelcast-all Show documentation
Show all versions of hazelcast-all Show documentation
Kubernetes Service Discovery for Hazelcast Discovery SPI
/*
* Copyright (c) 2008-2019, 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.spi;
import com.hazelcast.nio.Address;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.hazelcast.util.Preconditions.checkNotNull;
/**
* Implements {@link LiveOperations} and additionally collects the call IDs of operations on remote members
* whose cancellation was requested.
*
* This data-structure can be optimized to generate less litter. Instead of using an ArrayList for Long objects,
* use an array for primitive longs. Also the lists don't need to be recreated every time the
* {@link LiveOperationsTracker#populate(LiveOperations)} method is called; they could be recycled. This would be easy
* to do since the {@link CallsPerMember} is used by a single thread.
*/
public final class CallsPerMember implements LiveOperations {
private final Address localAddress;
private final Map
callIdsByMember = new HashMap();
public CallsPerMember(Address localAddress) {
this.localAddress = checkNotNull(localAddress, "local address can't be null");
}
@Override
public void add(Address address, long callId) {
if (callId == 0) {
// it is an unregistered operation
return;
}
if (address == null) {
address = localAddress;
}
getOrCreateCallIdsForMember(address).liveOps.add(callId);
}
public void addOpToCancel(Address address, long callId) {
getOrCreateCallIdsForMember(address).opsToCancel.add(callId);
}
public Set addresses() {
return callIdsByMember.keySet();
}
public OperationControl toOpControl(Address address) {
CategorizedCallIds callIds = callIdsByMember.get(address);
if (callIds == null) {
throw new IllegalArgumentException("Address not recognized as a member of this cluster: " + address);
}
return new OperationControl(toArray(callIds.liveOps), toArray(callIds.opsToCancel));
}
public void clear() {
callIdsByMember.clear();
}
/**
* Makes sure that a list of counters is created for a member.
*
* This method exists to ensure that an operation-heartbeat is always sent, even if there are no running operations.
*
* @param address the address of the member.
*/
public void ensureMember(Address address) {
getOrCreateCallIdsForMember(address);
}
public CategorizedCallIds getOrCreateCallIdsForMember(Address address) {
CategorizedCallIds callIds = callIdsByMember.get(address);
if (callIds == null) {
callIds = new CategorizedCallIds();
callIdsByMember.put(address, callIds);
}
return callIds;
}
private static long[] toArray(List longs) {
long[] array = new long[longs.size()];
for (int k = 0; k < array.length; k++) {
array[k] = longs.get(k);
}
return array;
}
private static final class CategorizedCallIds {
final List liveOps = new ArrayList();
final List opsToCancel = new ArrayList();
}
}