com.microsoft.azure.servicebus.primitives.ClientEntity Maven / Gradle / Ivy
Show all versions of azure-servicebus Show documentation
/*
* 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.servicebus.primitives;
import java.util.Locale;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
/**
* Contract for all client entities with Open-Close/Abort state m/c
* main-purpose: closeAll related entities
* Internal-class
* @since 1.0
*/
public abstract class ClientEntity
{
private final String clientId;
private final Object syncClose;
private boolean isClosing;
private boolean isClosed;
protected ClientEntity(final String clientId)
{
this.clientId = clientId;
this.syncClose = new Object();
}
protected abstract CompletableFuture onClose();
public String getClientId()
{
return this.clientId;
}
protected boolean getIsClosed()
{
synchronized (this.syncClose)
{
return this.isClosed;
}
}
protected boolean getIsClosingOrClosed()
{
synchronized (this.syncClose)
{
return this.isClosing || this.isClosed;
}
}
// used to force close when entity is faulted
protected final void setClosed()
{
synchronized (this.syncClose)
{
this.isClosed = true;
}
}
public final CompletableFuture closeAsync()
{
if(this.getIsClosingOrClosed())
{
return CompletableFuture.completedFuture(null);
}
synchronized (this.syncClose)
{
this.isClosing = true;
}
return this.onClose().thenRunAsync(new Runnable()
{
@Override
public void run()
{
synchronized (ClientEntity.this.syncClose)
{
ClientEntity.this.isClosing = false;
ClientEntity.this.isClosed = true;
}
}}, MessagingFactory.INTERNAL_THREAD_POOL);
}
public final void close() throws ServiceBusException
{
try
{
this.closeAsync().get();
}
catch (InterruptedException|ExecutionException exception)
{
if (exception instanceof InterruptedException)
{
// Re-assert the thread's interrupted status
Thread.currentThread().interrupt();
}
Throwable throwable = exception.getCause();
if (throwable != null)
{
if (throwable instanceof RuntimeException)
{
throw (RuntimeException)throwable;
}
if (throwable instanceof ServiceBusException)
{
throw (ServiceBusException)throwable;
}
throw new ServiceBusException(true, throwable);
}
}
}
protected final void throwIfClosed(Throwable cause)
{
if (this.getIsClosingOrClosed())
{
throw new IllegalStateException(String.format(Locale.US, "Operation not allowed after the %s instance is closed.", this.getClass().getName()), cause);
}
}
@Override
protected void finalize()
{
try {
if(!this.isClosed)
{
this.close();
}
super.finalize();
} catch (Throwable e) {
//Ignore
}
}
}