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 2015 the original author or authors.
*
* 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 io.atomix.catalyst.transport.netty;
import io.atomix.catalyst.concurrent.Listener;
import io.atomix.catalyst.concurrent.Listeners;
import io.atomix.catalyst.concurrent.Scheduled;
import io.atomix.catalyst.concurrent.ThreadContext;
import io.atomix.catalyst.serializer.SerializationException;
import io.atomix.catalyst.transport.Connection;
import io.atomix.catalyst.transport.MessageHandler;
import io.atomix.catalyst.util.Assert;
import io.atomix.catalyst.util.reference.ReferenceCounted;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import java.net.ConnectException;
import java.time.Duration;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
/**
* Netty connection.
*
* @author Jordan Halterman
*/
public class NettyConnection implements Connection {
static final byte REQUEST = 0x01;
static final byte RESPONSE = 0x02;
static final byte SUCCESS = 0x03;
static final byte FAILURE = 0x04;
private static final ThreadLocal INPUT = new ThreadLocal() {
@Override
protected ByteBufInput initialValue() {
return new ByteBufInput();
}
};
private static final ThreadLocal OUTPUT = new ThreadLocal() {
@Override
protected ByteBufOutput initialValue() {
return new ByteBufOutput();
}
};
private final Channel channel;
private final ThreadContext context;
private final Map handlers = new ConcurrentHashMap<>();
private final Listeners exceptionListeners = new Listeners<>();
private final Listeners closeListeners = new Listeners<>();
private final long requestTimeout;
private volatile long requestId;
private volatile Throwable failure;
private volatile boolean closed;
private Scheduled timeout;
private final Map responseFutures = new ConcurrentSkipListMap<>();
private ChannelFuture writeFuture;
/**
* @throws NullPointerException if any argument is null
*/
public NettyConnection(Channel channel, ThreadContext context, NettyOptions options) {
this.channel = channel;
this.context = context;
this.requestTimeout = options.requestTimeout();
this.timeout = context.schedule(Duration.ofMillis(requestTimeout / 2), Duration.ofMillis(requestTimeout / 2), this::timeout);
}
/**
* Handles a request.
*/
void handleRequest(ByteBuf buffer) {
long requestId = buffer.readLong();
try {
Object request = readRequest(buffer);
HandlerHolder handler = handlers.get(request.getClass());
if (handler != null) {
handler.context.executor().execute(() -> handleRequest(requestId, request, handler));
} else {
handleRequestFailure(requestId, new SerializationException("unknown message type: " + request.getClass()), this.context);
}
} catch (SerializationException e) {
handleRequestFailure(requestId, e, this.context);
} finally {
buffer.release();
}
}
/**
* Handles a request.
*/
private void handleRequest(long requestId, Object request, HandlerHolder handler) {
@SuppressWarnings("unchecked")
CompletableFuture