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

org.eclipse.jetty.http2.WindowRateControl Maven / Gradle / Ivy

The newest version!
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.http2;

import java.time.Duration;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;

import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.NanoTime;

/**
 * 

An implementation of {@link RateControl} that limits the number of * events within a time period.

*

Events are kept in a queue and for each event the queue is first * drained of the old events outside the time window, and then the new * event is added to the queue. The size of the queue is maintained * separately in an AtomicInteger and if it exceeds the max * number of events then {@link #onEvent(Object)} returns {@code false}.

*/ public class WindowRateControl implements RateControl { private final Queue events = new ConcurrentLinkedQueue<>(); private final AtomicInteger size = new AtomicInteger(); private final int maxEvents; private final long window; public static WindowRateControl fromEventsPerSecond(int maxEvents) { return new WindowRateControl(maxEvents, Duration.ofSeconds(1)); } public WindowRateControl(int maxEvents, Duration window) { this.maxEvents = maxEvents; this.window = window.toNanos(); if (this.window == 0) throw new IllegalArgumentException("Invalid duration " + window); } public int getEventsPerSecond() { try { long rate = maxEvents * 1_000_000_000L / window; return Math.toIntExact(rate); } catch (ArithmeticException x) { return Integer.MAX_VALUE; } } @Override public boolean onEvent(Object event) { long now = NanoTime.now(); while (true) { Long time = events.peek(); if (time == null) break; if (NanoTime.isBefore(now, time)) break; if (events.remove(time)) size.decrementAndGet(); } events.add(now + window); return size.incrementAndGet() <= maxEvents; } public static class Factory implements RateControl.Factory { private final int maxEventRate; public Factory(int maxEventRate) { this.maxEventRate = maxEventRate; } @Override public RateControl newRateControl(EndPoint endPoint) { return WindowRateControl.fromEventsPerSecond(maxEventRate); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy