zauberzeug / rosys

An all-Python robot system based on web technologies. The purpose is similar to ROS, but it's based on NiceGUI and easier to use for mobile robotics.
https://rosys.io
MIT License
69 stars 10 forks source link

import rosys does not work with ui.run(reload=False) - RuntimeError: multiprocessing start method must be "spawn" #19

Open AndyPermaRobotics opened 1 year ago

AndyPermaRobotics commented 1 year ago

Hello everyone,

I have come across the following error message when I set the reload flag to False in the ui.run function:

 Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/nicegui/background_tasks.py", line 55, in _handle_task_result
  task.result()
File "/usr/local/lib/python3.11/site-packages/nicegui/helpers.py", line 77, in result_with_client
  await result
File "/rosys/rosys/rosys.py", line 144, in startup
  raise RuntimeError(
RuntimeError: multiprocessing start method must be "spawn"; see https://pythonspeed.com/articles/python-multiprocessing/

To better localize the source of the error, I have created a minimal example where the error occurs. Just import rosys is enough.

Example:

from nicegui import ui

import rosys

ui.run(
    title='Test', 
    port=8080,
    reload=False
    )

The error also occurs when I try to plan a path in my main program.


How did I come up with the idea of setting reload=False?

The reload flag causes my script to run twice. This results in two instances of each class being created. This has caused problems when I tried to subscribe to an MQTT topic, and my callback function was suddenly called twice for each message. The reload does not seem to be a complete restart where all resources from the previous run are cleaned up.

rodja commented 1 year ago

Thanks for reporting this @AndyPermaRobotics, but the example works fine here on MacOS. Are you testing this on Windows?

About the multiple evaluation of main you may want to have a look into the NiceGUI FAQ where I just added the infos from https://github.com/zauberzeug/nicegui/issues/794.

In RoSys we often use the last option with app.on_startup in combination with a System class which manages the robot state. See our field friend code for example.

AndyPermaRobotics commented 1 year ago

@rodja thanks for the link to the FAQ, my script works now.

It's interesting, that you could not reproduce the issue on MacOS. I let it run in a Docker Container.

Dockerfile:


FROM zauberzeug/rosys:latest 

WORKDIR /usr/src/app

docker-compose.yml

version: "3.9"
services:
  rosys_service:
    build: .
    tty: true
    ports:
      - "8080:8080"
    volumes:
      - ./:/app
    hostname: docker
rodja commented 1 year ago

Ah very good @AndyPermaRobotics. With Docker the error comes up as described by you. Before I had just tested locally on mac.

falkoschindler commented 11 months ago

@rodja Do you already have an idea what to do about it?

rodja commented 11 months ago

No, I have not looked into it.

NiklasNeugebauer commented 6 months ago

I looked into this a little. I think the best way to solve this may be keeping Nicegui's behavior consistent in case there is no specific reason that it does not set the spawn method when reload=False. However, I do not understand enough about Nicegui to fix this.

Another Option would be forcing the method to spawn instead of raising an exception in rosys.py on_startup: multiprocessing.set_start_method('spawn', force=True)