我正在尝试开发一种 API 服务,该服务在从不同来源连续收集数据后,详细说明该数据,并保持该信息不被其他服务请求。
我正在使用 Flask,它在单个线程之上工作。
我的问题是关于访问缓存数据的慢行。收集过程效果很好,但有时当我要求服务器提供数据时它很忙,因为与此同时它正在从源中获取数据。
我应该如何设置线程以避免这种情况?
下面我通过一些简化的函数和类来解释我所做的事情。
抓取服务
class FetchingService():
def __init__(self,url=None,speed=None):
self.url = url
self.speed = speed # speed in seconds
self.last_updated = None # last time the service was used
def loadData(self):
time = { 'timestamp': int(time.time()) }
try:
r = requests.get(self.url) # get the data from the url
data = r.json() # if is a json
data.update({ 'status': True })
data.update(time)
return data
except:
data = { 'status': False }
data.update(time)
return data
def isTimeToUpdate(self):
if self.last_updated is not None: # check if is the time to run an update
delta = int(time.time()) - self.last_updated
if delta >= self.speed: # if passed enougth time
return True # is time to update
else:
return False # too early
else:
return False # last_updated not set
def run(self):
if self.last_updated is None:
self.last_udated = int(time.time())
if self.isTimeToUpdate():
self.loadData()
缓存服务
class Caching():
def __init__(self,instances):
self.data = []
self.instances = instances
def run(self):
if self.instances:
for i in instances:
self.data.append(i.run())
def queryLast(self):
if self.data:
return self.data[-1]
线程
class myThread():
def __init__ (self,thread_time,instances):
self.speed = thread_time
self.data = None
self.instances = instances
self.dataLock = threading.Lock()
self.myThread = threading.Thread()
def primaryThread(self):
self.myThread = threading.Timer(self.speed, self.run, ())
self.myThread.start()
def run(self):
with self.dataLock:
self.data.run()
self.primaryThread()
def activate(self):
with self.dataLock:
self.data = Caching(self.instances)
self.primaryThread()
return 'active'
def queryLast(self,key,value):
with self.dataLock:
data = self.data.queryLast()
self.primaryThread()
return data
主要的
a = FetchingService(url='/api/test/',10)
b = FetchingService(url='/api/data/',5)
c = FetchingService(url='/boh/',100)
instances = [ a , b , c ]
t = myThread(1,instances)
烧瓶视图
@application.route('/active/', methods=['GET'])
def app_start():
result = t.activate()
return jsonify(result)
@application.route('/last/', methods=['GET'])
def app_query():
result = t.queryLast()
return jsonify(result)