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.