Search in sources :

Example 1 with CurrentInstance

use of com.vaadin.flow.internal.CurrentInstance in project flow by vaadin.

the class UI method accessSynchronously.

/**
 * Locks the session of this UI and runs the provided command right away.
 * <p>
 * It is generally recommended to use {@link #access(Command)} instead of
 * this method for accessing a session from a different thread as
 * {@link #access(Command)} can be used while holding the lock of another
 * session. To avoid causing deadlocks, this methods throws an exception if
 * it is detected than another session is also locked by the current thread.
 * <p>
 * This method behaves differently than {@link #access(Command)} in some
 * situations:
 * <ul>
 * <li>If the current thread is currently holding the lock of the session,
 * {@link #accessSynchronously(Command)} runs the task right away whereas
 * {@link #access(Command)} defers the task to a later point in time.</li>
 * <li>If some other thread is currently holding the lock for the session,
 * {@link #accessSynchronously(Command)} blocks while waiting for the lock
 * to be available whereas {@link #access(Command)} defers the task to a
 * later point in time.</li>
 * </ul>
 *
 * @since 7.1
 *
 * @param command
 *            the command which accesses the UI
 * @throws UIDetachedException
 *             if the UI is not attached to a session (and locking can
 *             therefore not be done)
 * @throws IllegalStateException
 *             if the current thread holds the lock for another session
 *
 * @see #access(Command)
 * @see VaadinSession#accessSynchronously(Command)
 */
public void accessSynchronously(Command command) throws UIDetachedException {
    Map<Class<?>, CurrentInstance> old = null;
    VaadinSession session = getSession();
    if (session == null) {
        throw new UIDetachedException();
    }
    VaadinService.verifyNoOtherSessionLocked(session);
    session.lock();
    try {
        if (getSession() == null) {
            // acquired the lock.
            throw new UIDetachedException();
        }
        old = CurrentInstance.setCurrent(this);
        command.execute();
    } finally {
        session.unlock();
        if (old != null) {
            CurrentInstance.restoreInstances(old);
        }
    }
}
Also used : CurrentInstance(com.vaadin.flow.internal.CurrentInstance) VaadinSession(com.vaadin.flow.server.VaadinSession)

Example 2 with CurrentInstance

use of com.vaadin.flow.internal.CurrentInstance in project flow by vaadin.

the class ApplicationRunnerServlet method findDeploymentConfiguration.

private DeploymentConfiguration findDeploymentConfiguration(DeploymentConfiguration originalConfiguration) throws Exception {
    // First level of cache
    DeploymentConfiguration configuration = CurrentInstance.get(DeploymentConfiguration.class);
    if (configuration == null) {
        // Not in cache, try to find a VaadinSession to get it from
        VaadinSession session = VaadinSession.getCurrent();
        if (session == null) {
            /*
                 * There's no current session, request or response when serving
                 * static resources, but there's still the current request
                 * maintained by ApplicationRunnerServlet, and there's most
                 * likely also a HttpSession containing a VaadinSession for that
                 * request.
                 */
            HttpServletRequest currentRequest = VaadinServletService.getCurrentServletRequest();
            if (currentRequest != null) {
                HttpSession httpSession = currentRequest.getSession(false);
                if (httpSession != null) {
                    Map<Class<?>, CurrentInstance> oldCurrent = CurrentInstance.setCurrent((VaadinSession) null);
                    try {
                        VaadinServletService service = (VaadinServletService) VaadinService.getCurrent();
                        session = service.findVaadinSession(new VaadinServletRequest(currentRequest, service));
                    } finally {
                        /*
                             * Clear some state set by findVaadinSession to
                             * avoid accidentally depending on it when coding on
                             * e.g. static request handling.
                             */
                        CurrentInstance.restoreInstances(oldCurrent);
                        currentRequest.removeAttribute(VaadinSession.class.getName());
                    }
                }
            }
        }
        if (session != null) {
            String name = ApplicationRunnerServlet.class.getName() + ".deploymentConfiguration";
            try {
                session.lock();
                configuration = (DeploymentConfiguration) session.getAttribute(name);
                if (configuration == null) {
                    ApplicationRunnerServlet servlet = (ApplicationRunnerServlet) VaadinServlet.getCurrent();
                    Class<?> classToRun;
                    try {
                        classToRun = servlet.getClassToRun();
                    } catch (ClassNotFoundException e) {
                        /*
                             * This happens e.g. if the UI class defined in the
                             * URL is not found or if this servlet just serves
                             * static resources while there's some other servlet
                             * that serves the UI (e.g. when using /run-push/).
                             */
                        return originalConfiguration;
                    }
                    CustomDeploymentConfiguration customDeploymentConfiguration = classToRun.getAnnotation(CustomDeploymentConfiguration.class);
                    if (customDeploymentConfiguration != null) {
                        Properties initParameters = new Properties(originalConfiguration.getInitParameters());
                        for (Conf entry : customDeploymentConfiguration.value()) {
                            initParameters.put(entry.name(), entry.value());
                        }
                        initParameters.put(VaadinSession.UI_PARAMETER, getApplicationRunnerApplicationClassName(request.get()));
                        configuration = new DefaultDeploymentConfiguration(servlet.getClass(), initParameters, this::scanForResources);
                    } else {
                        configuration = originalConfiguration;
                    }
                    session.setAttribute(name, configuration);
                }
            } finally {
                session.unlock();
            }
            CurrentInstance.set(DeploymentConfiguration.class, configuration);
        } else {
            configuration = originalConfiguration;
        }
    }
    return configuration;
}
Also used : VaadinSession(com.vaadin.flow.server.VaadinSession) Conf(com.vaadin.flow.uitest.servlet.CustomDeploymentConfiguration.Conf) HttpSession(javax.servlet.http.HttpSession) VaadinServletRequest(com.vaadin.flow.server.VaadinServletRequest) VaadinServletService(com.vaadin.flow.server.VaadinServletService) DefaultDeploymentConfiguration(com.vaadin.flow.server.DefaultDeploymentConfiguration) Properties(java.util.Properties) HttpServletRequest(javax.servlet.http.HttpServletRequest) CurrentInstance(com.vaadin.flow.internal.CurrentInstance) DeploymentConfiguration(com.vaadin.flow.function.DeploymentConfiguration) DefaultDeploymentConfiguration(com.vaadin.flow.server.DefaultDeploymentConfiguration)

