001/*
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2022, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014
015package ch.qos.logback.core.util;
016
017import java.util.concurrent.atomic.AtomicLong;
018import java.util.function.LongBinaryOperator;
019import java.util.function.LongUnaryOperator;
020import java.util.function.UnaryOperator;
021
022/**
023 * An invocation gate using very simple logic.
024 *
025 * @since 1.3.6/1.4.6
026 */
027public class SimpleInvocationGate implements InvocationGate {
028
029    //volatile long next = 0;
030
031    AtomicLong atomicNext = new AtomicLong(0);
032    final Duration increment;
033
034    // 60 seconds by default
035    final public static Duration DEFAULT_INCREMENT = Duration.buildBySeconds(60);
036
037    public SimpleInvocationGate() {
038        this(DEFAULT_INCREMENT);
039    }
040
041    public SimpleInvocationGate(Duration anIncrement) {
042        this.increment = anIncrement;
043    }
044
045    @Override
046    public boolean isTooSoon(long currentTime) {
047        if (currentTime == -1)
048            return false;
049
050        long localNext = atomicNext.get();
051        if (currentTime >= localNext) {
052            long next2 = currentTime+increment.getMilliseconds();
053            // if success, we were able to set the variable, otherwise some other thread beat us to it
054            boolean success = atomicNext.compareAndSet(localNext, next2);
055            // while we have crossed 'next', the other thread already returned true. There is
056            // no point in letting more than one thread per duration.
057            return !success;
058        } else {
059            return true;
060        }
061
062    }
063
064
065}
066
067//    private final boolean isTooSoonSynchronized(long currentTime) {
068//        if (currentTime == -1)
069//            return false;
070//
071//        synchronized (this) {
072//            if (currentTime >= next) {
073//                next = currentTime + increment;
074//                return false;
075//            }
076//        }
077//        return true;
078//    }
079