Home > Back-end >  Vaadin why not show notification in multiThreads app
Vaadin why not show notification in multiThreads app

Time:06-07

My problem is that in my app not show notification.

My application does that each time a button is pressed I create new thread and show notification with info that thread is running or waiting (this works fine). Then, if the thread is running, it will randomly sleep for 5-10 seconds and get data from the rest api and a notification should be displayed that the thread is finished (this notification is not displayed).

Fineshed notifications show after i press again button. As you can see in the image.

Image: enter image description here

constructor view:

public MainView() {
    Button ipButton = getIpButton();

    setMargin(true);
    setHorizontalComponentAlignment(Alignment.START, ipButton);

    add(ipButton);
}

button:

private Button getIpButton() {
        final UI ui = UI.getCurrent();
        final VaadinSession session = VaadinSession.getCurrent();

        Button ipButton = new Button("My IP");

        AtomicInteger orderIndex = new AtomicInteger();

        ipButton.addClickListener(_e -> {
            int orderThread = orderIndex.getAndIncrement();
            openBeginNotification(orderThread);

            executor.submit(() -> {
                try {
                    UI.setCurrent(ui);
                    VaadinSession.setCurrent(session);

                    long sleepTime = (long) (Math.random() * (10 - 5)   5);
                    System.out.printf("%d: %ds\n", orderThread, sleepTime);

                    Thread.sleep(sleepTime * 1000);

                    IpDTO ip = restTemplate.getForObject("http://ip.jsontest.com/", IpDTO.class);
                    System.out.printf("%d: %s\n", orderThread, ip);

                    try {
                        VaadinSession.getCurrent().lock();
                        getFinishNotification(orderThread).open(); // here not show notification
                        VaadinSession.getCurrent().unlock();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
        });

    return ipButton;
}

notification methods:

private void openBeginNotification(int orderThread) {
    Notification notification;
    if (executor.getActiveCount() == MAX_THREADS) {
        // thread is in front
        notification = getWaitNotification(orderThread);
    }  else {
        // thread run
        notification = getRunNotification(orderThread);
    }
    notification.open();
}

private Notification getRunNotification(int orderThread) {
    return getNotification("Task "   orderThread   ": run", NotificationVariant.LUMO_PRIMARY);
}

private Notification getWaitNotification(int orderThread) {
    return getNotification("Task "   orderThread   ": wait", NotificationVariant.LUMO_CONTRAST);
}

private Notification getFinishNotification(int orderThread) {
    return getNotification("Task "   orderThread   ": finish", NotificationVariant.LUMO_SUCCESS);
}

private Notification getNotification(String notificationText, NotificationVariant variant) {
    Notification notification = new Notification(notificationText, 1000);
    notification.addThemeVariants(variant);

    return notification;
}

CodePudding user response:

First, you need to enable @Push to make Vaadin open a websocket connection that makes it possible for the server to directly send messages to the browser without waiting for the browser to send a message asking for changes (which happens when you click a button). The @Push annotation should be in different location depending on the Vaadin version you're using, so please refer to documentation to find the right place.

Second, please use UI::access instead of manually doing setCurrent and locking. While I didn't spot anything in your example that would break the happy case, there are still also a whole bunch of edge cases that you'd need to take into account. As an example, you're not cleaning up after setCurrent which might cause memory leaks and you're not unlocking in case something related to the notification throws an exception.

  • Related