Updating Remote Render Window based on Timed Thread

I am trying to accomplish the exact same thing as the OP. I am using a paraview server in python as the back end. The problem comes when I try to update the render from the timed thread. At first I tried something like this in my server initialize method:

    def update():
        while True:
            self.cnt = self.cnt + 1
            text.Text = str(self.cnt)
            simple.Render()
            self.getApplication().InvokeEvent('UpdateEvent')
            time.sleep(5)
    
    t1 = threading.Thread(target=update)
    t1.start()

As soon as the thread fires however, the remote goes blank and I see this error on the console:
( 422.694s) [ BFBE5700] vtkEGLRenderWindow.cxx:569 WARN| vtkEGLRenderWindow (0x17db77f0): Unable to eglMakeCurrent: 12290

After some research, it appears that you should not call any render functions from a different thread. I changed my thread to invoke a custom event and added an observer for that event in my initialize method that updates the text. I am still seeing the same egl error.

Is there some better pattern for getting a timed callback where I can update what I am rendering without any client interaction?

Here is my full initialize method:

def initialize(self):
    # Bring used components
    self.registerVtkWebProtocol(pv_protocols.ParaViewWebMouseHandler())
    self.registerVtkWebProtocol(pv_protocols.ParaViewWebViewPort())
    self.registerVtkWebProtocol(
        pv_protocols.ParaViewWebPublishImageDelivery(decode=False))
    self.registerVtkWebProtocol(pv_protocols.ParaViewWebFileListing("/home/perception", "Home", "", ""))
    self.updateSecret(DemoServer.authKey)

    # tell the C++ web app to use no encoding.
    # ParaViewWebPublishImageDelivery must be set to decode=False to match.
    self.getApplication().SetImageEncoding(0)

    # Disable interactor-based render calls
    simple.GetRenderView().EnableRenderOnInteraction = 0
    simple.GetRenderView().Background = [0, 0, 0]
    cone = simple.Cone()
    text = simple.Text()
    text.Text = "Hello"
    simple.Show(cone)
    simple.Show(text)
    simple.Render()
    
    rcallback = lambda *args, **kwargs: self.rupdate(text)
    
    tag = self.getApplication().AddObserver('TUpdate', rcallback)
            
    def update():
        while True:
            self.getApplication().InvokeEvent('TUpdate')
            time.sleep(5)
    
    t1 = threading.Thread(target=update)
    t1.start()
    

    # Update interaction mode
    pxm = simple.servermanager.ProxyManager()
    interactionProxy = pxm.GetProxy(
        'settings', 'RenderViewInteractionSettings')
    interactionProxy.Camera3DManipulators = [
        'Rotate', 'Pan', 'Zoom', 'Pan', 'Roll', 'Pan', 'Zoom', 'Rotate', 'Zoom']