Dynamic Progress Bar

by
Odoo
v 11.0 v 12.0 Third Party 1340
Download for v 12.0 Deploy on Odoo.sh
Technical Name web_progress
LicenseLGPL-3
Also available in version v 13.0 v 11.0
You bought this module and need support? Click here!
Technical Name web_progress
LicenseLGPL-3
Also available in version v 13.0 v 11.0

Dynamic Progress Bar

Progress bar for Odoo waiting screen, possibility to cancel an ongoing operation and a system tray menu for all operations in progress.

web_progress exists for Odoo 11.0 and 12.0 (CE and EE).

Author: Grzegorz Marczyński

License: LGPL-3.

Copyright © 2019 Grzegorz Marczyński

Features

  • progress reporting for all standard Odoo import and export operations
  • system tray menu that lists ongoing operations initiated by the logged user (all operations visible to Administrator)
  • support for all operations initiated through UI and executed by planned activities (cron)
  • generator-like method to simply add progress reporting to any iteration (support for sub-iterations)

For developers

Typically when your code executes any long-term operation there is a loop over a collection in your code.

In order to report progress of the operation, wrap the collection with self.web_progress_iter(collection, msg="Message") or, if the collection is self (or other recordset), use a simpler version self.with_progress("Message")

Say, your operation's main method looks as follows:


    @api.multi
    def action_operation(self):
        for rec in self:
            rec.do_somethig()
            

then a progress-reporting-ready version would be:


    @api.multi
    def action_operation(self):
        for rec in self.web_progress_iter(self, msg="Message"):
            rec.do_something()
            

or a simpler version for recordsets:


    @api.multi
    def action_operation(self):
        for rec in self.with_progress(msg="Message"):
            rec.do_something()
        

Progress tracking may be added to sub-operations as well:


    @api.multi
    def action_operation(self):
        for rec in self.with_progress(msg="Message"):
            lines = rec.get_lines()
            for line in lines.with_progress("Sub-operation")
                line.do_something()
        

Release Notes

1.3 - 2019-07-15 - new functionality
  • estimated time left / total
1.2 - 2019-06-24 - fixes:
  • refactor global progress data
  • change progress template name to avoid clash with progressbar widget
1.1 - 2019-06-23 - fixes:
  • remove unecessary dependency on multiprocessing
  • fix memory leak in time-tracking internal data
1.0 - 2019-06-20 - initial version

Adding progress tracking to your code

Prerequisites

Progress reporting uses longpolling to send progress data from backend to web client, so make sure that the longpolling is operational before testing this module.

Simple case

Typically when your code executes any long-term operation there is a loop over a collection in your code.

In order to report progress of the operation, wrap the collection with self.web_progress_iter(collection, msg="Message")

Say, your operation's main method looks as follows:

@api.multi
def action_operation(self):
    for rec in self:
        rec.do_somethig()

Then a progress-reporting-ready version would be:

@api.multi
def action_operation(self):
    for rec in self.web_progress_iter(self, msg="Message"):
        rec.do_something()

or a simpler version for recordsets:

@api.multi
def action_operation(self):
    for rec in self.with_progress(msg="Message"):
        rec.do_something()

Progress tracking may be added to sub-operations as well:

@api.multi
def action_operation(self):
    for rec in self.with_progress(msg="Message"):
        lines = rec.get_lines()
        for line in lines.with_progress("Sub-operation")
            line.do_something()

Advanced case

This module adds methods web_progress_iter and with_progress to every Odoo model. The only difference between these methods is that web_progress_iter requires as its first parameter a collection to iterate upon and with_progress iterates always on self.

Both methods accept the following optional parameters:

  • msg (str): an operation description, the message to be shown in the progress report,
  • total (int): if provided, will be used as a length of the given collection, so len(collection) will never be called, which is essential when tracking progress of generators (default is None, i.e. len will be called),
  • cancellable (bool): whether cancelling the operation should be possible, i.e visible button "Cancel" (default is True),
  • log_level (str): which log level shall be used when logging progress (default is "info").
@api.multi
def action_operation(self, data, length):
    for row in self.web_progress_iter(data, total=length, msg="Message",
                                      cancellable=True, log_level="debug"):
        self.do_something(row)

Another approach

You can also add iteration progress reporting to any recordset by adding progress_iter=True to its context.

FAQ

In this section you will find answers to the common questions concerning progress reporting implemented in web_progress module.

