Commit Graph
8 Commits
Author SHA1 Message Date
tsm-odoo 461f1c7998 [IMP] bus: last notification id reset after restoring db
Before this PR, the last notification id known by the client
was not reset after restoring the database. This was an issue
since there can be a gap between the last notification  and the
one that has been restored with the database. In this scenario,
messages are not received after restoring the database since the
client subscribes to higher notification ids that the ones that are
created.

This PR fixes this issue by defaulting to 0 if the one the client
passed is higher.

closes odoo/odoo#103311

X-original-commit: 5118da53a6e9adb94577a4f16999522a7e1e8c10
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Signed-off-by: Stockbauer Matthieu (tsm) <tsm@odoo.com>
2022-10-17 17:11:05 +02:00
tsm-odoo 3c09d6c5a9 [FIX] bus: fix websocket errors on local tests
When executing python tests with Odoo opened in the browser, the
websocket connection coming from the browser can lead to issues
with savepoints/rollbacks. Indeed, during test set up, a savepoint
is created. This savepoint is released at the end of each test.

The issue occurs when the websocket connection opens a cursor (and
thus creates a savepoint) after the one created by the test but releases
it after the one created by the test:
    - SAVEPOINT TEST
    - SAVEPOINT WS
    - ROLLBACK TO SAVEPOINT TEST
    - SAVEPOINT WS DOES NOT EXIST

In order to solve this issue, let's prevent browsers from opening a
websocket connection during python tests. This does not apply to chrome
headless since remaining threads are awaited before the end of every tour
(which means the websocket connection will be close before releasing the
test cursor).

closes odoo/odoo#99538

Signed-off-by: Julien Castiaux <juc@odoo.com>
2022-09-05 18:35:48 +02:00
tsm-odoo 58eade9f34 [FIX] bus: bus message dispatching
Before the websockets were introduced, longpolling coroutines were
sleeping until postgres notify. Each coroutine was then wake up and
notifications were fetched.

Since the websocket introduction, the main loop, responsible for listening
to postgres sends the notifications itself. This means, the postgres loop
is blocked during message fetch/dispatching and notifications are dispatched
in a sequential fashion resulting in a slow message dispatching.

In order to solve this issue, websocket coroutines are now responsible to
fetch/dispatch notifications, letting the main loop free to relay notifications
as they come and allowing notifications to be sent simultaneously.

When instructed to dispatch available notifications, the websocket coroutines
will try to acquire a cursor. Each coroutine will try up to `MAX_TRY_ON_POOL_ERROR`
times, sleeping between each try. If no cursor can be acquired, the connection is
closed with the TRY_LATER` close code.

closes odoo/odoo#98880

Signed-off-by: Antony Lesuisse <al@odoo.com>
2022-09-05 14:50:17 +02:00
Matthieu Stockbauer 9c85261597 [FIX] bus: fix test user logout outgoing message
The test_user_logout_outgoing_message is undeterministic because
it speculate on the fact that the channel subscription was made
when we try to dispatch notifications. Sometimes it is not and
the websocket to channel map is empty resulting in a StopIteration
exception being raised. Let's wait for the subscribe to occur to
ensure the websocket will be registered before trying to dispatch
the message.

closes odoo/odoo#99204

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2022-08-30 12:44:40 +02:00
tsm-odoo bf9ae3bbc8 [FIX] bus: pop unused channels from channel map
When a websocket is disconnected, its subscription is removed.
Each channel leads to a set of subscribed websockets. When no
more sockets are listening to a channel, this channel should be
pop from this mapping or the map will keep growing.

closes odoo/odoo#98766

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2022-08-25 03:11:51 +02:00
tsm-odoo de6de48deb [IMP] bus, *: adapt server to use websocket instead of longpolling
*: hr_presence, web_editor.

This commit is part of the websocket integration in Odoo.
It focuses on adapting the bus to support websockets:
   - last notification id is now kept on the server
   - channel list is built by overriding the `_build_bus_channel_list`
     method of the `ir_websocket` model instead of overriding the `_poll`
     method of the bus controller.
   - The bus presence was updated during polls, since there is no more poll,
     bus presence update will be the responsability of the client.
   - The `/websocket/peek_notifications`, `/websocket/update_bus_presence`
     routes will be available so that odoo sh can access notifications/update presence
      from http requests.
   - /longpolling routes are now prefixed with /bus thus won't be redirected to the
     gevent worker anymore except for `/longpolling/health` which is the
     health check route of the gevent server.

Since websocket now handle incoming messages, a way to manage authentication
have been introduced :
    - The session is retrieved from the HTTP handshake.
    - When a websocket message comes/leaves the session is retrieved
      on the file system so that we're sure it still exists and that
      it is up to date.
    - The session is checked
    - If no session is found on the file system or `check_session`
      fails, the websocket connection is closed with the `SESSION_EXPIRED`
      close code (which is a custom close code: 4001).
    - Note that websocket connections are closed every `KEEP_ALIVE_TIMEOUT`
      seconds to ensure no websocket connection will stay open if the user
      clears its cookies.
    - Note that a wsrequest object is available when processing incoming
      messages. It is similar to the http request and contains various
      useful informations (session, env, ...).

Part-of: odoo/odoo#75510
2022-08-23 17:55:10 +02:00
tsm-odoo 256ea2bd28 [IMP] bus, core, website: add lifecycle events to websocket server
This commit is part of the websocket integration in Odoo.
It focuses on implementing websocket  lifecycle events.

Two lifecycle hooks are currently available:
   - onopen: called after the websocket opening
   - onclose: called after the websocket closure.

Those callbacks will be passed an environment and the websocket
related to the lifecycle event.

In order to subscribe to websocket lifecycle events, one must decorate
a free functions with either `@Websocket.onopen` or `@Websocket.onclose`.

Part-of: odoo/odoo#75510
2022-08-23 17:55:10 +02:00
tsm-odoo e06bb9a42d [ADD] bus: add websocket implementation
This commit is the first commit of the websocket integration in Odoo.
It focuses on the implementation of the websocket protocol as per RFC6455.

The implementation is tested thanks to the autobahn test suite.

A config parameter is available to customize the websocket connection:
   - websocket_keep_alive_timeout (default 600): Integer specifying how
     many seconds a websocket connection should be kept alive

Part-of: odoo/odoo#75510
2022-08-23 17:55:09 +02:00