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

dev.mayuna.timestop.networking.extension.NetworkTask Maven / Gradle / Ivy

package dev.mayuna.timestop.networking.extension;

import dev.mayuna.timestop.networking.base.TimeStopClient;
import dev.mayuna.timestop.networking.base.TimeStopConnection;
import lombok.NonNull;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

public class NetworkTask {

    private NetworkTask() {
    }

    /**
     * Sends a TCP request and waits for a response. Returns null if the timeout is reached.
     *
     * @param connection    Connection
     * @param request       Request
     * @param responseClass Response class
     * @param timeout       Timeout in milliseconds
     * @param   Connection type
     * @param            Response type
     *
     * @return Response
     */
    public static  T sendTCPWithResponseSync(Connection connection, Object request, Class responseClass, long timeout) {
        final AtomicBoolean ignore = new AtomicBoolean(false);
        final AtomicReference atomicResponse = new AtomicReference<>(null);

        connection.sendTCPWithResponse(request, responseClass, response -> {
            if (ignore.get()) {
                return;
            }

            atomicResponse.set(response);

            synchronized (atomicResponse) {
                atomicResponse.notifyAll();
            }
        });

        synchronized (atomicResponse) {
            try {
                atomicResponse.wait(timeout);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            ignore.set(true);
        }

        return atomicResponse.get();
    }

    /**
     * Sends a TCP request and waits for a response. Returns null if the timeout is reached.
     *
     * @param client        Client
     * @param request       Request
     * @param responseClass Response class
     * @param timeout       Timeout in milliseconds
     * @param       Connection type
     * @param            Response type
     *
     * @return Response
     */
    public static  T sendTCPWithResponseSync(Client client, Object request, Class responseClass, long timeout) {
        final AtomicBoolean ignore = new AtomicBoolean(false);
        final AtomicReference atomicResponse = new AtomicReference<>(null);

        client.sendTCPWithResponse(request, responseClass, response -> {
            if (ignore.get()) {
                return;
            }

            atomicResponse.set(response);

            synchronized (atomicResponse) {
                atomicResponse.notifyAll();
            }
        });

        synchronized (atomicResponse) {
            try {
                atomicResponse.wait(timeout);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            ignore.set(true);
        }

        return atomicResponse.get();
    }

    /**
     * Sends a TCP request and waits for a response. Returns null if the connection's default timeout is reached.
     *
     * @param connection    Connection
     * @param request       Request
     * @param responseClass Response class
     * @param   Connection type
     * @param            Response type
     *
     * @return Response
     */
    public static  T sendTCPWithResponseSync(Connection connection, Object request, Class responseClass) {
        return sendTCPWithResponseSync(connection, request, responseClass, connection.getEndpointConfig().getDefaultResponseTimeoutMillis());
    }

    /**
     * Sends a TCP request and waits for a response. Returns null if the connection's default timeout is reached.
     *
     * @param client        Client
     * @param request       Request
     * @param responseClass Response class
     * @param       Client type
     * @param            Response type
     *
     * @return Response
     */
    public static  T sendTCPWithResponseSync(Client client, Object request, Class responseClass) {
        return sendTCPWithResponseSync(client, request, responseClass, client.getEndpointConfig().getDefaultResponseTimeoutMillis());
    }

    /**
     * Base interface for network tasks
     *
     * @param  Connection type (e.g., com.esotericsoftware.kryonet.Connection or TimeStopConnection)
     * @param        Send type
     * @param    Response type
     */
    public interface Base {

        /**
         * Runs the task synchronously (shall block, when waiting for a response, etc.)
         *
         * @param connection Connection
         * @param send       Send
         *
         * @return Response
         */
        @NotNull Response run(@NonNull Connection connection, @NonNull Send send);

        /**
         * Runs the task asynchronously
         *
         * @param connection Connection
         * @param send       Send
         *
         * @return Future of the response
         */
        default @NotNull CompletableFuture runAsync(@NonNull Connection connection, @NonNull Send send) {
            CompletableFuture future = new CompletableFuture<>();

            CompletableFuture.runAsync(() -> {
                try {
                    future.complete(run(connection, send));
                } catch (Exception e) {
                    future.completeExceptionally(e);
                }
            });

            return future;
        }

        /**
         * Runs the task asynchronously
         *
         * @param executor   Executor
         * @param connection Connection
         * @param send       Send
         *
         * @return Future of the response
         */
        default @NotNull CompletableFuture runAsync(@NonNull Executor executor, @NonNull Connection connection, @NonNull Send send) {
            CompletableFuture future = new CompletableFuture<>();

            executor.execute(() -> {
                try {
                    future.complete(run(connection, send));
                } catch (Exception e) {
                    future.completeExceptionally(e);
                }
            });

            return future;
        }
    }

    /**
     * Interface for network tasks that do not require a send object
     *
     * @param  Connection type (e.g., com.esotericsoftware.kryonet.Connection or TimeStopConnection)
     * @param    Response type
     */
    public interface EmptySend {

        /**
         * Runs the task synchronously (shall block, when waiting for a response, etc.)
         *
         * @param connection Connection
         *
         * @return Response
         */
        @NotNull Response run(@NonNull Connection connection);

        /**
         * Runs the task asynchronously
         *
         * @param connection Connection
         *
         * @return Future of the response
         */
        default @NotNull CompletableFuture runAsync(@NonNull Connection connection) {
            CompletableFuture future = new CompletableFuture<>();

            CompletableFuture.runAsync(() -> {
                try {
                    future.complete(run(connection));
                } catch (Exception e) {
                    future.completeExceptionally(e);
                }
            });

            return future;
        }

        /**
         * Runs the task asynchronously
         *
         * @param executor   Executor
         * @param connection Connection
         *
         * @return Future of the response
         */
        default CompletableFuture runAsync(@NonNull Executor executor, @NonNull Connection connection) {
            CompletableFuture future = new CompletableFuture<>();

            executor.execute(() -> {
                try {
                    future.complete(run(connection));
                } catch (Exception e) {
                    future.completeExceptionally(e);
                }
            });

            return future;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy