So, I spend the best part of the day playing with your example but wasn't 
able to make it work.

The best I have is that I see that before the form is submitted 
*getprogress* is called and return the expected value, but while progress 
is running it blocks the invocation of *getprogress* and the prints in 
*getprogress* are executed all at once after the sleep loop of *progress* 
is complete. It looks like a limitation of web2py. I didn't try to create a 
new thread for the update of 
*cache.ram('progress_data', ...)*
Am I doing something wrong?

Here is what I got, after making some minor modification to your code to 
make it work for me:

In my *controller/playground.py*

# Progress bar example:
# See: https://groups.google.com/d/msg/web2py/zgSLxeg7avw/JvPidEBMAQAJ
import time

def progress():
    some_form = SQLFORM.factory(Field('a_field'))
    
    if request.post_vars:
        n = 20 #simulate 20 iterations
        for i in range(n):
            msg = "Working"
            percent = 100*(i+1) / n
            progress_data = cache.ram('progress_data',
                                      lambda: dict(percent=percent, msg=msg
),
                                      time_expire=0)               
            print "progress:", progress_data
            time.sleep(1)
        #we are calling this controller through ajax so return a string 
when done
        return "done"
    else:
        progress_data = cache.ram('progress_data',
                                  lambda: dict(percent=(-1), msg='Ready'),
                                  time_expire=0)
    return locals()

def getprogress():
    progress_data = cache.ram('progress_data', lambda: None, None)
    print "getprogress:", progress_data
    return progress_data

And in my *view/playground/progress.html* I have:

{{extend 'layout.html'}}

{{=a_form}}

<div class="container-fluid">
    <div id="pbar">
        <div class="row">
            <div class="col-md-12">
                <h3 id="pbar_status">Ready...</h3>
            </div>
            <div class="col-md-12">
                <div class="progress progress-bar-xl"
                     style="margin-top: 3px">
                    <div class="progress-bar progress-bar-warning"
                         role="progressbar" 
                         aria-valuenow="60"
                         aria-valuemin="0"
                         aria-valuemax="100"
                         style="width: 0%;">0%</div>
                </div>
            </div>
        </div>
    </div>
</div>

<script type="text/javascript">
 function ProgressBar (selector) {

     self = this
     
     self.el = $(selector)
     self.text = self.el.find("#pbar_status");
     self.progress = self.el.find(".progress-bar");
     self.btnstart = self.el.find("#start");
     self.btnabort = self.el.find("#abort");
     
     self.value = 0;
     self.min = 0;
     self.max = 100;
     self.interval = 5000;
     self.running = false;
     self.timer = null;
     self.offset = 0;

     self.set_progress = function (value) {
         value = value || 0;
         var done = false;
         if (value >= self.max) {
             value = self.max
             done = true;
         };
         value = parseInt(value) + "%";
         self.progress.css("width", value);
         self.progress.text(value);
         if (done) {
             self.done();
         };
     };

     self.done = function (msg) {
         var msg = msg || "Process Completed"
         self.text.text(msg)
             console.log("done", self.timer);
         clearInterval(self.timer);
         self.running = false;
     };

     self.abort = function (e) {
         if (self.running) {

             self.value = 0;
             self.set_progress(0);
             self.text.text("Aborted");
             if (self.timer) {
                 clearInterval(self.timer);
             };
             self.running = false;
         };
     }

     // ask the server for the progress
     self.ask = function () {
         var ask = $.ajax({
             type: "GET",
             url: window.location.origin + "{{=URL('getprogress.json')}}",
             dataType: "json",
         });
         
         ask.done(function (json) {
             console.log(json);
             var percent = parseInt(json.percent);
             var msg = json.msg;
             if (percent == -1) {
                 console.log(msg);
                 return;
             };
             self.text.text("Processing...");
             self.text.text(msg);
             self.value = percent + self.offset;
             self.set_progress(self.value);
         });

         ask.fail(function (xhr, status, error) {
             var resp = xhr.responseText;
             self.done("Error (see browser's console for details)");
             if (console) {
                 console.log(resp);
             };
         });
     };

     self.start = function (e) {
         if (self.running) {
             console.log("already runing");
         } else {
             console.log("running");
             
             self.value = 0;
             self.set_progress();
             self.ask();
             self.timer = setInterval(self.ask, self.interval);
             self.running = true
         };
     };

     self.set_progress(self.value);
 }

 // start here
 $(function() {
     var pbar = new ProgressBar("#pbar");
     pbar.start();
 })
</script>


Thank you very much.

Cheers,
Chen.


On Tuesday, February 16, 2016 at 11:15:06 PM UTC+2, Alfonso Serra wrote:
>
> Im trying to make a progress bar by reading and writing a session variable:
>
> There are 2 controllers:
>
> Get session.progress
> def getprogress():
>     print "getprogress:", session.progress
>     return session.progress
>
> This one takes 5 seconds to perform and changes session.progress each time.
> def progress():
>     # when a form is submitted, change progress each second
>     if request.post_vars:
>         for i in range(5):
>             session.progress = i
>             print "main:", session.progress
>             sleep(1)
>         return "done"
>     else:
>         session.progress = -1
>     return locals()
>
> At the view, there are two ajax calls. One that triggers "getprogress" 
> each second, and another one that triggers "progress" when a random form is 
> submitted through ajax to avoid redirection.
>
> at the browser's console, getprogress only returns -1
>
> at the python console i get a log like this:
> getprogress: -1
> getprogress: -1
> main: 0
> getprogress: -1
> main: 1
> getprogress: -1
> main: 2
> getprogress: -1
> main: 3
> getprogress: -1
> main: 4
> getprogress: -1
>
> getprogress should be changing since im writing the session variable.
>
> If im changing a session variable in a controller why hasnt changed when i 
> ask for it on another one?
>
> Should i be using cron jobs or threads to make a progress bar? Whats the 
> best way?
>
> Thank you very much.
>
>

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to