当一个 GET 请求开始工作时,我想设置一个可以立即被其他 GET 请求读取的变量
When one GET request starts working, I want set a variable which can immediately be read by other GET requests
在请求完成之前,模块级变量似乎实际上并不是 "changed"。
我需要它立即更新,以便其他请求可以知道工作正在处理中。
这是问题的一个例子:
import cherrypy
import time
@cherrypy.expose
class CherryPySleeps(object):
status = "not sleeping"
@cherrypy.tools.accept(media='text/plain')
def GET(self):
if CherryPySleeps.status == "not sleeping":
CherryPySleeps.status = "sleeping"
time.sleep(10)
CherryPySleeps.status = "not sleeping"
return "I finished sleeping"
else:
return "I am sleeping, shhh"
if __name__ == '__main__':
conf = {
'/': {
'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
'tools.sessions.on': True,
'tools.response_headers.on': True,
'tools.response_headers.headers': [('Content-Type', 'text/plain')],
}
}
cherrypy.quickstart(CherryPySleeps(), '/', conf)
当我打开 2 个浏览器选项卡时,在第一个请求页面,然后等待一秒钟,然后在第二个请求页面,我在每个选项卡上暂停 10 秒,然后 "I finished sleeping"。
我想要的是第二个选项卡能够非常快速地响应,"I am sleeping, shhh"
如果要保证请求(线程)之间的某种同步性,可以对读写都使用锁(或者在if
条件下使用锁)。顺便说一句,我无法复制您描述的确切条件(它对我有用),但至少锁应该 保证 这将是一个一致的结果。
看看这个例子:
import time
import threading
import cherrypy
@cherrypy.expose
class CherryPySleeps(object):
def __init__(self):
# share the same lock among read and write operations,
# the read is not "strictly" required, but you can use
# it to make sure there is no write happening at the
# same time
self._status_lock = threading.Lock()
# the internal status variable
self._status = "not sleeping"
@property
def status(self):
with self._status_lock:
return self._status
@status.setter
def status(self, new_status):
with self._status_lock:
self._status = new_status
@cherrypy.tools.accept(media='text/plain')
def GET(self):
if self.status == "not sleeping":
self.status = "sleeping"
time.sleep(10)
self.status = "not sleeping"
return "I finished sleeping"
else:
return "I am sleeping, shhh"
if __name__ == '__main__':
conf = {
'/': {
'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
'tools.sessions.on': True,
'tools.response_headers.on': True,
'tools.response_headers.headers': [('Content-Type', 'text/plain')],
}
}
cherrypy.quickstart(CherryPySleeps(), '/', conf)
还有其他方法可以做到这一点,使用 CherryPy 中的插件系统,但我认为对于这个例子来说没有必要。
在请求完成之前,模块级变量似乎实际上并不是 "changed"。 我需要它立即更新,以便其他请求可以知道工作正在处理中。
这是问题的一个例子:
import cherrypy
import time
@cherrypy.expose
class CherryPySleeps(object):
status = "not sleeping"
@cherrypy.tools.accept(media='text/plain')
def GET(self):
if CherryPySleeps.status == "not sleeping":
CherryPySleeps.status = "sleeping"
time.sleep(10)
CherryPySleeps.status = "not sleeping"
return "I finished sleeping"
else:
return "I am sleeping, shhh"
if __name__ == '__main__':
conf = {
'/': {
'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
'tools.sessions.on': True,
'tools.response_headers.on': True,
'tools.response_headers.headers': [('Content-Type', 'text/plain')],
}
}
cherrypy.quickstart(CherryPySleeps(), '/', conf)
当我打开 2 个浏览器选项卡时,在第一个请求页面,然后等待一秒钟,然后在第二个请求页面,我在每个选项卡上暂停 10 秒,然后 "I finished sleeping"。
我想要的是第二个选项卡能够非常快速地响应,"I am sleeping, shhh"
如果要保证请求(线程)之间的某种同步性,可以对读写都使用锁(或者在if
条件下使用锁)。顺便说一句,我无法复制您描述的确切条件(它对我有用),但至少锁应该 保证 这将是一个一致的结果。
看看这个例子:
import time
import threading
import cherrypy
@cherrypy.expose
class CherryPySleeps(object):
def __init__(self):
# share the same lock among read and write operations,
# the read is not "strictly" required, but you can use
# it to make sure there is no write happening at the
# same time
self._status_lock = threading.Lock()
# the internal status variable
self._status = "not sleeping"
@property
def status(self):
with self._status_lock:
return self._status
@status.setter
def status(self, new_status):
with self._status_lock:
self._status = new_status
@cherrypy.tools.accept(media='text/plain')
def GET(self):
if self.status == "not sleeping":
self.status = "sleeping"
time.sleep(10)
self.status = "not sleeping"
return "I finished sleeping"
else:
return "I am sleeping, shhh"
if __name__ == '__main__':
conf = {
'/': {
'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
'tools.sessions.on': True,
'tools.response_headers.on': True,
'tools.response_headers.headers': [('Content-Type', 'text/plain')],
}
}
cherrypy.quickstart(CherryPySleeps(), '/', conf)
还有其他方法可以做到这一点,使用 CherryPy 中的插件系统,但我认为对于这个例子来说没有必要。