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

com.microsoft.azure.eventhubs.FaultTolerantObject Maven / Gradle / Ivy

There is a newer version: 3.3.0
Show newest version
/*
 * Copyright (c) Microsoft. All rights reserved.
 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
 */
package com.microsoft.azure.eventhubs;

import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import com.microsoft.azure.eventhubs.amqp.DispatchHandler;
import com.microsoft.azure.eventhubs.amqp.IIOObject;
import com.microsoft.azure.eventhubs.amqp.IOperation;
import com.microsoft.azure.eventhubs.amqp.IOperationResult;
import com.microsoft.azure.eventhubs.amqp.ReactorDispatcher;

public class FaultTolerantObject {

    final IOperation openTask;
    final IOperation closeTask;
    final Queue> openCallbacks;
    final Queue> closeCallbacks;

    T innerObject;
    boolean creatingNewInnerObject;
    boolean closingInnerObject;

    public FaultTolerantObject(
            final IOperation openAsync,
            final IOperation closeAsync) {

        this.openTask = openAsync;
        this.closeTask = closeAsync;
        this.openCallbacks = new ConcurrentLinkedQueue<>();
        this.closeCallbacks = new ConcurrentLinkedQueue<>();
    }

    // should be invoked from reactor thread
    public T unsafeGetIfOpened() {

        if (innerObject != null && innerObject.getState() == IIOObject.IOObjectState.OPENED)
            return innerObject;

        return null;
    }

    public void runOnOpenedObject(
            final ReactorDispatcher dispatcher,
            final IOperationResult openCallback) {

        try {
            dispatcher.invoke(new DispatchHandler() {
                @Override
                public void onEvent() {
                    if (!creatingNewInnerObject
                            && (innerObject == null || innerObject.getState() == IIOObject.IOObjectState.CLOSED || innerObject.getState() == IIOObject.IOObjectState.CLOSING)) {
                        creatingNewInnerObject = true;
                        openCallbacks.offer(openCallback);
                        openTask.run(new IOperationResult() {
                            @Override
                            public void onComplete(T result) {
                                creatingNewInnerObject = false;
                                innerObject = result;
                                for (IOperationResult callback : openCallbacks)
                                    callback.onComplete(result);

                                openCallbacks.clear();
                            }

                            @Override
                            public void onError(Exception error) {
                                creatingNewInnerObject = false;
                                for (IOperationResult callback : openCallbacks)
                                    callback.onError(error);

                                openCallbacks.clear();
                            }
                        });
                    } else if (innerObject != null && innerObject.getState() == IIOObject.IOObjectState.OPENED) {
                        openCallback.onComplete(innerObject);
                    } else {
                        openCallbacks.offer(openCallback);
                    }
                }
            });
        } catch (IOException ioException) {
            openCallback.onError(ioException);
        }
    }

    public void close(
            final ReactorDispatcher dispatcher,
            final IOperationResult closeCallback) {

        try {
            dispatcher.invoke(new DispatchHandler() {
                @Override
                public void onEvent() {
                    if (innerObject == null || innerObject.getState() == IIOObject.IOObjectState.CLOSED) {
                        closeCallback.onComplete(null);
                    } else if (!closingInnerObject && (innerObject.getState() == IIOObject.IOObjectState.OPENED || innerObject.getState() == IIOObject.IOObjectState.OPENING)) {
                        closingInnerObject = true;
                        closeCallbacks.offer(closeCallback);
                        closeTask.run(new IOperationResult() {
                            @Override
                            public void onComplete(Void result) {
                                closingInnerObject = false;
                                for (IOperationResult callback : closeCallbacks)
                                    callback.onComplete(result);

                                closeCallbacks.clear();
                            }

                            @Override
                            public void onError(Exception error) {
                                closingInnerObject = false;
                                for (IOperationResult callback : closeCallbacks)
                                    callback.onError(error);

                                closeCallbacks.clear();
                            }
                        });
                    } else {
                        closeCallbacks.offer(closeCallback);
                    }
                }
            });
        } catch (IOException ioException) {
            closeCallback.onError(ioException);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy