remi icon indicating copy to clipboard operation
remi copied to clipboard

Second remi app in same python program does not close.

Open c-rodwell opened this issue 4 years ago • 5 comments

When I start a remi app twice in one program, the second time does not exit on App.close(). It appears to stay in serve_forever() until I ctrl-c in terminal. This happens in remi versions 2021.3.2 and 2021.3.2.post5+gabcb0d5 , on windows 10 and raspbian, python 3.9.1.

context - I'm trying to use remi for a web interface in a larger command line program. It launches the remi app from a user action in the same thread, then return to the original program on close. So I'm waiting for the remi.start to return. Maybe I am using it the wrong way - I could keep the remi server running the whole time in a separate thread. So I'm open to suggestions on how to avoid this.

Here's a small program to show the issue. It will open a window with a close button, then do it again. The first time, it exits properly when I click the close button. The second time, it gets stuck in serve_forever.

` import remi.gui as gui from remi import start, App

class MyApp(App):
    def __init__(self, *args):
        super(MyApp, self).__init__(*args)

    def main(self):
        self.close_button = gui.Button("Close")
        self.close_button.onclick.do(self.on_close_button)
        column = gui.VBox(width = 100, height=100)
        column.append([self.close_button])
        return column

    def on_close_button(self, widget):
        print("on_close_button")
        self.close()

    def on_close(self):
        print("on_close start")
        super(MyApp, self).on_close()
        self.server.server_starter_instance._alive = False
        self.server.server_starter_instance._sserver.shutdown()
        print("on_close end")

if __name__ == "__main__":
    print("\nfirst instance: ")
    start(MyApp, update_interval=0.1, debug=True)
    print("first instance complete")
    print("\nsecond instance")
    start(MyApp, update_interval=0.1, debug=True)
    print("second instance complete") #only see this after a ctrl-c`

Here is the program output with debug statements and my prints:

first instance: remi.server INFO Started httpserver http://127.0.0.1:55920/ remi.request INFO built UI (path=/) remi.request DEBUG get: / 127.0.0.1 - - [18/Jun/2021 14:10:47] "GET / HTTP/1.1" 200 - remi.request DEBUG get: /res:style.css 127.0.0.1 - - [18/Jun/2021 14:10:48] "GET /res:style.css HTTP/1.1" 200 - remi.server.ws INFO connection established: ('127.0.0.1', 62444) remi.server.ws DEBUG handle remi.server.ws DEBUG handshake remi.server.ws INFO handshake complete remi.server.ws DEBUG send_message: 0270422221... -> ('127.0.0.1', 62444) remi.server.ws DEBUG send_message: 3... -> ('127.0.0.1', 62444) remi.server.ws DEBUG on_message: connected remi.server.ws DEBUG send_message: 3... -> ('127.0.0.1', 62444) remi.server.ws DEBUG on_message: callback remi.request DEBUG App.onload event occurred remi.server.ws DEBUG send_message: 3... -> ('127.0.0.1', 62444) remi.server.ws DEBUG on_message: callback remi.request DEBUG App.onpageshow event occurred remi.request DEBUG get: /favicon.ico remi.server.ws DEBUG send_message: 3... -> ('127.0.0.1', 62444) remi.server.ws DEBUG on_message: callback on_close_button remi.request DEBUG shutting down... on_close start on_close end remi.server.ws DEBUG ws ending websocket service remi.server DEBUG ** serve_forever() quitting first instance complete

second instance remi.server INFO Started httpserver http://127.0.0.1:60652/ remi.request DEBUG get: / 127.0.0.1 - - [18/Jun/2021 14:10:51] "GET / HTTP/1.1" 200 - remi.request DEBUG get: /res:style.css 127.0.0.1 - - [18/Jun/2021 14:10:51] "GET /res:style.css HTTP/1.1" 200 - remi.server.ws INFO connection established: ('127.0.0.1', 50800) remi.server.ws DEBUG handle remi.server.ws DEBUG handshake remi.server.ws INFO handshake complete remi.server.ws DEBUG send_message: 0270422221... -> ('127.0.0.1', 50800) remi.server.ws DEBUG send_message: 3... -> ('127.0.0.1', 50800) remi.server.ws DEBUG on_message: connected remi.server.ws DEBUG send_message: 3... -> ('127.0.0.1', 50800) remi.server.ws DEBUG on_message: callback remi.request DEBUG App.onload event occurred remi.server.ws DEBUG send_message: 3... -> ('127.0.0.1', 50800) remi.server.ws DEBUG on_message: callback remi.request DEBUG App.onpageshow event occurred remi.request DEBUG get: /favicon.ico remi.server.ws DEBUG send_message: 3... -> ('127.0.0.1', 50800) remi.server.ws DEBUG on_message: callback on_close_button remi.request DEBUG shutting down... on_close start on_close end remi.server.ws DEBUG ws ending websocket service

At this point it hangs and does not reach the "second instance complete" print. If I ctrl-c in terminal, it continues:

on_close start on_close end remi.server INFO *** signal 2 received. remi.server DEBUG ** serve_forever() quitting second instance complete

c-rodwell avatar Jun 18 '21 21:06 c-rodwell

Hello @c-rodwell , the problem is caused by the Web page that remains open and keeps the websocket thread running. This prevents the app to exit. Look at issue #452 , you will find a working example that forces the Web page to close, modify it to run two instances and please let me know if this works ;-)

dddomodossola avatar Jun 19 '21 05:06 dddomodossola

It looks like the same issue happened except that the windows closed now. I copied that example and changed main to:

if name == "main": start(MyApp) print("first app completed") start(MyApp) print("second app completed")

When I click close in the first app, it closes as expected. On the second close button, it prints "I'm going to be closed." but does not reach the "second app completed" unless I ctrl-c (probably interrupting the serve_forever).

I also tried putting a sleep(10) between the two starts, or starting two different App subclasses and the same thing happens.

If I make both start calls with the same port number, the second window doesn't display properly. I mean something like this:

start(MyApp, address='0.0.0.0', port=8081) start(MyApp, address='0.0.0.0', port=8081)

This makes me think that the port isn't released. So when they use different ports (which it does by default), could the port still open from the first prevent the server from exiting on the second?

I'm new to using remi so I'm not sure if starting one app right after the other is proper use. I can probably change my application to only use it once. And I'll read the other examples for ideas.

c-rodwell avatar Jun 19 '21 09:06 c-rodwell

Hello @c-rodwell , I am able to reproduce the problem. I suggest you to run the two server instances by separate processes. I think that running the two instances as you did above, you can get strange behaviour.

dddomodossola avatar Jun 22 '21 12:06 dddomodossola

Thanks for looking. My interface doesn't really need to be on web so it's not a big deal for me. I might try running the servers in another process or other work arounds. I think I should leave this open since it acts not in the way I would expect, but up to you.

c-rodwell avatar Jul 09 '21 01:07 c-rodwell

;-)

dddomodossola avatar Jul 09 '21 06:07 dddomodossola