【问题标题】:What is the simplest way to implement a remote FIFO queue as a Python GAE application?将远程 FIFO 队列实现为 Python GAE 应用程序的最简单方法是什么?
【发布时间】:2009-09-09 06:33:35
【问题描述】:

将远程 FIFO 队列实现为 Python GAE 应用程序然后将名称-值对字典推入/拉出它的最简单方法是什么?

例如,当对 GAE 应用程序进行 http get 时,GAE 应用程序将返回发布到应用程序且之前未从队列中拉出的最早的名称-值对集合。然后,这些名称-值对将在客户端重新实例化为字典。 urllib.urlencode 提供了一种将字典编码为参数的简单机制,但是当您 http“获取”参数时,将参数解码为字典的类似简单方法是什么?当队列中没有项目时,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

【问题讨论】:

    标签: python google-app-engine


    【解决方案1】:

    类似的东西:

    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 同步服务器)。不过,可能不是真正的问题,具体取决于您的用例。

    【讨论】:

    • 您认为可以向此队列添加命名空间支持吗?我想使用具有不同命名空间的同一个队列。
    • 数据存储区自动支持命名空间 - 只需设置命名空间即可。
    • 谢谢,还没有收到你评论的红包通知,所以,如你所知:-/,我问了一个关于这个话题的问题here
    【解决方案2】:

    以下假设您使用的是 webapp 框架。

    简单的答案是您只需使用 self.request.GET,它是一个 MultiDict(在许多情况下您可以将其视为 dict),其中包含发送到请求的表单数据。

    请注意,HTTP 允许表单数据多次包含相同的键;如果您想要的不是真正的 dict 而是已发送到您的应用程序的键值对列表,您可以使用 self.request.GET.items() 获得这样的列表(参见 http://pythonpaste.org/webob/reference.html#query-post-variables )然后将这些对添加到您的队列中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      相关资源
      最近更新 更多