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

org.jgroups.blocks.UnicastRequest Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

There is a newer version: 34.0.0.Final
Show newest version
package org.jgroups.blocks;


import org.jgroups.*;
import org.jgroups.annotations.GuardedBy;
import org.jgroups.protocols.relay.SiteAddress;
import org.jgroups.util.Buffer;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;


/**
 * Sends a request to a single target destination
 *
 * @author Bela Ban
 */
public class UnicastRequest extends Request {
    protected final Address    target;


    public UnicastRequest(RequestCorrelator corr, Address target, RequestOptions options) {
        super(corr, options);
        this.target=target; // target is guaranteed to be non-null
    }


    public void sendRequest(Buffer data) throws Exception {
        try {
            corr.sendUnicastRequest(target, data, options.mode() == ResponseMode.GET_NONE? null : this, this.options);
        }
        catch(Exception ex) {
            corrDone();
            throw ex;
        }
    }
    

    /* ---------------------- Interface RspCollector -------------------------- */
    /**
     * Callback (called by RequestCorrelator or Transport).
     * Adds a response to the response table. When all responses have been received, {@code execute()} returns.
     */
    public void receiveResponse(Object response_value, Address sender, boolean is_exception) {
        if(isDone())
            return;
        if(is_exception && response_value instanceof Throwable)
            completeExceptionally((Throwable)response_value);
        else
            complete((T)response_value);
        corrDone();
    }


    public void siteUnreachable(String site) {
        if(!(target instanceof SiteAddress) || !((SiteAddress)target).getSite().equals(site) || isDone())
            return;
        completeExceptionally(new UnreachableException(target));
        corrDone();
    }

    /**
     * If the target address is not a member of the new view, we'll mark the response as suspected and unblock
     * the caller of execute()
     */
    public void viewChange(View view, boolean handle_previous_subgroups) {
        if(view == null)
            return;

        if(view instanceof MergeView && handle_previous_subgroups) {
            // if target is not in a subview then we need to suspect it (https://issues.redhat.com/browse/JGRP-2575)
            for(View v: ((MergeView)view).getSubgroups()) {
                if(v.containsMember(target) && !v.containsMember(corr.local_addr)) {
                    completeExceptionally(new SuspectedException(target));
                    corrDone();
                    return;
                }
            }
        }
        // SiteAddresses are not checked as they might be in a different cluster
        if(!(target instanceof SiteAddress) && !view.containsMember(target) && !isDone()) {
            completeExceptionally(new SuspectedException(target));
            corrDone();
        }
    }

    public void transportClosed() {
        if(isDone())
            return;
        completeExceptionally(new IllegalStateException("transport was closed"));
        corrDone();
    }

    /* -------------------- End of Interface RspCollector ----------------------------------- */
    public T get() throws InterruptedException, ExecutionException {
        try {
            return super.get();
        }
        finally {
            corrDone();
        }
    }

    public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        try {
            return super.get(timeout, unit);
        }
        finally {
            corrDone();
        }
    }

    public T join() {
        return around(super::join);
    }

    public T getNow(T valueIfAbsent) {
        return around(() -> super.getNow(valueIfAbsent));
    }

    public T waitForCompletion(long timeout, TimeUnit unit) throws Exception {
        return getResult(() -> get(timeout, unit));
    }

    public T waitForCompletion() throws Exception {
        return getResult(this::get);
    }


    public String toString() {
        return String.format("%s, target=%s", super.toString(), target);
    }


    @GuardedBy("lock")
    public boolean responsesComplete() {
        return options.mode() == ResponseMode.GET_NONE || isDone();
    }

    protected T around(Supplier supplier) {
        try {return supplier.get();}
        finally {corrDone();}
    }


    protected T getResult(Callable supplier) throws Exception {
        try {
            T result=supplier.call();
            if(result == null && !isDone())
                throw new TimeoutException("timeout waiting for response from " + target + ", request: " + toString());
            return result;
        }
        catch(ExecutionException ex) {
            Throwable exception=ex.getCause();
            if(exception instanceof Error) throw (Error)exception;
            else if(exception instanceof RuntimeException) throw (RuntimeException)exception;
            else if(exception instanceof Exception) throw (Exception)exception;
            else throw new RuntimeException(exception);
        }
        finally {
            corrDone();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy