Search in sources :

Example 1 with BeanCreationException

use of org.eclipse.scout.rt.platform.exception.BeanCreationException in project scout.rt by eclipse.

the class DefaultBeanInstanceProducer method getApplicationScopedInstance.

private T getApplicationScopedInstance(final IBean<T> bean) {
    T instance = m_applicationScopedInstance.get();
    if (instance != null) {
        return instance;
    }
    if (m_creatorThread.compareAndSet(null, Thread.currentThread())) {
        try {
            // check again to avoid race conditions
            instance = m_applicationScopedInstance.get();
            if (instance != null) {
                return instance;
            }
            // current thread has to create instance
            instance = safeCreateInstance(bean.getBeanClazz());
            m_applicationScopedInstance.set(instance);
            return instance;
        } finally {
            synchronized (this) {
                // reset creator thread so that another one tries to create the bean again in case the current ran into an exception.
                m_creatorThread.set(null);
                // wake up other threads waiting on the application-scoped instance
                this.notifyAll();
            }
        }
    }
    // remember creator thread for logging purposes
    final Thread creatorThread = m_creatorThread.get();
    final int maxWaitTimeSeconds = getDeadlockDetectionMaxWaitTimeSeconds();
    final long maxWaitEndTimeMillis = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(maxWaitTimeSeconds);
    boolean logDebug = LOG.isDebugEnabled();
    do {
        try {
            synchronized (this) {
                if (m_creatorThread.get() == null) {
                    break;
                }
                long waitTimeMillis = logDebug ? TimeUnit.SECONDS.toMillis(Math.min(maxWaitTimeSeconds, DEADLOCK_DETECTION_DEBUG_WAIT_TIME_SECONDS)) : maxWaitEndTimeMillis - System.currentTimeMillis();
                if (waitTimeMillis > 0) {
                    // wait for the creator to complete, but not too long because the notify signal could have been missed
                    this.wait(waitTimeMillis);
                }
            }
        } catch (InterruptedException e) {
            throw new ThreadInterruptedError("Thread has been interrupted");
        }
        if (m_creatorThread.get() == null) {
            break;
        }
        if (logDebug) {
            logWarnPotentialDeadlock(creatorThread);
            logDebug = false;
        }
    } while (// try as long as the other thread is still creating the bean and the max wait time has not been elapsed
    System.currentTimeMillis() < maxWaitEndTimeMillis);
    // check if bean has been created in the meantime
    instance = m_applicationScopedInstance.get();
    if (instance != null) {
        return instance;
    }
    // bean has not been created
    if (System.currentTimeMillis() < maxWaitEndTimeMillis) {
        throw new BeanCreationException("Thread was waiting on bean instance creator thread which most likely failed (check the log).").withContextInfo("beanClass", bean == null || bean.getBeanClazz() == null ? "n/a" : bean.getBeanClazz().getName()).withContextInfo("creatorThreadID", creatorThread == null ? "n/a" : creatorThread.getId()).withContextInfo("creatorThreadName", creatorThread == null ? "n/a" : creatorThread.getName());
    } else {
        logWarnPotentialDeadlock(creatorThread);
        throw new BeanCreationException("Potential deadlock detected: bean is being created by another thread. Either the creation takes longer than {}s " + "or the current and the creator threads are blocking each other (check the log).", maxWaitTimeSeconds).withContextInfo("beanClass", bean == null || bean.getBeanClazz() == null ? "n/a" : bean.getBeanClazz().getName()).withContextInfo("creatorThreadID", creatorThread == null ? "n/a" : creatorThread.getId()).withContextInfo("creatorThreadName", creatorThread == null ? "n/a" : creatorThread.getName());
    }
}
Also used : BeanCreationException(org.eclipse.scout.rt.platform.exception.BeanCreationException) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError)

Aggregations

BeanCreationException (org.eclipse.scout.rt.platform.exception.BeanCreationException)1 ThreadInterruptedError (org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError)1