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

org.jgroups.protocols.MFC 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: 33.0.2.Final
Show newest version
package org.jgroups.protocols;

import org.jgroups.Address;
import org.jgroups.Event;
import org.jgroups.Message;
import org.jgroups.annotations.MBean;
import org.jgroups.annotations.ManagedAttribute;
import org.jgroups.annotations.ManagedOperation;
import org.jgroups.util.CreditMap;
import org.jgroups.util.Tuple;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;


/**
 * Simple flow control protocol based on a credit system. Each sender has a number of credits (bytes
 * to send). When the credits have been exhausted, the sender blocks. Each receiver also keeps track of
 * how many credits it has received from a sender. When credits for a sender fall below a threshold,
 * the receiver sends more credits to the sender. Works for both unicast and multicast messages.
 * 

* Note that this protocol must be located towards the top of the stack, or all down_threads from JChannel to this * protocol must be set to false ! This is in order to block JChannel.send()/JChannel.down(). *
This is the second simplified implementation of the same model. The algorithm is sketched out in * doc/FlowControl.txt *
* Changes (Brian) April 2006: *

    *
  1. Receivers now send credits to a sender when more than min_credits have been received (rather than when min_credits * are left) *
  2. Receivers don't send the full credits (max_credits), but rather the actual number of bytes received *
      * @author Bela Ban */ @MBean(description="Simple flow control protocol based on a credit system") public class MFC extends FlowControl { /* --------------------------------------------- Fields ------------------------------------------------------ */ /** Maintains credits per member */ protected CreditMap credits; /** Last time a credit request was sent. Used to prevent credit request storms */ protected long last_credit_request; // ns /** Allows to unblock a blocked sender from an external program, e.g. JMX */ @ManagedOperation(description="Unblock a sender") public void unblock() { if(log.isTraceEnabled()) log.trace("unblocking the sender and replenishing all members"); credits.replenishAll(); } @ManagedOperation(description="Print credits") public String printCredits() { return super.printCredits() + "\nsenders min credits: " + credits.computeLowestCreditWithAccumulated(); } @ManagedOperation(description="Print sender credits") public String printSenderCredits() { return credits.toString(); } @ManagedAttribute(description="Number of times flow control blocks sender") public int getNumberOfBlockings() { return credits.getNumBlockings(); } @ManagedAttribute(description="Average time blocked (in ms) in flow control when trying to send a message") public double getAverageTimeBlocked() { return credits.getAverageBlockTime(); } protected boolean handleMulticastMessage() { return true; } public void init() throws Exception { super.init(); credits=new CreditMap(max_credits); } public void stop() { super.stop(); credits.clear(); } public void resetStats() { super.resetStats(); credits.reset(); } protected Object handleDownMessage(final Event evt, final Message msg, Address dest, int length) { if(dest != null) // 2nd line of defense, not really needed return down_prot.down(evt); long block_time=max_block_times != null? getMaxBlockTime(length) : max_block_time; while(running) { boolean rc=credits.decrement(length, block_time); if(rc || max_block_times != null || !running) break; if(needToSendCreditRequest()) { List> targets=credits.getMembersWithCreditsLessThan(min_credits); for(Tuple tuple: targets) sendCreditRequest(tuple.getVal1(), Math.min(max_credits, max_credits - tuple.getVal2())); } } // send message - either after regular processing, or after blocking (when enough credits are available again) return down_prot.down(evt); } protected synchronized boolean needToSendCreditRequest() { long current_time=System.nanoTime(); // will most likely send a request the first time (last_credit_request is 0), unless nanoTime() is negative if(current_time - last_credit_request >= TimeUnit.NANOSECONDS.convert(max_block_time, TimeUnit.MILLISECONDS)) { last_credit_request=current_time; return true; } return false; } protected void handleCredit(Address sender, long increase) { credits.replenish(sender, increase); if(log.isTraceEnabled()) { StringBuilder sb=new StringBuilder(); sb.append("received " + increase + " credits from ").append(sender).append(", new credits for " + sender + " : ") .append(credits.get(sender) + ", min_credits=" + credits.getMinCredits()); log.trace(sb); } } protected void handleViewChange(List
      mbrs) { super.handleViewChange(mbrs); Set
      keys=new HashSet<>(credits.keys()); for(Address key: keys) { if(!mbrs.contains(key)) credits.remove(key); } for(Address key: mbrs) credits.putIfAbsent(key); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy