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

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

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.azure.eventhubs.impl;

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

public class FaultTolerantObject {

    private final Operation openTask;
    private final Operation closeTask;
    private final Queue> openCallbacks;
    private final Queue> closeCallbacks;

    private T innerObject;
    private boolean creatingNewInnerObject;
    private boolean closingInnerObject;

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

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

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

        if (innerObject != null && innerObject.getState() == IOObject.IOObjectState.OPENED) {
            return innerObject;
        }
        return null;
    }

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

        try {
            dispatcher.invoke(new DispatchHandler() {
                @Override
                public void onEvent() {
                    if (!creatingNewInnerObject
                            && (innerObject == null || innerObject.getState() == IOObject.IOObjectState.CLOSED
                        || innerObject.getState() == IOObject.IOObjectState.CLOSING)) {
                        creatingNewInnerObject = true;

                        try {
                            openCallbacks.offer(openCallback);
                            openTask.run(new OperationResult() {
                                @Override
                                public void onComplete(T result) {
                                    innerObject = result;
                                    for (OperationResult callback : openCallbacks) {
                                        callback.onComplete(result);
                                    }

                                    openCallbacks.clear();
                                }

                                @Override
                                public void onError(Exception error) {
                                    for (OperationResult callback : openCallbacks) {
                                        callback.onError(error);
                                    }

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

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

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

                            @Override
                            public void onError(Exception error) {
                                closingInnerObject = false;
                                for (OperationResult callback : closeCallbacks) {
                                    callback.onError(error);
                                }
                                closeCallbacks.clear();
                            }
                        });
                    } else {
                        closeCallbacks.offer(closeCallback);
                    }
                }
            });
        } catch (IOException ioException) {
            closeCallback.onError(ioException);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy