All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
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.
com.hazelcast.client.spi.impl.ClientListenerServiceImpl Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2015, 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.client.spi.impl;
import com.hazelcast.client.connection.nio.ClientConnection;
import com.hazelcast.client.impl.ClientMessageDecoder;
import com.hazelcast.client.impl.HazelcastClientInstanceImpl;
import com.hazelcast.client.impl.protocol.ClientMessage;
import com.hazelcast.client.spi.ClientInvocationService;
import com.hazelcast.client.spi.ClientListenerService;
import com.hazelcast.client.spi.EventHandler;
import com.hazelcast.logging.ILogger;
import com.hazelcast.logging.Logger;
import com.hazelcast.nio.Connection;
import com.hazelcast.spi.exception.TargetDisconnectedException;
import com.hazelcast.util.ExceptionUtil;
import com.hazelcast.util.executor.StripedExecutor;
import com.hazelcast.util.executor.StripedRunnable;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
import java.util.logging.Level;
public final class ClientListenerServiceImpl implements ClientListenerService {
private final ILogger logger = Logger.getLogger(ClientInvocationService.class);
private final HazelcastClientInstanceImpl client;
private final ClientInvocationService invocationService;
private final ConcurrentMap registrationMap = new ConcurrentHashMap();
private final ConcurrentMap registrationAliasMap = new ConcurrentHashMap();
private final StripedExecutor eventExecutor;
private final Set failedListeners =
Collections.newSetFromMap(new ConcurrentHashMap());
public ClientListenerServiceImpl(HazelcastClientInstanceImpl client, int eventThreadCount, int eventQueueCapacity) {
this.client = client;
this.invocationService = client.getInvocationService();
this.eventExecutor = new StripedExecutor(logger, client.getName() + ".event",
client.getThreadGroup(), eventThreadCount, eventQueueCapacity);
}
public StripedExecutor getEventExecutor() {
return eventExecutor;
}
@Override
public String startListening(ClientMessage clientMessage, Object key, EventHandler handler,
ClientMessageDecoder responseDecoder) {
final ClientInvocationFuture future;
try {
handler.beforeListenerRegister();
if (key == null) {
future = new ClientListenerInvocation(client, handler, clientMessage, responseDecoder).invoke();
} else {
final int partitionId = client.getClientPartitionService().getPartitionId(key);
future = new ClientListenerInvocation(client, handler, clientMessage, partitionId,
responseDecoder).invoke();
}
ClientMessage responseMessage = future.get();
String registrationId = responseDecoder.decodeClientMessage(responseMessage);
registerListener(registrationId, clientMessage.getCorrelationId());
return registrationId;
} catch (Exception e) {
throw ExceptionUtil.rethrow(e);
}
}
@Override
public boolean stopListening(String registrationId, ListenerRemoveCodec listenerRemoveCodec) {
try {
String realRegistrationId = deRegisterListener(registrationId);
if (realRegistrationId == null) {
return false;
}
ClientMessage removeRequest = listenerRemoveCodec.encodeRequest(realRegistrationId);
Future future = new ClientInvocation(client, removeRequest).invoke();
future.get();
return true;
} catch (Exception e) {
throw ExceptionUtil.rethrow(e);
}
}
public void registerFailedListener(ClientInvocation future) {
failedListeners.add(future);
}
public void triggerFailedListeners() {
final Iterator iterator = failedListeners.iterator();
while (iterator.hasNext()) {
final ClientInvocation failedListener = iterator.next();
iterator.remove();
failedListener.notifyException(new TargetDisconnectedException());
}
}
public void registerListener(String uuid, Integer callId) {
registrationAliasMap.put(uuid, uuid);
registrationMap.put(uuid, callId);
}
public void reRegisterListener(String uuid, String alias, Integer callId) {
final String oldAlias = registrationAliasMap.put(uuid, alias);
if (oldAlias != null) {
registrationMap.remove(oldAlias);
registrationMap.put(alias, callId);
}
}
public String deRegisterListener(String alias) {
final String uuid = registrationAliasMap.remove(alias);
if (uuid != null) {
final Integer callId = registrationMap.remove(uuid);
invocationService.removeEventHandler(callId);
}
return uuid;
}
public void handleClientMessage(ClientMessage clientMessage, Connection clientConnection) {
try {
eventExecutor.execute(new ClientEventProcessor(clientMessage, (ClientConnection) clientConnection));
} catch (RejectedExecutionException e) {
logger.log(Level.WARNING, " event clientMessage could not be handled ", e);
}
}
public void shutdown() {
eventExecutor.shutdown();
}
private final class ClientEventProcessor implements StripedRunnable {
private final ClientMessage clientMessage;
private final ClientConnection clientConnection;
private ClientEventProcessor(ClientMessage clientMessage, ClientConnection clientConnection) {
this.clientMessage = clientMessage;
this.clientConnection = clientConnection;
}
@Override
public void run() {
try {
int correlationId = clientMessage.getCorrelationId();
final EventHandler eventHandler = invocationService.getEventHandler(correlationId);
if (eventHandler == null) {
logger.warning("No eventHandler for callId: " + correlationId + ", event: " + clientMessage);
return;
}
eventHandler.handle(clientMessage);
} finally {
clientConnection.decrementPendingPacketCount();
}
}
@Override
public int getKey() {
return clientMessage.getPartitionId();
}
}
}