All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.internal.tpcengine.net.AsyncSocket Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2008-2024, 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.internal.tpcengine.net;

import com.hazelcast.internal.tpcengine.Reactor;

import java.io.IOException;
import java.net.SocketAddress;
import java.util.concurrent.CompletableFuture;

/**
 * A Socket that is asynchronous. So reads and writes do not block,
 * but are executed on an {@link Reactor}.
 */
@SuppressWarnings({"checkstyle:MethodCount", "checkstyle:VisibilityModifier"})
public abstract class AsyncSocket extends AbstractAsyncSocket {

    protected volatile SocketAddress remoteAddress;
    protected volatile SocketAddress localAddress;
    protected final AsyncSocketMetrics metrics = new AsyncSocketMetrics();
    protected final boolean clientSide;

    protected AsyncSocket(boolean clientSide) {
        this.clientSide = clientSide;
    }

    /**
     * Return the {@link AsyncSocketMetrics} of this AsyncSocket.
     * 

* This call can always be made no matter the state of the socket. * * @return the metrics. */ public final AsyncSocketMetrics metrics() { return metrics; } /** * Gets the {@link Reactor} this {@link AsyncSocket} belongs to. * * @return the {@link Reactor} this AsyncSocket belongs. */ public abstract Reactor reactor(); /** * Returns the {@link AsyncSocketOptions} of this AsyncSocket. * * @return the AsyncSocketOptions. */ public abstract AsyncSocketOptions options(); /** * Gets the remote address. *

* If the AsyncSocket isn't connected yet, null is returned. *

* This method is thread-safe. * * @return the remote address. */ public final SocketAddress getRemoteAddress() { return remoteAddress; } /** * Gets the local address. *

* If the AsyncSocket isn't connected yet, null is returned. *

* This method is thread-safe. * * @return the local address. */ public final SocketAddress getLocalAddress() { return localAddress; } /** * Configures if this AsyncSocket is readable or not. If there is no change in the * readable status, the call is ignored. *

* When an AsyncSocket is readable, it will schedule itself at the Reactor as soon as * data is received at the receive buffer of the socket, so that the received data gets * processed. When it isn't readable, data might be received at the receive buffer, but * the socket will not schedule itself. *

* This functionality can be used to apply backpressure. So what happens is that the receive * buffer fills up. Once it fills up and the other side keeps sending data, the remote send * buffer fills up as well and the pressure get propagated upstream. *

* This call can safely be made from any thread, but typically you want to call it from the * eventloop-thread. This call is blocking; this isn't an issue for the eventloop thread * because it is an instantaneous call. For any other thread this call is not cheap. * * @param readable the new readable status. * @throws RuntimeException if the readable status could not be set. */ public abstract void setReadable(boolean readable); /** * Checks if this AsyncSocket is readable. For more information see {@link #setReadable(boolean)}. *

* This call can safely be made from any thread, but typically you want to call it from the * eventloop-thread. This call is blocking; this isn't an issue for the eventloop thread * because it is an instantaneous call. For any other thread this call is not cheap. * * @return true if readable, false otherwise. * @throws RuntimeException if the readable status could not be retrieved. */ public abstract boolean isReadable(); /** * Start the AsyncSocket by scheduling it on the reactor. The Socket should be * started only once. *

* Typically, you do not want to share this AsyncSocket with other threads till this * method is called. * * @throws RuntimeException if the Socket could not be started. */ public abstract void start(); /** * Ensures that any scheduled messages are flushed to the socket. *

* What happens under the hood is that the AsyncSocket is scheduled in the * {@link Reactor} where at some point in the future the messages get written * to the socket. *

* This method is thread-safe. *

* This call is ignored when then AsyncSocket is already closed. */ public abstract void flush(); /** * Writes a message to this AsyncSocket without scheduling the AsyncSocket * in the {@link Reactor}. *

* This call can be used to buffer a series of messages and then call * {@link #flush()} to trigger the actual writing to the socket. *

* There is no guarantee that message is actually going to be received by the caller after * the AsyncSocket has accepted the message. E.g. when the TCP/IP connection is dropped. *

* This method is thread-safe. * * @param msg the message to write. * @return true if the msg was accepted, false otherwise. */ public abstract boolean write(Object msg); /** * Writes a message to this AsyncSocket and flushes it. Flushing causes the AsyncSocket * to be scheduled in the {@link Reactor}. *

* This is the same as calling {@link #write(Object)} followed by a {@link #flush()}. *

* There is no guarantee that message is actually going to be received by the caller if * the AsyncSocket has accepted the message. E.g. when the connection closes. *

* This method is thread-safe. * * @param msg the message to write. * @return true if the msg was accepted, false otherwise. */ public abstract boolean writeAndFlush(Object msg); /** * Writes a message. *

* Should only be called from the reactor-thread. */ public abstract boolean unsafeWriteAndFlush(Object msg); /** * Connects asynchronously to some address. *

* This method is not thread-safe. *

* This method should be called after {@link #start()}. * * @param address the address to connect to. * @return a {@link CompletableFuture} * @throws NullPointerException if address is null */ public abstract CompletableFuture connect(SocketAddress address); @Override protected void close0() throws IOException { localAddress = null; remoteAddress = null; } @Override public final String toString() { return getClass().getSimpleName() + "[" + localAddress + "->" + remoteAddress + "]"; //if (clientSide) { // return getClass().getSimpleName() + "[" + localAddress + "->" + remoteAddress + "]"; //} else { // return " " + getClass().getSimpleName() + "[" + localAddress + "<-" + remoteAddress + "]"; //} } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy