Skip to content

Commit

Permalink
Rate limit bonjour notifications to 30 per minute. Use property rende…
Browse files Browse the repository at this point in the history
…zvous.notification.limit to set other value.

Former-commit-id: 858ccd8a5bceab2caee82bd7007209c631f904c4
  • Loading branch information
dkocher committed Aug 18, 2013
1 parent 613f6ee commit f38e342
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 10 deletions.
59 changes: 49 additions & 10 deletions source/ch/cyberduck/core/AbstractRendezvous.java
Expand Up @@ -20,6 +20,7 @@
*/

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.concurrent.TimedSemaphore;
import org.apache.log4j.Logger;

import java.util.Collections;
Expand All @@ -29,6 +30,7 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

public abstract class AbstractRendezvous implements Rendezvous {
private static Logger log = Logger.getLogger(AbstractRendezvous.class);
Expand Down Expand Up @@ -81,6 +83,8 @@ public String[] getServiceTypes() {
private Set<RendezvousListener> listeners =
Collections.synchronizedSet(new HashSet<RendezvousListener>());

private RendezvousListener notifier = new LimitedRendezvousListener();

/**
* Register a listener to be notified
*
Expand Down Expand Up @@ -194,12 +198,7 @@ protected void add(final String fullname, final Host host) {
log.debug(String.format("Add resolved host %s for full name %s", host, fullname));
}
if(null == services.put(fullname, host)) {
if(log.isInfoEnabled()) {
log.info(String.format("Service resolved with identifier %s with %s", fullname, host));
}
for(RendezvousListener listener : listeners) {
listener.serviceResolved(fullname, host);
}
notifier.serviceResolved(fullname, host);
}
}

Expand All @@ -210,11 +209,51 @@ protected void remove(final String identifier) {
if(null == services.remove(identifier)) {
return;
}
if(log.isInfoEnabled()) {
log.info(String.format("Service with name %s lost", identifier));
notifier.serviceLost(identifier);
}

private final class LimitedRendezvousListener implements RendezvousListener {
/**
* Rate limit for notifications
*/
private TimedSemaphore limit
= new TimedSemaphore(1L, TimeUnit.MINUTES, Preferences.instance().getInteger("rendezvous.notification.limit"));

@Override
public void serviceResolved(final String identifier, final Host host) {
if(log.isInfoEnabled()) {
log.info(String.format("Service resolved with identifier %s with %s", identifier, host));
}
if(this.acquire()) {
for(RendezvousListener listener : listeners) {
listener.serviceResolved(identifier, host);
}
}
}

@Override
public void serviceLost(final String servicename) {
if(log.isInfoEnabled()) {
log.info(String.format("Service with name %s lost", servicename));
}
if(this.acquire()) {
for(RendezvousListener listener : listeners) {
listener.serviceLost(servicename);
}
}
}
for(RendezvousListener listener : listeners) {
listener.serviceLost(identifier);

private boolean acquire() {
if(limit.getAvailablePermits() > 0) {
try {
limit.acquire();
return true;
}
catch(InterruptedException e) {
log.warn(String.format("Failure acquiring lock %s", e.getMessage()));
}
}
return false;
}
}
}
1 change: 1 addition & 0 deletions source/ch/cyberduck/core/Preferences.java
Expand Up @@ -193,6 +193,7 @@ protected void setDefaults() {

defaults.put("rendezvous.enable", String.valueOf(true));
defaults.put("rendezvous.loopback.supress", String.valueOf(true));
defaults.put("rendezvous.notification.limit", String.valueOf(30));

defaults.put("growl.enable", String.valueOf(true));

Expand Down

0 comments on commit f38e342

Please sign in to comment.