2

Google App Engine db.Model に基づいて FIFO キューを処理するために、次のアプローチを使用しています (この質問を参照してください)。

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

このキューは期待どおりに機能します (非常に良好)。

現在、私のコードには、遅延キューによって呼び出されるこの FIFO キューにアクセスするメソッドがあります。

def deferred_worker():
        data= QueueItem.pop()
        do_something_with(data)

独自のキューにアクセスする必要がある特定のクライアントを表す client_ID パラメータを追加して、このメソッドとキュー データ構造を強化したいと考えています。何かのようなもの:

def deferred_worker(client_ID):
        data= QueueItem_of_this_client_ID.pop() # I need to implement this
        do_something_with(data)

client_ID を認識できるようにキューをコーディングするにはどうすればよいですか?

制約:
- クライアントの数は動的であり、事前定義されていません
- Taskqueue はオプションではありません (1. 最大 10 個のキュー 2. 自分のキューを完全に制御したい)

新しい名前空間 APIを使用してこの動作を追加する方法を知っていますか(webapp.RequestHandler から db.Model を呼び出していないことを思い出してください)。
別のオプション:client_ID db.StringPropertyプル メソッドにフィルターを使用して QueueItem に追加できます。

QueueItem.all(keys_only=True).filter(client_ID=an_ID).order('created').fetch(10)

もっと良いアイデアはありますか?

4

2 に答える 2

1

私の元の回答に対する質問に答えて言ったように、これを名前空間で機能させるために何もする必要はありません。キューが構築されているデータストアはすでに名前空間をサポートしています。ドキュメントで説明されているように、名前空間を必要に応じて設定するだけです。

于 2010-10-19T09:11:18.647 に答える
1

「クライアント クラス」が実際にクライアントが呼び出すリクエスト ハンドラであると仮定すると、次のようなことができます。

from google.appengine.api import users
from google.appengine.api.namespace_manager import set_namespace

class ClientClass(webapp.RequestHandler):
  def get(self):
    # For this example let's assume the user_id is your unique id.
    # You could just as easily use a parameter you are passed.
    user = users.get_current_user()
    if user:
       # If there is a user, use their queue.  Otherwise the global queue.
       set_namespace(user.user_id())

    item = QueueItem.pop()
    self.response.out.write(str(item))

    QueueItem.push('The next task.')

または、名前空間app-wideを設定することもできます。

デフォルトの名前空間を設定すると、明示的に指定しない限り、データストアへのすべての呼び出しがその名前空間の「範囲内」になります。タスクを取得して実行するには、名前空間を知っている必要があることに注意してください。そのため、クリーンアップのために、デフォルトの名前空間に名前空間のリストを維持したいと思うでしょう。

于 2010-10-18T23:21:15.920 に答える