I have created a simple script in Python (i am a newby). Everything is working as needed, except for one minor issue.
My project: I send a request to my server through http: {ip-of-server}/?speed=999&time=8¢s=50
This will display a countdown timer in your shell. Counting down from 8 to 0 in this case. That works well. When I send {ip-of-server}/?speed=499&time=8¢s=50 it will count down twice as fast. This is as needed.
The issue i am facing: During countdown, i need to be able to send a new request to my server. It should update the countdown with the new values. At the moment it will create 2 countdowns. Which is correct if you read the script, but not what I need. I need some help how to just update the existing countdown.
My code:
from flask import Flask, request
app = Flask(__name__)
import time
@app.route('/', methods = ["GET"])
def post():
speed = float(request.args["speed"])
thetime = request.args["time"]
cents = request.args["cents"]
print('\n')
print('AccuView Digital:')
print('Speed:', speed,' Time:', thetime,' Cents:', cents)
print('-------------------------------')
def countdown(thetime):
while thetime:
mins, secs = divmod(thetime, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
print('Tijd:', timer, end="\r")
time.sleep((speed+1)/1000)
thetime -= 1
if thetime == 0:
print('Werp geld in\n')
countdown(int(thetime))
return '1'
app.run(host='192.168.1.107', port= 8090)
Thanks
The script is working fine as you said yourself. So what's happening right now is that flask is creating threads to serve your requests. You send 1st request, flask starts a counter on one thread and when you send another request, flask starts another thread and another counter runs on that thread. Both threads have their own values of speed
, thetime
and cents
and one thread cannot change the value of a variable in another thread.
So what we want to do is to access/modify the value of variables from any thread. One easy solution for this is to use global variables so that these variables are accessible from all the threads.
Solution:
speed
, thetime
and cents
as global variables so they are modifiable from any thread.thetime
is 0
).countdown()
). Else we don't need to do anything (we have already updated the values of global variables in previous step so the existing counter is updated).Code:
import time
from flask import Flask, request
app = Flask(__name__)
# We create global variables to keep track of the counter
speed = thetime = cents = 0
@app.route('/', methods=["GET"])
def post():
global speed, thetime, cents
# Check if previous counter is running
counter_running = True if thetime else False
thetime = int(request.args["time"])
speed = float(request.args["speed"])
cents = request.args["cents"]
print('\n')
print('AccuView Digital:')
print('Speed:', speed, ' Time:', thetime, ' Cents:', cents)
print('-------------------------------')
def countdown():
global thetime, speed
while thetime:
mins, secs = divmod(thetime, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
print('Tijd:', timer, end="\r")
time.sleep((speed + 1) / 1000)
thetime -= 1
if thetime == 0:
print('Werp geld in\n')
# If existing counter is running, then we don't start another counter
if not counter_running:
countdown()
return '1'
app.run(host='192.168.1.107', port= 8090)
Code (so that we can interrupt sleep):
import time
import threading
from flask import Flask, request
app = Flask(__name__)
# We create global variables to keep track of the counter
speed = thetime = cents = 0
sleep_speed = threading.Event()
@app.route('/', methods=["GET"])
def post():
global speed, thetime, cents, sleep_speed
# Check if previous counter is running
counter_running = True if thetime else False
thetime = int(request.args["time"])
speed = float(request.args["speed"])
cents = request.args["cents"]
# Make sure to interrupt counter's sleep
if not sleep_speed.is_set():
sleep_speed.set()
sleep_speed.clear()
print('\n')
print('AccuView Digital:')
print('Speed:', speed, ' Time:', thetime, ' Cents:', cents)
print('-------------------------------')
def countdown():
global thetime, speed
while thetime:
mins, secs = divmod(thetime, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
print('Tijd:', timer, end="\r")
sleep_speed.wait((speed + 1) / 1000)
thetime -= 1
if thetime == 0:
print('Werp geld in\n')
# If existing counter is running, then we don't start another counter
if not counter_running:
countdown()
return '1'
app.run(host='0.0.0.0', port=8090)