How to report a problem or ask a question?

Please use the issue tracker of our GitHub repository to report problems or ask questions. You will find it here.

How the progress reporting works?

...

How each operation is identified?

  1. Web client injects a unique progress_code (UUID) into the context of every RPC call towards backend.
  2. Both web_progress_iter and with_progress convert the given collection (or generator) into an instance of a generator-like class that uses a progress_code from context to perform progress tracking while your code iterates upon the collection.
  3. Sheduled (cron) actions have their progress_code injected into the context by scheduler prior to their execution.

How often the progress is reported?

For each progress_code (i.e. a unique operation) the first interation (the first element) of the collection wrapped with web_progress_iter or with_progress is reported to the web client (via longpolling).

After that, the progress is reported in intervals of minimum 5 seconds (i.e. any access to any wrapped collection more than 5 seconds after the last reported progress is reported).

Also the final iteration (the last element) of the main wrapped collection (on the top-level) is reported.

What is the overhead of progress reporting?

...

How the operation cancelling works?

...

How multi-level progress reporting works?

...

Is the current transaction commited to make progress visible?

No. Progress reporting uses a fresh transaction for each progress report and cancelled operation verification; therefore, the main transation stays untouched and in total isolation.

However, it should be noted that since progress report records and longpolling messages are commited into the database, even if the main transaction is still not commited, the main transaction shall never inspect or change those records in order to avoid inter-transactional conflicts (update-in-parallel exceptions).

Is it possible to put an ongoing operation into background?

Yes, by pressing F5. Actually this is a standard Odoo behaviour that any long-term operation may be put into background by pressing F5. The difference here is that, thanks to system tray menu, user has possibility to follow the progress of ongoing background operations and to cancel them.

Beware that putting an operation to the background makes it impossible to interact further with the user after the operation is finished. So this is OK for data imports (unless there are import errors) and this is definitely not OK for data exports (or reports) that let the user download a generated file after the export operation is finished.

Does progress reporting work with reports?

Yes, you can iterate over the wrapped collections in QWeb reports and the progress will be visible to the user.

Please log in to comment on this module

  • The author can leave a single reply to each comment.
  • This section is meant to ask simple questions or leave a rating. Every report of a problem experienced while using the module should be addressed to the author directly (refer to the following point).
  • If you want to start a discussion with the author, please use the developer contact information. They can usually be found in the description.
Please choose a rating from 1 to 5 for this module.
Works great
by
Fabio Tielen
on 9/11/19, 2:00 PM

Hello, I have just installed your app on a demo setup (Odoo 12 enterprise) and works very nice. But I noticed there is no option to "push" the process to background. Only "cancel" the process. I can suggest you add another button "move to background" next to cancel. Now somebody can decide to "wait" until it's ready or put it to background so you get the screen back and do other things. In the top bar, we now have the icon where we can follow progress. But in your current version, this is useless. Because when you start e.g. an import, the black overlay screen just stay in front so I can not click and see that icon in top bar. Being able to move it to background gives the user back freedom to do other tasks while your progress is available in a single click in top bar. Thanks for your great app! I hope you can put my idea in a next update!

Re: Works great
by
Grzegorz Marczyński
on 9/11/19, 3:31 PM Author

Hi, Thank you for comment and your suggestion. I thought about the "Put to background" button, but technically this is not that obvious how should it be handled. For the moment you can just press F5 to refresh the page and you can continue to work and even run another import, if you like. The progress of all operations will be visible in the tray menu next to the unread messages icon. Just beware of the number of workers in your configuration, because each long-term operation occupies one worker, so make sure that you leave at least one for the UI operations. Good luck with your Odoo adventure!


Doesn't work. Great idea, very disappointed :(
by
Glen Morley
on 9/10/19, 8:41 AM

I have installed numerous aftermarket apps successfully, but failed twice with this one. It installs, but doesn't work.

Re: Doesn't work. Great idea, very disappointed :(
by
Grzegorz Marczyński
on 9/10/19, 9:25 AM Author

Please give some more details of how it does not work (Odoo ver.? Odoo config? How do you test it?). Do you have longpolling working correctly?


Template 'web_progress.ProgressMenu' not found
by
mohamed fouad
on 1/1/20, 12:31 PM

it worked well in production server, but in test inviroment i tack a backup from the db i get this errpr Uncaught Error: QWeb2: Template 'web_progress.ProgressMenu' not found