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

org.jgroups.protocols.CENTRAL_EXECUTOR Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote Jakarta Enterprise Beans and Jakarta Messaging, including all dependencies. It is intended for use by those not using maven, maven users should just import the Jakarta Enterprise Beans and Jakarta Messaging 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: 35.0.0.Beta1
Show newest version
package org.jgroups.protocols;

import org.jgroups.Address;
import org.jgroups.View;
import org.jgroups.annotations.ManagedAttribute;
import org.jgroups.annotations.Property;
import org.jgroups.util.Util;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


/**
 * This is a central executor service where each request is sent to the coordinator
 * for either a task or a current waiting thread.
 * 
 * @author wburns
 * @since 2.12.0
 */
public class CENTRAL_EXECUTOR extends Executing {

    @Property(description="Number of backups to the coordinator.  Queue State gets replicated to these nodes as well")
    protected int num_backups=1;

    protected Address coord;

    @ManagedAttribute
    protected boolean is_coord;

    protected final List
backups=new ArrayList<>(); public CENTRAL_EXECUTOR() { super(); } public Address getCoord() { return coord; } public boolean isCoord() { return is_coord; } @ManagedAttribute public String getCoordinator() { return coord != null? coord.toString() : "n/a"; } public int getNumberOfBackups() { return num_backups; } public void setNumberOfBackups(int num_backups) { this.num_backups=num_backups; } @ManagedAttribute public String getBackups() { return backups != null? backups.toString() : null; } public void handleView(View view) { Address oldCoord = coord; if(view.size() > 0) { coord=view.getCoord(); is_coord=coord.equals(local_addr); if(log.isDebugEnabled()) log.debug("local_addr=" + local_addr + ", coord=" + coord + ", is_coord=" + is_coord); } // If we got a new coordinator we have to send all the requests for // tasks and consumers again just incase they were missed when // coordinator went down // We are okay with duplicates since we don't add multiple times. // We also have a problem that if a task/consumer was picked up as the // consumer is changing we may have duplicates. But this is technically // okay in that an extra consumer will reject and an extra task will just // be ran and return nowhere, but at least we won't lose data. if (oldCoord != coord) { for (Long requests : _requestId.values()) { sendToCoordinator(Type.RUN_REQUEST, requests, local_addr); } for (Long requests : _consumerId.keySet()) { sendToCoordinator(Type.CONSUMER_READY, requests, local_addr); } } if(num_backups > 0) { if (is_coord) { List
new_backups=Util.pickNext(view.getMembers(), local_addr, num_backups); List
new_members=null; synchronized(backups) { if(!backups.equals(new_backups)) { new_members=new ArrayList<>(new_backups); new_members.removeAll(backups); backups.clear(); backups.addAll(new_backups); } } if(new_members != null && !new_members.isEmpty()) copyQueueTo(new_members); } // We keep what backups we have ourselves, so that when we become // the coordinator we don't update them again. Technically we can // send multiple requests but don't if to prevent more message being // sent. else { List
possiblebackups = Util.pickNext(view.getMembers(), coord, num_backups); boolean foundMyself = false; List
myBackups = new ArrayList<>(); for (Address backup : possiblebackups) { if (foundMyself) { myBackups.add(backup); } else if (backup.equals(local_addr)) { foundMyself = true; } } synchronized (backups) { backups.clear(); backups.addAll(myBackups); } } } // Need to run this last so the backups are updated super.handleView(view); } protected void updateBackups(Type type, Owner obj) { synchronized(backups) { for(Address backup: backups) sendRequest(backup, type, obj.getRequestId(), obj.getAddress()); } } protected void copyQueueTo(List
new_joiners) { Set copyRequests; Set copyConsumers; _consumerLock.lock(); try { copyRequests = new HashSet<>(_runRequests); copyConsumers = new HashSet<>(_consumersAvailable); } finally { _consumerLock.unlock(); } if(log.isTraceEnabled()) log.trace("copying queue to " + new_joiners); for(Address joiner: new_joiners) { for(Owner address: copyRequests) { sendRequest(joiner, Type.CREATE_RUN_REQUEST, address.getRequestId(), address.getAddress()); } for(Owner address: copyConsumers) { sendRequest(joiner, Type.CREATE_CONSUMER_READY, address.getRequestId(), address.getAddress()); } } } // @see org.jgroups.protocols.Executing#sendToCoordinator(org.jgroups.protocols.Executing.Type, long, org.jgroups.Address) @Override protected void sendToCoordinator(Type type, final long requestId, final Address value) { if (is_coord) { if(log.isTraceEnabled()) log.trace("[redirect] <--> [" + local_addr + "] " + type.name() + " [" + value + (requestId != -1 ? " request id: " + requestId : "") + "]"); switch(type) { case RUN_REQUEST: handleTaskRequest(requestId, value); break; case CONSUMER_READY: handleConsumerReadyRequest(requestId, value); break; case CONSUMER_UNREADY: handleConsumerUnreadyRequest(requestId, value); break; }; } else sendRequest(coord, type, requestId, value); } // @see org.jgroups.protocols.Executing#sendNewRunRequest(org.jgroups.protocols.Executing.Owner) @Override protected void sendNewRunRequest(Owner sender) { if(is_coord) updateBackups(Type.CREATE_RUN_REQUEST, sender); } // @see org.jgroups.protocols.Executing#sendRemoveRunRequest(org.jgroups.protocols.Executing.Owner) @Override protected void sendRemoveRunRequest(Owner sender) { if(is_coord) updateBackups(Type.DELETE_RUN_REQUEST, sender); } // @see org.jgroups.protocols.Executing#sendNewConsumerRequest(org.jgroups.protocols.Executing.Owner) @Override protected void sendNewConsumerRequest(Owner sender) { if(is_coord) updateBackups(Type.CREATE_CONSUMER_READY, sender); } // @see org.jgroups.protocols.Executing#sendRemoveConsumerRequest(org.jgroups.protocols.Executing.Owner) @Override protected void sendRemoveConsumerRequest(Owner sender) { if(is_coord) updateBackups(Type.DELETE_CONSUMER_READY, sender); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy