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

org.jgroups.util.Delayer Maven / Gradle / Ivy

There is a newer version: 5.4.1.Final
Show newest version
package org.jgroups.util;

import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
 * Collects actions by key and executes them - if a predicate is true - every N ms.
 * @author Bela Ban
 * @since  5.3.1
 */
public class Delayer {
    protected long         timeout=2000; // ms
    protected Map map=new ConcurrentHashMap<>();

    public Delayer(long timeout) {
        this.timeout=timeout;
    }

    public long       timeout()       {return timeout;}
    public Delayer timeout(long t) {timeout=t; return this;}
    public int        size()          {return map.size();}
    public int        done()          {return (int)map.values().stream().filter(Entry::done).count();}

    public Delayer add(T key, Predicate pred, Consumer action) {
        map.computeIfAbsent(key, k -> new Entry(k, pred, action).run());
        return this;
    }

    public Delayer clear() {
        map.values().forEach(e -> {
            if(e.f != null)
                e.f.cancel(true);
        });
        map.clear();
        return this;
    }

    @Override
    public String toString() {
        return String.format("%d entries (%d done)", size(), done());
    }

    protected class Entry {
        protected T                       key;
        protected Predicate            pred;
        protected Consumer       action;
        protected CompletableFuture f;

        public Entry(T key, Predicate pred, Consumer action) {
            this.key=key;
            this.pred=pred;
            this.action=action;
        }

        public boolean done() {
            return f.isDone();
        }

        public Entry run() {
            f=CompletableFuture.supplyAsync(() -> Util.waitUntilTrue(timeout, timeout / 10, () -> pred.test(key)))
              .thenAccept(success -> {
                  try {
                      action.accept(success);
                  }
                  finally {
                      map.remove(key);
                  }
              });
            return this;
        }

        @Override
        public String toString() {
            return String.format("%s: done=%b", key, done());
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy