SAO web client freezes when reloading the browser several times with bus activated

Hi,
I have a problem with the SAO client when using the bus (I haven’t tried with the python client).
Context : Our client operator works with 3 screens to manage the planning. Each screen displays a different view of the same planning and each view provides a different entry point to edit the planning.
We are using the bus to synchronise the 3 plannings browser tabs and it works as expected.

But we have an issue, since we have activated the bus, we encounter frequent freezes when refreshing the sao web client, when it freezes it’s blocked until “long_polling_timeout” is reached.

Note : the issue is not related to our module, it happens on every screen when the bus is activated.

Is there a setting to prevent this behavior ? Am I missing something ?

Thanks

1 Like

For me you are hit by the connection limitation of browsers. As I guess you open in 3 different tabs the client, they execute each one a long-polling connection to the server (see Known Issues and Best Practices for the Use of Long Polling and Streaming in Bidirectional HTTP).
And as you probably use the same host name for the RPC and the bus, this blocks also the new RPC request until one bus connection expire and leave a slot for the RPC until it restart again.
So a good practice is to use a different host name for the bus like that only the bus is blocked if too much tabs are opened.
Such limit is higher if you use HTTP/2 (nginx has a default limit to 1000).
Also it will be better to use the sao tab instead of the browser’s one to reduce resource usage.

I though that using server-sent event could improve the situation but indeed it has the same limits as the long polling: Using server-sent events - Web APIs | MDN.
This javascript - Server sent events and browser limits - Stack Overflow has some more tricks but I do not think we need to complicate the current implementation as HTTP/2 solves this and can be configured on the server-side.

Thanks for the reply @ced

I don’t understand how I could use sao tab across 3 different screens. Is it doable ?

I tried different ways but I can’t make it work. Is it doable while using the docker image ?
I tried with extra_hosts in docker compose, but I don’t know how the browser can resolve that.
So I added a host “bushost” on my local machine, the call to bushost:8000/tryton/bus is resolved but the response is empty :

net::ERR_EMPTY_RESPONSE
(anonymous) @ VM10:1
send @ jquery.min.js:2
ajax @ jquery.min.js:2
Sao.Bus.listen @ tryton-sao.min.js:5
VM10:1 XHR failed loading: POST "http://bushost:8000/tryton/bus".
(anonymous) @ VM10:1
send @ jquery.min.js:2
ajax @ jquery.min.js:2
Sao.Bus.listen @ tryton-sao.min.js:5
VM10:1 XHR finished loading: POST "http://localhost:8000/tryton/bus".

I’m probably not doing the right thing…

I do not think so.

Yes it is done on the demo see tryton-docker-demo: 42f801e608ca 6.0.env

But this makes me think that maybe you are also using the uwsgi server for the long polling which is not great because it consumes one database connection per long polling connection. Indeed you must run a service with trytond --coroutine.

Thank you very much @ced I finally managed to make it work locally.

In my docker-compose file I added :

tryton-bus:
    image: tryton/tryton:6.0
    env_file: docker-tryton.env
    command: trytond --coroutine
    ports:
      - 8001:8000
    depends_on:
      - tryton-postgres
    environment:
      - DB_PASSWORD=XXXXXXXX
    restart: unless-stopped

here is my docker-tryton.env file :

DB_HOSTNAME=tryton-postgres
DB_PORT=5432
TRYTOND_WEB__CORS="http://localhost:8000"
TRYTOND_BUS__ALLOW_SUBSCRIBE=true
TRYTOND_BUS__URL_HOST=http://localhost:8001/
TRYTOND_SESSION__AUTHENTICATIONS=none,password

This way it can only be accessed via localhost and only from my machine.
I guess when I deploy to my client server I will have to put the server IP or hostname (instead of localhost) in order to make it accessible to users connected to the network.
Am I missing something here ? Is there a way to make it accessible without knowing the host or maybe is it possible to dynamically put the IP in the docker compose ? I hope this makes sens…
Anyway thanks again for your assistance @ced

Note: The trailing slash is required for TRYTOND_BUS__URL_HOST
It took me some time to figure out what I was missing.

I think I found a solution to be able to access to tryton from localhost and by hostname/ip. It’s working as expected the synchronization of the planning works instantly and no more freezes.
My coworker was modifying an event via the hostname url and I could see his change in real time even if I was connected via localhost !

Here is the configuration I use :

docker-compose.yml

tryton:
    image: tryton/tryton:6.0
    env_file: docker-tryton.env
    ports:
      - 80:8000
    depends_on:
      - tryton-postgres
    environment:
      - TRYTOND_BUS__ALLOW_SUBSCRIBE=true
      - TRYTOND_BUS__URL_HOST=http://${TRYTON_HOSTNAME:-localhost}:8001/ 
      - DB_PASSWORD=${POSTGRES_PASSWORD}
    restart: unless-stopped

  tryton-bus:
    image: tryton/tryton:6.0
    env_file: docker-tryton.env
    command: trytond --coroutine
    ports:
      - 8001:8000
    depends_on:
      - tryton-postgres
    environment:
      - TRYTOND_BUS__ALLOW_SUBSCRIBE=true
      - TRYTOND_WEB__CORS=
      
        http://localhost
      
        http://${TRYTON_HOSTNAME}
      - DB_PASSWORD=${POSTGRES_PASSWORD}
    restart: unless-stopped

docker-tryton.env :

DB_HOSTNAME=tryton-postgres
DB_PORT=5432
TRYTOND_SESSION__AUTHENTICATIONS=none,password

also I have .env file not in the source control different for each machine :

POSTGRES_PASSWORD=My-Password-for-postgres
TRYTON_HOSTNAME=my-hostname-or-ip
1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.