Hello,
I want to use the Timer to update a label that takes values from table (something like progress bar)
I am using uplink and not Background task to deal with the Timer once the task is completed.
What I’ve tried and what’s not working:
I have set the Timer but it starts as soon I open the Form and it does not show the real progress.
Code Sample:
self.timer_1.interval = 0
def file_loader_1_click(self, file, **event_args):
self.timer_1.interval = 2
anvil.server.call("dosmth",file)
self.timer_1.interval = 0
def timer_1_tick(self, **event_args):
self.label_1.text = anvil.server.call("store_data")
@anvil.server.callable
def store_data():
last = app_tables.table_name.search(rows = rows)[0]
return f" {last} rows in progress"
I need to start the Timer event when start a function until it ends with the conditions above
Thank you
What you are doing will work, in principle. The timer does start, and will fire. But:
-
You’re setting the interval to 2 seconds. How long does it take the dosmth
call to return? If it’s less than 2 seconds, the timer never fires.
-
The timer is doing a server call iself. There seems to be some interaction between that server call and the original one. I can only get one timer tick to fire no matter how long that original server call takes.
You really want to use background tasks for this sort of thing. The file loader server call starts the background task and returns, while the timer tick checks the status of the background task. The timer tick itself will sets its own interval to 0 when it detects that the background task is done.
Do note that on a free plan background tasks are limited to 30 seconds, so this might not be suitable if you don’t have a paid plan.
My problem is that the Timer starts as I open the Form and not when calling The file loader.
If I solve this issue I am ok.
The dosmth
call last depending on the rows that the file has so it last from 15 minutes to 40 minutes.
I cannot use background task(on other function I use this method to trigger timer, I have paid plan) because I use Uplink for The file loader server call due to Selenium library.
Thanks
Look in the Timer component properties. It has a default value set for the interval, which is something like 0.5. Set that to 0 in the properties pane, and the timer will not start automatically.
Thank you for your prompt response. I changed the properties to 0 but obviously it trigger Timer once since the call is made once ( The dosmth
call). In alternative can be used a function that get the value from table and refresh every time the table changed?
I’m sorry, but I don’t understand what isn’t working now.
That’s what the Timer is for. There’s no way to trigger a call from the server to the client when the table is changed. Calls have to go from client to server to ask for information.
You cannot make a call for a task that lasts longer than 30 seconds.
You do need to use a background task.
Your background task will call the uplink function, the uplink function will run for 40 minutes and return the control to the background task.
While the uplink function runs, it should update a row in the database every few seconds, and your timer should check that row.
Make sure interval is set to 0 on the form, so the timer doesn’t tick when the form opens.
You could do something like this:
# on the form
def file_loader_1_click(self, file, **event_args):
self.timer_1.interval = 2
anvil.server.call("start_the_job", job_id)
def timer_1_tick(self, **event_args):
status = anvil.server.call_s("get_status", job_id)
self.label_1.text = status
if status == 'done':
self.timer_1.interval = 0
# on the server
@anvil.server.callable
def start_the_job(job_id):
row = app_tables.table_name.add_row(job_id=job_id, status='starting')
anvil.server.launch_background_task('uplink_task', job_id)
@anvil.server.callable
def get_status(job_id):
row = app_tables.table_name.get(job_id=job_id)
return row['status']
#uplink
@anvil.server.background_task
def uplink_task(job_id):
row = app_tables.table_name.get(job_id=job_id)
for i in range(1000):
row['status'] = f'step {i}' # make sure this doesn't execute more than once every 2-3 seconds
# do something slow
row['status'] = 'done'
I have done something similar years ago, and if I remember correctly running background tasks on uplink wasn’t a smart idea.
This is pseudocode I wrote very quickly. I’m sure it will not work as is, it’s there just to give you an idea.
1 Like