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

com.github.thorbenkuck.network.stream.SimpleSubscription Maven / Gradle / Ivy

package com.github.thorbenkuck.network.stream;

import java.util.ArrayList;
import java.util.List;

class SimpleSubscription implements NotifiableSubscription {

	private Subscriber subscriber;
	private final List throwableBuffer = new ArrayList<>();
	private final Object lock = new Object();
	private final Object cancelLock = new Object();
	private final Object referenceLock = new Object();
	private Reference> reference;
	private Runnable onCancel;

	SimpleSubscription(Subscriber subscriber, Reference> reference) {
		this.subscriber = subscriber;
		this.reference = reference;
	}

	private void addThrowable(Throwable throwable) {
		try {
			subscriber.onError(throwable);
		} catch (Throwable e) {
			synchronized (throwableBuffer) {
				throwableBuffer.add(throwable);
			}
		}
	}

	@Override
	public void notify(T t) {
		synchronized (lock) {
			if (!isCanceled()) {
				try {
					subscriber.accept(t);
				} catch (Throwable throwable) {
					throwable.printStackTrace();
					addThrowable(throwable);
				}
			}
		}
	}

	@Override
	public void notify(Throwable throwable) {
		addThrowable(throwable);
	}

	@Override
	public boolean isCanceled() {
		synchronized (referenceLock) {
			return subscriber == null;
		}
	}

	@Override
	public void cancel() {
		if (isCanceled()) {
			return;
		}
		synchronized (lock) {
			if (subscriber != null) {
				subscriber.onCancel();
				subscriber = null;
			}

			synchronized (referenceLock) {
				if (reference != null) {
					reference.remove(this);
					reference = null;
				}
			}

			synchronized (cancelLock) {
				if (onCancel != null) {
					try {
						onCancel.run();
					} catch (Throwable t) {
						addThrowable(t);
					}
					onCancel = null;
				}
			}
		}
	}

	@Override
	public void setOnCancel(Runnable runnable) {
		synchronized (cancelLock) {
			this.onCancel = runnable;
		}
	}

	@Override
	public List drainEncountered() {
		List toReturn;
		synchronized (throwableBuffer) {
			toReturn = new ArrayList<>(throwableBuffer);
		}
		throwableBuffer.clear();
		return toReturn;
	}

	@Override
	public boolean hasEncounteredErrors() {
		synchronized (throwableBuffer) {
			return !throwableBuffer.isEmpty();
		}
	}

	@Override
	public String toString() {
		return "SimpleSubscription{" + "subscriber=" + subscriber +
				", throwableBuffer=" + throwableBuffer +
				", onCancel=" + onCancel +
				'}';
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy