【问题标题】:How to use Memcache with ProtoRPC (Google App Engine - Python)如何将 Memcache 与 ProtoRPC 一起使用(Google App Engine - Python)
【发布时间】:2013-01-12 17:59:40
【问题描述】:

我正在尝试将 memcache 与 ProtoRPC 一起使用来加速某些过程(带有 Python 的 Google App Engine)。为了简化问题,我使用了Hello World 示例,并对其进行了一些修改。这是我的版本:

from protorpc import messages
from protorpc import remote
from protorpc.wsgi import service

from google.appengine.api import memcache

class HelloRequest(messages.Message):
  my_name = messages.StringField(1, required=True)

class ElementOfArrayResponse(messages.Message):
  value=messages.IntegerField(1)

class HelloResponse(messages.Message):
  hello = messages.StringField(1, required=True)
  list = messages.MessageField(ElementOfArrayResponse, 2, repeated=True)

class HelloService(remote.Service):
  @remote.method(HelloRequest, HelloResponse)
  def hello(self, request):
    response = memcache.get(request.my_name)

    if response is None:
      list = []
      for i in range(7):
        list.append(SomeElementResponse(value=i))
      response = HelloResponse(hello='Hello there, %s!' % request.my_name, list=list)
      memcache.set(request.my_name,response)
    return response

app = service.service_mappings([('/hello.*', HelloService)])

但是,不幸的是,此代码返回错误:ERROR 2013-01-12 17:17:31,081 service.py:196] Encountered unexpected error from ProtoRPC method implementation: PicklingError (Can't pickle <type 'weakref'>: attribute lookup __builtin__.weakref failed)。

但是,当我使用与原始 HelloResponse 几乎相同的代码时,memcache 工作得很好。

那么,我做错了什么?

【问题讨论】:

    标签: python google-app-engine python-2.7


    【解决方案1】:

    两件事,看起来您的 memcache 键是一个 List 对象(要确保您知道这一点)。在您的代码旁边,您必须在放入/退出 memcache api 时序列化 message 对象。

    这里是重写:

    from protorpc import remote
    from protorpc import messages
    from protorpc import protojson
    from protorpc.wsgi import service
    from google.appengine.api import memcache
    
    
    class HelloRequest(messages.Message):
      my_name = messages.StringField(1, required=True)
    
    class ElementOfArrayResponse(messages.Message):
      value=messages.IntegerField(1)
    
    class HelloResponse(messages.Message):
      hello = messages.StringField(1, required=True)
      list = messages.MessageField(ElementOfArrayResponse, 2, repeated=True)
    
    class HelloService(remote.Service):
      @remote.method(HelloRequest, HelloResponse)
      def hello(self, request):
        response = memcache.get(request.my_name)
        if response:
          # decode the value to a message..
          response = protojson.decode_message(HelloResponse, response)
        else:
          list = []
          for i in range(7):
            list.append(SomeElementResponse(value=i))
          response = HelloResponse(hello='Hello there, %s!' % request.my_name, list=list)
          # encode the message to a serializable format..
          value = protojson.encode_message(message)
          memcache.set(request.my_name, value)
        return response
    
    app = service.service_mappings([('/hello.*', HelloService)])
    

    【讨论】:

    • 很好的答案,谢谢。 (顺便说一句,hello(self,req) 函数有一点空白问题。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-27
    • 1970-01-01
    • 2016-08-10
    • 2011-08-15
    • 2015-08-12
    • 1970-01-01
    • 2013-11-26
    相关资源
    最近更新 更多