Grid Auto Refresh in every 10 seconds

I need to call an API every 10 seconds and need to refresh the grid with updated data. I read about Polling and Server push, but I cant find the optimal solution in my case.I have tried with @push and a Feederthread (Which handles API request and populate values in grid) but while running the Application, thread is not getting started. Below is my code,

@Route(value = UserNavigation.ROUTE)
@PreserveOnRefresh
@org.springframework.stereotype.Component
public class UserNavigation extends AppLayout {

CCUIConfig config;

    @Autowired
    public UserNavigation( CCUIConfig config) {
    this.config = config;

    addToDrawer(createAccordianMenu());
    }

    private Component createAccordianMenu() {
    VerticalLayout scrollableLayout = new VerticalLayout();

    Div kioskMonitor_div = new Div(kiosksMonitorLabel);
    kioskMonitor_div.addClickListener(event -> {
            try {
                setContent(new Monitor(config).getDashboard());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    scrollableLayout.add(kioskMonitor_div);
    return scrollableLayout;
    }
}


@Push
@Route
public class Monitor extends VerticalLayout{
    

    CCUIConfig config;
    Grid<Model> grid = new Grid<>();
    private FeederThread thread;
    

    public Monitor(CCUIConfig config) {
        this.config = config;
    }
   @Override
    protected void onAttach(AttachEvent attachEvent) {
        // Start the data feed thread
        super.onAttach(attachEvent);
        thread = new FeederThread(attachEvent.getUI(),grid);
        thread.start();
    }
   @Override
    protected void onDetach(DetachEvent detachEvent) {
        thread.interrupt();
        thread = null;
    }

    public  Component getDashboard() throws IOException{
        
        String updateddate =null;

        VerticalLayout dashboardview = new VerticalLayout();
        
        Grid.Column<Model> idColumn = grid.addColumn(Model::getid)
                .setHeader(ID);
        Grid.Column<Model> nameColumn = grid.addColumn(Model::getName)
                .setHeader(Name);
        Grid.Column<Model> memoryColumn = grid.addColumn(Model::getRefreshTime)
                .setHeader(Refresh time"));
        
        dashboardview.add(grid);
        return dashboardview;   
}
}
    


class FeederThread extends Thread {
    private final com.vaadin.flow.component.UI ui;
    private  final  Grid<Model>  grid;
    private final CCUIConfig config;

    private int count = 30;


    public FeederThread(com.vaadin.flow.component.UI ui,Grid<Model> grid) {
        this.config = new CCUIConfig();
        this.ui = ui;
        this.grid= grid;
    }

    @Override
    public void run() {
        while (count>0){
            try {
                Thread.sleep(1000);
                ui.access(()-> {
                    System.out.println("Thread Entry ");
                    try {
                    StringBuilder jsongrid = HttpClientGetRequestClient.executeUrlGet(config.getRefreshAPI());
                    ObjectMapper mapper = new ObjectMapper();
                    List<Model> userlist = new ArrayList<Model>();
                    String date="";
                    if(jsongrid!=null)
                    {
                    ModelWrapper eh = mapper.readValue(jsongrid.toString(), ModelWrapper.class);
                    userlist = eh.getMetricsData();
                    }
                                        
                    if(userlist != null)
                    {
                    grid.setItems(userlist);                
                    grid.getDataProvider().refreshAll();
                    }
                    }catch(JSONException |JsonProcessingException e) {
                        
                        e.printStackTrace();
                    } 

                });
                count--;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


        }
    }

}

UserNavigation is the page that loads after user login, it contains a sidebar with multiple options(or functionalities). One of the functionality is the Monitor screen. Monitor is the page with a grid where we need to refresh it in 30 seconds. FeederThread is the thread class that calls an API and update the data in the grid asynchronously.

As from the above code, what happens is like

onAttach(AttachEvent attachEvent)

is not getting executed so the grid is not getting displayed on the page, we use vaadin 14, any help will be appreciated

I can’t tell from the code (there are syntax errors present) what the context of the grid is. Does the grid even appear in your UI?

I have pasted the basic logic only, as the actual UI have more code. Grid is not appeared in UI. Infact onAttach method is not executing. I have edited the code now, with more details of my flow

Just commenting this piece of code. Do not pass UI reference or instantiate the component in the background thread. Vaadin component cannot be shared with multiple UI’s. Having UI reference in thread is also a recipe for memory leakages etc.

public FeederThread(com.vaadin.flow.component.UI ui,Grid<Model> grid) {
	this.config = new CCUIConfig();
	this.ui = ui;
	this.grid= grid;
}

The answer to the original question can be found in this training video. Download the exercise project linked on the video page. It has a UI with a Grid that is periodically updated from a background thread showing how it is done correctly.

https://vaadin.com/learn/training/v14-push

Also brief comment: You should avoid having a long ui.access() block which contains e.g. calls to external services. Instead, do as much as possible outside the UI.access and only do the updates to components inside the access block.