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

com.liferay.portal.kernel.concurrent.AsyncBroker Maven / Gradle / Ivy

Go to download

Contains interfaces for the portal services. Interfaces are only loaded by the global class loader and are shared by all plugins.

There is a newer version: 156.0.0
Show newest version
/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */

package com.liferay.portal.kernel.concurrent;

import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.memory.FinalizeAction;
import com.liferay.portal.kernel.memory.FinalizeManager;
import com.liferay.portal.kernel.util.ReflectionUtil;

import java.lang.ref.Reference;
import java.lang.reflect.Field;

import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Future;

/**
 * @author Shuyang Zhou
 */
public class AsyncBroker {

	public Map> getOpenBids() {
		return Collections.>unmodifiableMap(
			_defaultNoticeableFutures);
	}

	public NoticeableFuture post(K key) {
		DefaultNoticeableFuture defaultNoticeableFuture =
			new DefaultNoticeableFuture<>();

		NoticeableFuture previousNoticeableFuture = post(
			key, defaultNoticeableFuture);

		if (previousNoticeableFuture == null) {
			return defaultNoticeableFuture;
		}

		return previousNoticeableFuture;
	}

	public NoticeableFuture post(
		final K key, final DefaultNoticeableFuture defaultNoticeableFuture) {

		DefaultNoticeableFuture previousDefaultNoticeableFuture =
			_defaultNoticeableFutures.putIfAbsent(key, defaultNoticeableFuture);

		if (previousDefaultNoticeableFuture != null) {
			return previousDefaultNoticeableFuture;
		}

		defaultNoticeableFuture.addFutureListener(
			new FutureListener() {

				@Override
				public void complete(Future future) {
					_defaultNoticeableFutures.remove(
						key, defaultNoticeableFuture);
				}

			});

		if (_REFERENT_FIELD != null) {
			FinalizeManager.register(
				defaultNoticeableFuture, new CancellationFinalizeAction(key),
				FinalizeManager.PHANTOM_REFERENCE_FACTORY);
		}

		return null;
	}

	public NoticeableFuture take(K key) {
		return _defaultNoticeableFutures.remove(key);
	}

	public boolean takeWithException(K key, Throwable throwable) {
		DefaultNoticeableFuture defaultNoticeableFuture =
			_defaultNoticeableFutures.remove(key);

		if (defaultNoticeableFuture == null) {
			return false;
		}

		defaultNoticeableFuture.setException(throwable);

		return true;
	}

	public boolean takeWithResult(K key, V result) {
		DefaultNoticeableFuture defaultNoticeableFuture =
			_defaultNoticeableFutures.remove(key);

		if (defaultNoticeableFuture == null) {
			return false;
		}

		defaultNoticeableFuture.set(result);

		return true;
	}

	private static final Field _REFERENT_FIELD;

	private static final Log _log = LogFactoryUtil.getLog(AsyncBroker.class);

	static {
		Field referentField = null;

		try {
			referentField = ReflectionUtil.getDeclaredField(
				Reference.class, "referent");
		}
		catch (Throwable t) {
			if (_log.isWarnEnabled()) {
				_log.warn(
					"Cancellation of orphaned noticeable futures is disabled " +
						"because the JVM does not support phantom reference " +
							"resurrection",
					t);
			}
		}

		_REFERENT_FIELD = referentField;
	}

	private final ConcurrentMap>
		_defaultNoticeableFutures = new ConcurrentReferenceValueHashMap<>(
			FinalizeManager.WEAK_REFERENCE_FACTORY);

	private static class CancellationFinalizeAction implements FinalizeAction {

		public CancellationFinalizeAction(Object key) {
			_key = key;
		}

		@Override
		public void doFinalize(final Reference reference) {
			try {
				NoticeableFuture noticeableFuture =
					(NoticeableFuture)_REFERENT_FIELD.get(reference);

				if (noticeableFuture.cancel(true) && _log.isWarnEnabled()) {
					_log.warn(
						"Cancelled orphan noticeable future " +
							noticeableFuture + " with key " + _key);
				}
			}
			catch (Exception e) {
				_log.error("Unable to access referent of " + reference, e);
			}
		}

		private final Object _key;

	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy