Asynchronous Updates

This section describes to use server push from your application code. See Server Push Configuration for an overall description on what server push means and how to configure your application to use server push.

Making changes to a UI from another thread and pushing them to the browser requires locking the user session. Otherwise, the UI update done from another thread could conflict with a regular event-driven update and cause either data corruption or deadlocks. Because of this, you may only access an UI using the access() method, which locks the session to prevent conflicts. It takes as parameter a Command to execute while the session is locked.

For example:

Java

  1. ui.access(new Command() {
  2. @Override
  3. public void execute() {
  4. statusLabel.setText(statusText);
  5. }
  6. });

You also use a simple lambda expression to define your access command.

Java

  1. ui.access(() -> statusLabel.setText(statusText));

If the push mode is manual, you need to push the pending UI changes to the browser explicitly with the push() method.

Java

  1. ui.access(() -> {
  2. statusLabel.setText(statusText);
  3. ui.push();
  4. });

Below is a complete example of a case where we make UI changes from another thread.

Java

  1. @Push
  2. @Route("push")
  3. public class PushyView extends VerticalLayout {
  4. private FeederThread thread;
  5. @Override
  6. protected void onAttach(AttachEvent attachEvent) {
  7. add(new Span("Waiting for updates"));
  8. // Start the data feed thread
  9. thread = new FeederThread(attachEvent.getUI(), this);
  10. thread.start();
  11. }
  12. @Override
  13. protected void onDetach(DetachEvent detachEvent) {
  14. // Cleanup
  15. thread.interrupt();
  16. thread = null;
  17. }
  18. private static class FeederThread extends Thread {
  19. private final UI ui;
  20. private final PushyView view;
  21. private int count = 0;
  22. public FeederThread(UI ui, PushyView view) {
  23. this.ui = ui;
  24. this.view = view;
  25. }
  26. @Override
  27. public void run() {
  28. try {
  29. // Update the data for a while
  30. while (count < 10) {
  31. // Sleep to emulate background work
  32. Thread.sleep(500);
  33. String message = "This is update " + count++;
  34. ui.access(() -> view.add(new Span(message)));
  35. }
  36. // Inform that we are done
  37. ui.access(() -> {
  38. view.add(new Span("Done updating"));
  39. });
  40. } catch (InterruptedException e) {
  41. e.printStackTrace();
  42. }
  43. }
  44. }
  45. }

When sharing data between UIs or user sessions, you need to consider the message-passing mechanism more carefully, as explained in Creating Collaborative Views.