将远程FIFO队列实现为Python GAE应用程序,然后推送/拉出名称 - 值对字典的最简单方法是什么?
例如,当对GAE应用程序进行http get时,GAE应用程序将返回发布到应用程序的最旧的名称 - 值对集合,这些名称 - 值对之前尚未从队列中提取。然后,这些名称 - 值对将在客户端重新实例化为字典。 urllib.urlencode提供了一种简单的机制来将字典编码为参数,但当你“获取”它们时,将参数解码为字典的同样简单的方法是什么?当队列中没有项目时,GAE应用程序应返回null或客户端可以响应的其他更合适的标识符。
#A local python script
import urllib
targetURL="http://myapp.appspot.com/queue"
#Push to dictionary to GAE queue
params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
f = urllib.urlopen(targetURL, params)
print f.read()
params = urllib.urlencode({'foo': 1, 'bar': 2})
f = urllib.urlopen(targetURL, params)
print f.read()
#Pull oldest set of name-value pairs from the GAE queue and create a local dictionary from them.
#f = urllib.urlopen(targetURL, ……)
#returnedDictionary = ????
实施这个简短的GAE应用程序最简单的方法是什么?
#queue.py a url handler in a GAE application.
# For posts, create an object from the posted name-value pairs and insert it into the queue as the newest item in the queue
# For gets, return the name-value pairs for the oldest object in the queue and remove the object from the queue.
# If there are no items in the queue, return null
答案 0 :(得分:3)
这些方面的东西:
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import run_wsgi_app
class QueueItem(db.Model):
created = db.DateTimeProperty(required=True, auto_now_add=True)
data = db.BlobProperty(required=True)
@staticmethod
def push(data):
"""Add a new queue item."""
return QueueItem(data=data).put()
@staticmethod
def pop():
"""Pop the oldest item off the queue."""
def _tx_pop(candidate_key):
# Try and grab the candidate key for ourselves. This will fail if
# another task beat us to it.
task = QueueItem.get(candidate_key)
if task:
task.delete()
return task
# Grab some tasks and try getting them until we find one that hasn't been
# taken by someone else ahead of us
while True:
candidate_keys = QueueItem.all(keys_only=True).order('created').fetch(10)
if not candidate_keys:
# No tasks in queue
return None
for candidate_key in candidate_keys:
task = db.run_in_transaction(_tx_pop, candidate_key)
if task:
return task
class QueueHandler(webapp.RequestHandler):
def get(self):
"""Pop a request off the queue and return it."""
self.response.headers['Content-Type'] = 'application/x-www-form-urlencoded'
task = QueueItem.pop()
if not task:
self.error(404)
else:
self.response.out.write(task.data)
def post(self):
"""Add a request to the queue."""
QueueItem.push(self.request.body)
一个警告:因为队列排序依赖于时间戳,所以在不同机器上非常靠近的任务可能无序排队,因为没有全局时钟(只有NFS同步服务器)。可能不是一个真正的问题,取决于你的用例。
答案 1 :(得分:0)
以下假设您正在使用webapp框架。
简单的答案是你只需使用self.request.GET,它是一个MultiDict(你可以在很多情况下将其视为dict),其中包含发送给请求的表单数据。
请注意,HTTP允许表单数据多次包含相同的键;如果您想要的不是dict,而是已经发送到您的应用程序的键值对列表,您可以使用self.request.GET.items()获得这样的列表(参见http://pythonpaste.org/webob/reference.html#query-post-variables)然后将这些对添加到队列中。