Example 3 with CurrentInstance

use of com.vaadin.flow.internal.CurrentInstance in project flow by vaadin.

the class VaadinSession method unlock.

/**
 * Unlocks this session. This method should always be used in a finally
 * block after {@link #lock()} to ensure that the lock is always released.
 * <p>
 * For UIs in this session that have its push mode set to
 * {@link PushMode#AUTOMATIC automatic}, pending changes will be pushed to
 * their respective clients.
 *
 * @see #lock()
 * @see UI#push()
 */
public void unlock() {
    assert hasLock();
    boolean ultimateRelease = false;
    try {
        /*
             * Run pending tasks and push if the reentrant lock will actually be
             * released by this unlock() invocation.
             */
        if (((ReentrantLock) getLockInstance()).getHoldCount() == 1) {
            ultimateRelease = true;
            getService().runPendingAccessTasks(this);
            for (UI ui : getUIs()) {
                if (ui.getPushConfiguration().getPushMode() == PushMode.AUTOMATIC) {
                    Map<Class<?>, CurrentInstance> oldCurrent = CurrentInstance.setCurrent(ui);
                    try {
                        ui.push();
                    } finally {
                        CurrentInstance.restoreInstances(oldCurrent);
                    }
                }
            }
        }
    } finally {
        getLockInstance().unlock();
    }
    /*
         * If the session is locked when a new access task is added, it is
         * assumed that the queue will be purged when the lock is released. This
         * might however not happen if a task is enqueued between the moment
         * when unlock() purges the queue and the moment when the lock is
         * actually released. This means that the queue should be purged again
         * if it is not empty after unlocking.
         */
    if (ultimateRelease && !getPendingAccessQueue().isEmpty()) {
        getService().ensureAccessQueuePurged(this);
    }
}
Also used : UI(com.vaadin.flow.component.UI) CurrentInstance(com.vaadin.flow.internal.CurrentInstance)

Aggregations

CurrentInstance (com.vaadin.flow.internal.CurrentInstance)3 VaadinSession (com.vaadin.flow.server.VaadinSession)2 UI (com.vaadin.flow.component.UI)1 DeploymentConfiguration (com.vaadin.flow.function.DeploymentConfiguration)1 DefaultDeploymentConfiguration (com.vaadin.flow.server.DefaultDeploymentConfiguration)1 VaadinServletRequest (com.vaadin.flow.server.VaadinServletRequest)1 VaadinServletService (com.vaadin.flow.server.VaadinServletService)1 Conf (com.vaadin.flow.uitest.servlet.CustomDeploymentConfiguration.Conf)1 Properties (java.util.Properties)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1 HttpSession (javax.servlet.http.HttpSession)1