Real-time notification

Continuing the discussion from Required clicks per Button:

Rational

Sometimes having real-time notification could improve the work performance because the user can react quickly. Of course such notification should be use with care to not overflow users with useless notification.
A notification is a pop-up display above all other windows. Most desktop has this feature and also most of the browsers.
The challenge is having the client listening for the notification for the current user with a minimal resource consumption client and server sides.

Proposition

We could use the long polling method. So the desktop client will start a new thread and the web client will start such query at login. They will make request on a specific address using the user ID and the session.
On the server side, we could use the LISTEN/NOTIFY mechanism to wait for notifications. For other back-ends which do not support such mechanism, the request will just return an error code and the client will not try any more.
We will created a channel for the user name and another for the session like that we could notify the user anywhere and only for a specific session (could be used with on_change).
On logout, the long polling should be stopped.
On web client, we will use Web Notifications.
On desktop client, we will use libnotify

Implementation

https://bugs.tryton.org/issue7537
https://bugs.tryton.org/issue7563

Why not use the websockets protocol? Two threads, one for pull (normal operation) and the other for push (message from the server).
It needs modification on the server-side but websockets are just a protocol and you can handle all the data in the same format as you have now.

I do not see any argument.

No need for polling, so less traffic needed. No need to have extra mechanisms on the serverside, But the first for me is a big argument, because traffic is expensive.

How do you count that? Long polling consume no trafic.

Long polling needs no change on server-side. Using WebSocket will require to write a websocket server and a websocket client.

One potential issue with “LISTEN/NOTIFY” is that it takes permanently a connection resource on the database per long polling. So the number of active client that a server can support will drop quickly with this feature.
A possible solution will be to have one thread per process that listen on a generic channel, each long polling request from the same process will register to this thread. Once the listen thread receive a notification, it dispatches it to the right long polling thread. The inconvenient of this method is that the listen thread will receive all notifications even for users who does not have a long polling thread registered. This could be improved by having the listen thread listen to each channel of the long polling thread.

Maybe a solution will be to have a separate process that listen on a specific port (server should sent the address or the port at the client login). This process will not be threaded but instead just asynchronous. It will use a connection per database and it will listen for all the requested channels. It will use a single event loop for new long polling connection and database notify and it will dispatch the notification to the right request.

A part from the protocol to comunicate with the server i think that it should be possible to relate the notification to some records and the user should be able to access does records with a single click.

For example: I do some long task in async way and I will like to notice the user when it have been finished. As this task may be related to a record the user may be able to open the record (in a new tab) directly when the notification is shown.

I do not think it is possible to click on a notification.

If we have to write a separate server solution I think we can now use a standard protocol (like websocket as @edbo suggested).

There is a python implemenation of the websocket protocol which supports python2.7, a python implementation for the server side which is only available on >3.4 version (3.3 with asyncio library) and it’s also available as native javascript.

For me adding new features only to users of python3.4 will incentive the movement to the newer python versions.

On my system I have notifications that have some buttons to click and do some actions related to them. An for what I read in the libnotify is possible to add Actions, and in case the system does not support them we can use a HyperLink with the tryton URL as fallback.

By why websocket? I see no advantages for this protocol because notification is any way in one direction server → client. Also with websocket, you just have something like a socket so you have to create your own protocol on top of it.
So to consider websocket, I need to have a rational for its usage and not just because it is a new cool kid.

This could be done only with a common protocol for all notification systems.

To me it has nothing to do with “new cool kid” because it isn’t a cool kid. It’s hard to implement because of it’s asynchronous nature. Websockets can also be used as “normal” connection. And because Tryton uses RPC, that can be transported by Websockets without a problem. But mostly there is a fallback to HTTP because not all browser support websockets.
By using websockets you lift the system out of the database like you want to do with the LISTEN / NOTIFY functions of PostgreSQL. Websockets gives you also the possibility to do some user-actions like sending notifications to a user from a module.

That’s exactly what I’m thinking of! E.g. print a complex report or do a long-running operation like reconciliation or open the chart of accounts etc. You are then be able to give the user status updates during the process of collecting data or printing. I’m also thinking of voip integration, so when the phone starts ringing, the user gets a notification who it is. Eventually the client can already open a new tab with the caller details.

But maybe I’m a bit of there … :grin:

1 Like

I do not want to move out of the database. Tryton is a transactional system, it needs the database and it needs a transactional notification system.

On more reason to not use it.

No you wont because of the transactional nature of Tryton.

Nothing to do with server notification. Your soft-phone can just query the client for that.

This isn’t also easy at all.

Please don’t open extra ports! It’s always a security risk and Tryton starts to look like other cool new software where you must open a lot of ports to get the software running with the (new) features.

I can not understand the rational behind that. But of course it is always simpler to configure if there is only one port.

I think the notification protocol should be flexible and not only limited to notification popup.
Indeed I think we should be able to send to the client action like reload this records, execute this action etc. This way we could get the client refreshing automatically records that were opened before a modification on the server side.

1 Like

I just stumbled onto Crossbar.io. Is this something we can use for this?

Since libnotify does not seem to be available for windows I made some search and found this SO question: windows - Notification using python - Stack Overflow

What bothers me after looking the code is that it’s basically just another window managed by tryton not at all something as well integrated as libnotify seems to be.

For macos it’s also the same kind of issue. People usually call some shell script or use libraries directly interacting with the OS but at least it’s a bit more integrated.

Well pywin32 is packaged on mingw: MINGW-packages/mingw-w64-python-pywin32 at master · Alexpux/MINGW-packages · GitHub
So there will be no issue to use it. But I think it will be better to write our own version than using Windows-10-Toast-Notifications.

FYI, there is no terminal-notifier application on our OSX.

PyObjC is not packaged by brew but it seems it can be installed via pip: https://pythonhosted.org/pyobjc/install.html

So I see no major issue.