0

我正在尝试使用托管 VM 功能基于 Google App Engine 设置应用程序。

我正在使用使用 ctypes 用 C++ 编写的共享库

cdll.LoadLibrary('./mylib.so')

它注册了一个回调函数

CB_FUNC_TYPE = CFUNCTYPE(None, eSubscriptionType)
cbFuncType = CB_FUNC_TYPE(scrptCallbackHandler)

我想将数据保存到 ndb 数据存储区

def scrptCallbackHandler(arg):
    model = Model(name=str(arg.data))
    model.put()

我正在注册一个回调函数,我想在其中从 C++ 程序中获取数据并将其放入 ndb 数据存储区。这会导致错误。在开发服务器上,它的行为略有不同,因此在生产服务器上:

suspended generator _put_tasklet(context.py:343) raised BadRequestError(Application Id (app) format is invalid: '_')LOG 2 1429698464071045 suspended generator put(context.py:810) raised BadRequestError(Application Id (app) format is invalid: '_') Traceback (most recent call last): File "_ctypes/callbacks.c", line 314, in 'calling callback function' File "/home/vmagent/app/isw_cloud_client.py", line 343, in scrptCallbackHandler node.put() File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/model.py", line 3380, in _put return self._put_async(**ctx_options).get_result() File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/tasklets.py", line 325, in get_result self.check_success() File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along value = gen.throw(exc.__class__, exc, tb) File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/context.py", line 810, in put key = yield self._put_batcher.add(entity, options) File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along value = gen.throw(exc.__class__, exc, tb) File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/context.py", line 343, in _put_tasklet keys = yield self._conn.async_put(options, datastore_entities) File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/tasklets.py", line 454, in _on_rpc_completion result = rpc.get_result() File "/home/vmagent/python_vm_runtime/google/appengine/api/apiproxy_stub_map.py", line 613, in get_result return self.__get_result_hook(self) File "/home/vmagent/python_vm_runtime/google/appengine/datastore/datastore_rpc.py", line 1827, in __put_hook self.check_rpc_success(rpc) File "/home/vmagent/python_vm_runtime/google/appengine/datastore/datastore_rpc.py", line 1342, in check_rpc_success raise _ToDatastoreError(err)google.appengine.api.datastore_errors.BadRequestError: Application Id (app) format is invalid: '_'

C++ 程序的启动由对请求处理程序的调用触发,但在后台运行并接受应在回调中处理的传入数据。

更新:正如蒂姆已经指出的那样,wsgi 处理程序的上下文似乎丢失了。这里的解决方案很可能是以某种方式创建应用程序上下文。

4

1 回答 1

0

我只是在猜测我的问题是什么,我想告诉我我做了什么来解决它。

回调函数的执行上下文与 Python 应用程序的其余部分有些不同。回调中的任何异步操作都会失败。我尝试进行 http 调用或将其保存到数据存储区。操作永远不会完成,并且在 60 秒后应用程序显示一个错误,他们崩溃了。我猜这是因为 python 如何管理执行和相应的内存分配。

通过将回调包装在类中的闭包中,我能够在对象的上下文中执行回调。这不是真正的问题,但可以在这个答案中找到解决方案:如何让方法作为 python ctypes 的回调工作?

对于我的解决方案,我现在使用另一个模块上的云端点和 ctypes 模块上的后台线程的组合。

在 C-Callback 中,我启动了一个后台线程,该线程能够进行异步工作

# Start a background thread using the background thread service from GAE
background_thread.start_new_background_thread(putData, [name, value])

这里是它执行的简单任务:

# Here i call my cloud-endpoints
def putData(name, value):
    body = {
        'name' : 'name',
        'value' : int(value)
    }
    res = service.objects().create(body=body).execute()

当然我需要做错误处理和其他事情,但对我来说这是一个很好的解决方案。

注意:bg线程中的datastore添加模型失败,因为bg线程中的环境与应用程序不同,并且没有设置app id。

于 2015-04-23T11:04:07.950 回答