
tinder.patterns.polling.Poller Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tinder-patterns Show documentation
Show all versions of tinder-patterns Show documentation
Programming patterns used by Tinder
The newest version!
/*
* Copyright 2019 Raffaele Ragni.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tinder.patterns.polling;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* Dynamic poller that expands and contracts its waiting time based on the min and max parameters.
* You can use 0 for min and/or max.
*
* @param the type passed between the producer and consumer.
*
* @author Raffaele Ragni
*/
public class Poller implements Runnable {
private final long min;
private final long max;
private final Supplier> producer;
private final Consumer consumer;
private long currentWait;
public Poller(
long min, long max,
Supplier> producer, Consumer consumer) {
this.min = min;
this.max = max;
this.producer = producer;
this.consumer = consumer;
pollIntervalReset();
}
/**
* Sets the minimum time.
* @param min number of seconds to wait minimally
* @return new poller
*/
public Poller min(long min) {
return min(min, TimeUnit.SECONDS);
}
/**
* Sets the maximum time.
* @param max number of seconds to wait maximally
* @return new poller
*/
public Poller max(long max) {
return max(max, TimeUnit.SECONDS);
}
/**
* Sets the minimum time.
* @param min number of time units to wait minimally
* @param timeUnit which time unit to use
* @return new poller
*/
public Poller min(long min, TimeUnit timeUnit) {
min = TimeUnit.MILLISECONDS.convert(min, timeUnit);
if (min < 0) {
throw new IllegalArgumentException("min can't be negative");
}
return new Poller(min, max, producer, consumer);
}
/**
* Sets the maximum time.
* @param max number of time units to wait maximally
* @param timeUnit new poller which time unit to use
* @return new poller
*/
public Poller max(long max, TimeUnit timeUnit) {
max = TimeUnit.MILLISECONDS.convert(max, timeUnit);
if (max < 0) {
throw new IllegalArgumentException("max can't be negative");
}
if (max < min) {
throw new IllegalArgumentException("max cannot be less than min");
}
return new Poller(min, max, producer, consumer);
}
/**
* Creates a new default Poller.
* You will still need to specify a min+max to have wait times.
* The default is to wait nothing (min and max being 0)
* @param Type of data passed between producer and consumer.
* @param producer the producer of some data (as optional). If data is present then the poller keeps going,
* if it's empty() it goes into larder wait times.
* @param consumer consumer of the returned type, without the optional.
* @return new poller.
*/
public static Poller poller(Supplier> producer, Consumer consumer) {
return new Poller(0L, 0L, producer, consumer);
}
/**
* Runs the poller.
* It will keep running forever until the thread gets interrupted so it's recommended to put this inside a thread.
*/
@Override
public void run() {
// Reset to min
pollIntervalReset();
while (!Thread.currentThread().isInterrupted()) {
Optional polledValue = producer.get();
polledValue.ifPresent(consumer);
// If a value was found, we reset the wait to the min because it means there could still be more data to process.
// if no value was found though, we step tp max because no data is there and wait longer.
if (polledValue.isPresent()) {
// Reset to min
pollIntervalReset();
} else {
// Go to max
pollIntervalStepUp();
}
// And now just wait...
pollIntervalWait();
}
}
private void pollIntervalWait() {
if (currentWait > 0L) {
try {
TimeUnit.MILLISECONDS.sleep(currentWait);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
private void pollIntervalReset() {
currentWait = min;
}
private void pollIntervalStepUp() {
currentWait = max;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy