Allow async capability implementation methods to return a tuple
This commit is contained in:
committed by
Jacob Alexander
parent
c037342615
commit
d53aa24733
@@ -99,6 +99,21 @@ cdef api void promise_task_add_done_callback(object task, object callback, VoidP
|
|||||||
cdef api void promise_task_cancel(object task):
|
cdef api void promise_task_cancel(object task):
|
||||||
task.cancel()
|
task.cancel()
|
||||||
|
|
||||||
|
def fill_context(method_name, context, returned_data):
|
||||||
|
if returned_data is None:
|
||||||
|
return
|
||||||
|
if not isinstance(returned_data, tuple):
|
||||||
|
returned_data = (returned_data,)
|
||||||
|
names = _find_field_order(context.results.schema.node.struct)
|
||||||
|
if len(returned_data) > len(names):
|
||||||
|
raise KjException(
|
||||||
|
"Too many values returned from `{}`. Expected {} and got {}"
|
||||||
|
.format(method_name, len(names), len(returned_data)))
|
||||||
|
|
||||||
|
results = context.results
|
||||||
|
for arg_name, arg_val in zip(names, returned_data):
|
||||||
|
setattr(results, arg_name, arg_val)
|
||||||
|
|
||||||
cdef api VoidPromise * call_server_method(object server,
|
cdef api VoidPromise * call_server_method(object server,
|
||||||
char * _method_name, CallContext & _context) except * with gil:
|
char * _method_name, CallContext & _context) except * with gil:
|
||||||
method_name = <object>_method_name
|
method_name = <object>_method_name
|
||||||
@@ -141,22 +156,15 @@ cdef api VoidPromise * call_server_method(object server,
|
|||||||
elif type(ret) is _Promise:
|
elif type(ret) is _Promise:
|
||||||
return new VoidPromise(helpers.convert_to_voidpromise(move((<_Promise>ret).thisptr)))
|
return new VoidPromise(helpers.convert_to_voidpromise(move((<_Promise>ret).thisptr)))
|
||||||
elif asyncio.iscoroutine(ret):
|
elif asyncio.iscoroutine(ret):
|
||||||
task = asyncio.create_task(ret)
|
async def finalize():
|
||||||
|
fill_context(method_name, context, await ret)
|
||||||
|
task = asyncio.create_task(finalize())
|
||||||
callback = _partial(void_task_done_callback, method_name)
|
callback = _partial(void_task_done_callback, method_name)
|
||||||
return new VoidPromise(helpers.taskToPromise(
|
return new VoidPromise(helpers.taskToPromise(
|
||||||
capnp.heap[PyRefCounter](<PyObject*>task),
|
capnp.heap[PyRefCounter](<PyObject*>task),
|
||||||
<PyObject*>callback))
|
<PyObject*>callback))
|
||||||
if not isinstance(ret, tuple):
|
else:
|
||||||
ret = (ret,)
|
fill_context(method_name, context, ret)
|
||||||
names = _find_field_order(context.results.schema.node.struct)
|
|
||||||
if len(ret) > len(names):
|
|
||||||
raise KjException(
|
|
||||||
"Too many values returned from `{}`. Expected {} and got {}"
|
|
||||||
.format(method_name, len(names), len(ret)))
|
|
||||||
|
|
||||||
results = context.results
|
|
||||||
for arg_name, arg_val in zip(names, ret):
|
|
||||||
setattr(results, arg_name, arg_val)
|
|
||||||
|
|
||||||
return NULL
|
return NULL
|
||||||
|
|
||||||
|
|||||||
@@ -68,8 +68,7 @@ class FunctionImpl(calculator_capnp.Calculator.Function.Server):
|
|||||||
another promise"""
|
another promise"""
|
||||||
|
|
||||||
assert len(params) == self.paramCount
|
assert len(params) == self.paramCount
|
||||||
value = await evaluate_impl(self.body, params)
|
return await evaluate_impl(self.body, params)
|
||||||
_context.results.value = value
|
|
||||||
|
|
||||||
|
|
||||||
class OperatorImpl(calculator_capnp.Calculator.Function.Server):
|
class OperatorImpl(calculator_capnp.Calculator.Function.Server):
|
||||||
@@ -101,8 +100,7 @@ class CalculatorImpl(calculator_capnp.Calculator.Server):
|
|||||||
"Implementation of the Calculator Cap'n Proto interface."
|
"Implementation of the Calculator Cap'n Proto interface."
|
||||||
|
|
||||||
async def evaluate(self, expression, _context, **kwargs):
|
async def evaluate(self, expression, _context, **kwargs):
|
||||||
value = await evaluate_impl(expression)
|
return ValueImpl(await evaluate_impl(expression))
|
||||||
_context.results.value = ValueImpl(value)
|
|
||||||
|
|
||||||
def defFunction(self, paramCount, body, _context, **kwargs):
|
def defFunction(self, paramCount, body, _context, **kwargs):
|
||||||
return FunctionImpl(paramCount, body)
|
return FunctionImpl(paramCount, body)
|
||||||
|
|||||||
Reference in New Issue
Block a user