diff --git a/capnp/helpers/helpers.pxd b/capnp/helpers/helpers.pxd index 6e506f8..f34b530 100644 --- a/capnp/helpers/helpers.pxd +++ b/capnp/helpers/helpers.pxd @@ -1,4 +1,4 @@ -from capnp.includes.capnp_cpp cimport Maybe, DynamicStruct, Request, Response, PyPromise, VoidPromise, PyPromiseArray, RemotePromise, DynamicCapability, InterfaceSchema, EnumSchema, StructSchema, DynamicValue, Capability, RpcSystem, MessageBuilder, MessageReader, TwoPartyVatNetwork, PyRestorer, AnyPointer, DynamicStruct_Builder, WaitScope, AsyncIoContext, StringPtr, TaskSet, Timer +from capnp.includes.capnp_cpp cimport Maybe, DynamicStruct, Request, Response, PyPromise, VoidPromise, PyPromiseArray, RemotePromise, DynamicCapability, InterfaceSchema, EnumSchema, StructSchema, DynamicValue, Capability, RpcSystem, MessageBuilder, MessageReader, TwoPartyVatNetwork, AnyPointer, DynamicStruct_Builder, WaitScope, AsyncIoContext, StringPtr, TaskSet, Timer from capnp.includes.schema_cpp cimport ByteArray @@ -27,15 +27,8 @@ cdef extern from "capnp/helpers/capabilityHelper.h": VoidPromise convert_to_voidpromise(PyPromise&) cdef extern from "capnp/helpers/rpcHelper.h": - Capability.Client restoreHelper(RpcSystem&) - Capability.Client restoreHelper(RpcSystem&, MessageBuilder&) - Capability.Client restoreHelper(RpcSystem&, MessageReader&) - Capability.Client restoreHelper(RpcSystem&, AnyPointer.Reader&) - Capability.Client restoreHelper(RpcSystem&, AnyPointer.Builder&) Capability.Client bootstrapHelper(RpcSystem&) Capability.Client bootstrapHelperServer(RpcSystem&) - RpcSystem makeRpcClientWithRestorer(TwoPartyVatNetwork&, PyRestorer&) - PyPromise connectServerRestorer(TaskSet &, PyRestorer &, AsyncIoContext *, StringPtr) PyPromise connectServer(TaskSet &, Capability.Client, AsyncIoContext *, StringPtr) cdef extern from "capnp/helpers/serialize.h": diff --git a/capnp/helpers/non_circular.pxd b/capnp/helpers/non_circular.pxd index b0a9ffd..c220673 100644 --- a/capnp/helpers/non_circular.pxd +++ b/capnp/helpers/non_circular.pxd @@ -12,8 +12,6 @@ cdef extern from "capnp/helpers/capabilityHelper.h": PyRefCounter(PyObject *) cdef extern from "capnp/helpers/rpcHelper.h": - cdef cppclass PyRestorer: - PyRestorer(PyObject *) cdef cppclass ErrorHandler: pass diff --git a/capnp/helpers/rpcHelper.h b/capnp/helpers/rpcHelper.h index 54f3081..44f098f 100644 --- a/capnp/helpers/rpcHelper.h +++ b/capnp/helpers/rpcHelper.h @@ -6,73 +6,6 @@ #include "Python.h" #include "capabilityHelper.h" -extern "C" { - capnp::Capability::Client * call_py_restorer(PyObject *, capnp::AnyPointer::Reader &); -} - -class PyRestorer final: public capnp::SturdyRefRestorer { -public: - PyRestorer(PyObject * _py_restorer): py_restorer(_py_restorer) { - // We don't need to incref/decref, since this C++ class will be owned by the Python wrapper class, and we'll make sure the python class doesn't refcount to 0 elsewhere. - // Py_INCREF(py_restorer); - } - - // ~PyRestorer() { - // Py_DECREF(py_restorer); - // } - - capnp::Capability::Client restore(capnp::AnyPointer::Reader objectId) override { - GILAcquire gil; - capnp::Capability::Client * ret = call_py_restorer(py_restorer, objectId); - check_py_error(); - capnp::Capability::Client stack_ret(*ret); - delete ret; - - return stack_ret; - } - -private: - PyObject * py_restorer; -}; - -capnp::Capability::Client restoreHelper(capnp::RpcSystem& client, capnp::MessageBuilder & objectId) { - capnp::MallocMessageBuilder hostIdMessage(8); - auto hostId = hostIdMessage.initRoot(); - hostId.setSide(capnp::rpc::twoparty::Side::SERVER); - return client.restore(hostId, objectId.getRoot()); -} - -capnp::Capability::Client restoreHelper(capnp::RpcSystem& client, capnp::MessageReader & objectId) { - capnp::MallocMessageBuilder hostIdMessage(8); - auto hostId = hostIdMessage.initRoot(); - hostId.setSide(capnp::rpc::twoparty::Side::SERVER); - return client.restore(hostId, objectId.getRoot()); -} - -capnp::Capability::Client restoreHelper(capnp::RpcSystem& client, capnp::AnyPointer::Reader & objectId) { - capnp::MallocMessageBuilder hostIdMessage(8); - auto hostId = hostIdMessage.initRoot(); - hostId.setSide(capnp::rpc::twoparty::Side::SERVER); - return client.restore(hostId, objectId); -} - -capnp::Capability::Client restoreHelper(capnp::RpcSystem& client, capnp::AnyPointer::Builder & objectId) { - capnp::MallocMessageBuilder hostIdMessage(8); - auto hostId = hostIdMessage.initRoot(); - hostId.setSide(capnp::rpc::twoparty::Side::SERVER); - return client.restore(hostId, objectId); -} - -capnp::Capability::Client restoreHelper(capnp::RpcSystem& client) { - capnp::MallocMessageBuilder hostIdMessage(8); - auto hostId = hostIdMessage.initRoot(); - hostId.setSide(capnp::rpc::twoparty::Side::SERVER); - - capnp::MallocMessageBuilder blankMessage(8); - auto objectId = blankMessage.getRoot(); - return client.restore(hostId, objectId); -} - capnp::Capability::Client bootstrapHelper(capnp::RpcSystem& client) { capnp::MallocMessageBuilder hostIdMessage(8); auto hostId = hostIdMessage.initRoot(); @@ -87,63 +20,12 @@ capnp::Capability::Client bootstrapHelperServer(capnp::RpcSystem -capnp::RpcSystem makeRpcClientWithRestorer( - capnp::VatNetwork& network, - PyRestorer& restorer) { - using namespace capnp; - return RpcSystem(network, restorer); -} - -struct ServerContextRestorer { - kj::Own stream; - capnp::TwoPartyVatNetwork network; - capnp::RpcSystem rpcSystem; - - ServerContextRestorer(kj::Own&& stream, capnp::SturdyRefRestorer& restorer) - : stream(kj::mv(stream)), - network(*this->stream, capnp::rpc::twoparty::Side::SERVER), - rpcSystem(makeRpcServer(network, restorer)) {} -}; - class ErrorHandler : public kj::TaskSet::ErrorHandler { void taskFailed(kj::Exception&& exception) override { kj::throwFatalException(kj::mv(exception)); } }; -void acceptLoopRestorer(kj::TaskSet & tasks, PyRestorer & restorer, kj::Own&& listener) { - auto ptr = listener.get(); - tasks.add(ptr->accept().then(kj::mvCapture(kj::mv(listener), - [&](kj::Own&& listener, - kj::Own&& connection) { - acceptLoopRestorer(tasks, restorer, kj::mv(listener)); - - auto server = kj::heap(kj::mv(connection), restorer); - - // Arrange to destroy the server context when all references are gone, or when the - // EzRpcServer is destroyed (which will destroy the TaskSet). - tasks.add(server->network.onDisconnect().attach(kj::mv(server))); - }))); -} - -kj::Promise connectServerRestorer(kj::TaskSet & tasks, PyRestorer & restorer, kj::AsyncIoContext * context, kj::StringPtr bindAddress) { - auto paf = kj::newPromiseAndFulfiller(); - auto portPromise = paf.promise.fork(); - - tasks.add(context->provider->getNetwork().parseAddress(bindAddress) - .then(kj::mvCapture(paf.fulfiller, - [&](kj::Own>&& portFulfiller, - kj::Own&& addr) { - auto listener = addr->listen(); - portFulfiller->fulfill(listener->getPort()); - acceptLoopRestorer(tasks, restorer, kj::mv(listener)); - }))); - - return portPromise.addBranch().then([&](unsigned int port) { return PyLong_FromUnsignedLong(port); }); -} - struct ServerContext { kj::Own stream; diff --git a/capnp/includes/capnp_cpp.pxd b/capnp/includes/capnp_cpp.pxd index 450a05e..9e53c51 100644 --- a/capnp/includes/capnp_cpp.pxd +++ b/capnp/includes/capnp_cpp.pxd @@ -6,7 +6,7 @@ cdef extern from "capnp/helpers/checkCompiler.h": from libcpp cimport bool from schema_cpp cimport Node, Data, StructNode, EnumNode, InterfaceNode, MessageBuilder, MessageReader, ReaderOptions -from capnp.helpers.non_circular cimport PythonInterfaceDynamicImpl, reraise_kj_exception, PyRefCounter, PyRestorer, PyEventPort, ErrorHandler +from capnp.helpers.non_circular cimport PythonInterfaceDynamicImpl, reraise_kj_exception, PyRefCounter, PyEventPort, ErrorHandler from capnp.includes.types cimport * cdef extern from "capnp/common.h" namespace " ::capnp": @@ -365,7 +365,6 @@ cdef extern from "capnp/rpc-twoparty.h" namespace " ::capnp": TwoPartyVatNetwork(EventLoop &, AsyncIoStream& stream, Side, ReaderOptions) VoidPromise onDisconnect() VoidPromise onDrained() - RpcSystem makeRpcServer(TwoPartyVatNetwork&, PyRestorer&) RpcSystem makeRpcServerBootstrap"makeRpcServer"(TwoPartyVatNetwork&, Capability.Client) RpcSystem makeRpcClient(TwoPartyVatNetwork&) diff --git a/capnp/lib/capnp.pxd b/capnp/lib/capnp.pxd index 4d9c7e1..21c8950 100644 --- a/capnp/lib/capnp.pxd +++ b/capnp/lib/capnp.pxd @@ -2,7 +2,7 @@ from capnp.includes cimport capnp_cpp as capnp from capnp.includes cimport schema_cpp -from capnp.includes.capnp_cpp cimport Schema as C_Schema, StructSchema as C_StructSchema, InterfaceSchema as C_InterfaceSchema, EnumSchema as C_EnumSchema, ListSchema as C_ListSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr, String, StringTree, DynamicOrphan as C_DynamicOrphan, AnyPointer as C_DynamicObject, DynamicCapability as C_DynamicCapability, Request, Response, RemotePromise, PyPromise, VoidPromise, CallContext, PyRestorer, RpcSystem, makeRpcServer, makeRpcServerBootstrap, makeRpcClient, Capability as C_Capability, TwoPartyVatNetwork as C_TwoPartyVatNetwork, Side, AsyncIoStream, Own, makeTwoPartyVatNetwork, PromiseFulfillerPair as C_PromiseFulfillerPair, copyPromiseFulfillerPair, newPromiseAndFulfiller, PyArray, DynamicStruct_Builder, TwoWayPipe +from capnp.includes.capnp_cpp cimport Schema as C_Schema, StructSchema as C_StructSchema, InterfaceSchema as C_InterfaceSchema, EnumSchema as C_EnumSchema, ListSchema as C_ListSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr, String, StringTree, DynamicOrphan as C_DynamicOrphan, AnyPointer as C_DynamicObject, DynamicCapability as C_DynamicCapability, Request, Response, RemotePromise, PyPromise, VoidPromise, CallContext, RpcSystem, makeRpcServerBootstrap, makeRpcClient, Capability as C_Capability, TwoPartyVatNetwork as C_TwoPartyVatNetwork, Side, AsyncIoStream, Own, makeTwoPartyVatNetwork, PromiseFulfillerPair as C_PromiseFulfillerPair, copyPromiseFulfillerPair, newPromiseAndFulfiller, PyArray, DynamicStruct_Builder, TwoWayPipe from capnp.includes.schema_cpp cimport Node as C_Node, EnumNode as C_EnumNode from capnp.includes.types cimport * from capnp.helpers.non_circular cimport reraise_kj_exception @@ -103,14 +103,12 @@ cdef class _Schema: cpdef as_struct(self) cpdef as_interface(self) cpdef as_enum(self) - cpdef get_dependency(self, id) cpdef get_proto(self) cdef class _InterfaceSchema: cdef C_InterfaceSchema thisptr cdef object __method_names, __method_names_inherited, __methods, __methods_inherited cdef _init(self, C_InterfaceSchema other) - cpdef get_dependency(self, id) cdef class _DynamicEnum: cdef capnp.DynamicEnum thisptr diff --git a/capnp/lib/capnp.pyx b/capnp/lib/capnp.pyx index 367b78a..1310ea1 100644 --- a/capnp/lib/capnp.pyx +++ b/capnp/lib/capnp.pyx @@ -10,7 +10,6 @@ cimport cython -from capnp.helpers.helpers cimport makeRpcClientWithRestorer from capnp.helpers.helpers cimport AsyncIoStreamReadHelper from capnp.includes.capnp_cpp cimport AsyncIoStream, WaitScope @@ -24,7 +23,6 @@ from cpython.buffer cimport PyBUF_SIMPLE, PyBUF_WRITABLE from types import ModuleType as _ModuleType import os as _os import sys as _sys -import imp as _imp import traceback as _traceback from functools import partial as _partial import warnings as _warnings @@ -120,17 +118,6 @@ cdef public VoidPromise * call_server_method(PyObject * _server, char * _method_ return NULL -cdef public C_Capability.Client * call_py_restorer(PyObject * _restorer, C_DynamicObject.Reader & _reader) except * with gil: - restorer = _restorer - reader = _DynamicObjectReader()._init(_reader, None) - - ret = restorer._restore(reader) - cdef _DynamicCapabilityServer server = ret - cdef _InterfaceSchema schema = ret.schema - - return new C_Capability.Client(helpers.server_to_client(schema.thisptr, server)) - - cdef public convert_array_pyobject(PyArray & arr) with gil: return [arr[i] for i in range(arr.size())] @@ -2233,21 +2220,6 @@ cdef class _CapabilityClient: s = schema return _DynamicCapabilityClient()._init(self.thisptr.castAs(s.thisptr), self._parent) -cdef class _Restorer: - cdef PyRestorer * thisptr - cdef public object restore, _parent - - def __init__(self, restore, parent=None): - self.thisptr = new PyRestorer(self) - self.restore = restore - self._parent = parent - - def __dealloc__(self): - del self.thisptr - - def _restore(self, obj): - return self.restore(obj) - cdef class _TwoPartyVatNetwork: cdef Own[C_TwoPartyVatNetwork] thisptr cdef _AsyncIoStream stream @@ -2264,27 +2236,14 @@ cdef class _TwoPartyVatNetwork: cpdef on_disconnect(self) except +reraise_kj_exception: return _VoidPromise()._init(deref(self.thisptr).onDisconnect(), self) -cdef _Restorer _convert_restorer(restorer): - if isinstance(restorer, _RestorerImpl): - return _Restorer(restorer._restore, restorer) - elif type(restorer) is _Restorer: - return restorer - elif hasattr(restorer, 'restore'): - return _Restorer(restorer.restore, restorer) - elif callable(restorer): - return _Restorer(restorer) - else: - raise KjException("Restorer object ({}) isn't able to be used as a restore".format(str(restorer))) - cdef class TwoPartyClient: cdef RpcSystem * thisptr cdef public _TwoPartyVatNetwork _network cdef public object _orig_stream - cdef public _Restorer _restorer cdef public _AsyncIoStream _stream cdef public _TwoWayPipe _pipe - def __init__(self, socket=None, restorer=None, traversal_limit_in_words=None, nesting_limit=None): + def __init__(self, socket=None, traversal_limit_in_words=None, nesting_limit=None): if isinstance(socket, basestring): socket = self._connect(socket) @@ -2299,15 +2258,7 @@ cdef class TwoPartyClient: self._pipe = _TwoWayPipe() self._network = _TwoPartyVatNetwork()._init_pipe(self._pipe, capnp.CLIENT, opts) - if restorer is None: - self.thisptr = new RpcSystem(makeRpcClient(deref(self._network.thisptr))) - self._restorer = None - else: - _warnings.warn('Restorers are deprecated. Please use the new bootstrap methods.', UserWarning) - self._restorer = _convert_restorer(restorer) - self.thisptr = new RpcSystem(makeRpcClientWithRestorer(deref(self._network.thisptr), deref(self._restorer.thisptr))) - - Py_INCREF(self._restorer) + self.thisptr = new RpcSystem(makeRpcClient(deref(self._network.thisptr))) if self._orig_stream: Py_INCREF(self._orig_stream) Py_INCREF(self._stream) @@ -2355,47 +2306,6 @@ cdef class TwoPartyClient: sock.setsockopt(_socket.IPPROTO_TCP, _socket.TCP_NODELAY, 1) return sock - cpdef restore(self, objectId) except +reraise_kj_exception: - _warnings.warn('Restorers are deprecated. Please use the new bootstrap methods.', UserWarning) - cdef _MessageBuilder builder - cdef _MessageReader reader - cdef _DynamicObjectBuilder object_builder - cdef _DynamicObjectReader object_reader - - if objectId is None: - return _CapabilityClient()._init(helpers.restoreHelper(deref(self.thisptr)), self) - elif type(objectId) is _DynamicObjectBuilder: - object_builder = objectId - return _CapabilityClient()._init(helpers.restoreHelper(deref(self.thisptr), deref(object_builder.thisptr)), self) - elif type(objectId) is _DynamicObjectReader: - object_reader = objectId - return _CapabilityClient()._init(helpers.restoreHelper(deref(self.thisptr), object_reader.thisptr), self) - else: - if not hasattr(objectId, 'is_root'): - raise KjException("objectId was not a valid Cap'n Proto struct") - if not objectId.is_root: - raise KjException("objectId must be the root of a Cap'n Proto message, ie. addressbook_capnp.Person.new_message()") - - try: - builder = objectId._parent - except: - reader = objectId._parent - - if builder is not None: - return _CapabilityClient()._init(helpers.restoreHelper(deref(self.thisptr), deref(builder.thisptr)), self) - elif reader is not None: - return _CapabilityClient()._init(helpers.restoreHelper(deref(self.thisptr), deref(reader.thisptr)), self) - else: - raise KjException("objectId unexpectedly was not convertible to the proper type") - - cpdef ez_restore(self, textId) except +reraise_kj_exception: - # ez-rpc from the C++ API uses Text under the hood - ref = _MallocMessageBuilder().get_root_as_any() - # objectId is an AnyPointer, so we have a special method for setting it to text - ref.set_as_text(textId) - - return self.restore(ref) - cpdef bootstrap(self) except +reraise_kj_exception: return _CapabilityClient()._init(helpers.bootstrapHelper(deref(self.thisptr)), self) @@ -2406,7 +2316,6 @@ cdef class TwoPartyServer: cdef RpcSystem * thisptr cdef public _TwoPartyVatNetwork _network cdef public object _orig_stream, _server_socket, _disconnect_promise - cdef public _Restorer _restorer cdef public _AsyncIoStream _stream cdef public _TwoWayPipe _pipe cdef object _port @@ -2414,18 +2323,17 @@ cdef class TwoPartyServer: cdef capnp.TaskSet * _task_set cdef capnp.ErrorHandler _error_handler - def __init__(self, socket=None, restorer=None, server_socket=None, bootstrap=None, + def __init__(self, socket=None, server_socket=None, bootstrap=None, traversal_limit_in_words=None, nesting_limit=None): - if not restorer and not bootstrap: - raise KjException("You must provide either a bootstrap interface or a restorer (deperecated) to a server constructor.") + if not bootstrap: + raise KjException("You must provide a bootstrap interface to a server constructor.") cdef _InterfaceSchema schema cdef schema_cpp.ReaderOptions opts = make_reader_opts(traversal_limit_in_words, nesting_limit) - self._restorer = None self._bootstrap = None if isinstance(socket, basestring): - self._connect(socket, restorer, bootstrap) + self._connect(socket, bootstrap) return self._orig_stream = socket @@ -2444,12 +2352,7 @@ cdef class TwoPartyServer: self._bootstrap = bootstrap schema = bootstrap.schema self.thisptr = new RpcSystem(makeRpcServerBootstrap(deref(self._network.thisptr), helpers.server_to_client(schema.thisptr, bootstrap))) - elif restorer: - _warnings.warn('Restorers are deprecated. Please use the new bootstrap methods.', UserWarning) - self._restorer = _convert_restorer(restorer) - self.thisptr = new RpcSystem(makeRpcServer(deref(self._network.thisptr), deref(self._restorer.thisptr))) - Py_INCREF(self._restorer) Py_INCREF(self._orig_stream) Py_INCREF(self._stream) Py_INCREF(self._pipe) @@ -2479,23 +2382,19 @@ cdef class TwoPartyServer: len(data) ).wait(self._pipe._event_loop.thisptr.waitScope) - cpdef _connect(self, host_string, restorer, bootstrap): + cpdef _connect(self, host_string, bootstrap): cdef _InterfaceSchema schema cdef _EventLoop loop = C_DEFAULT_EVENT_LOOP_GETTER() cdef capnp.StringPtr temp_string = capnp.StringPtr(host_string, len(host_string)) self._task_set = new capnp.TaskSet(self._error_handler) - if restorer: - self._restorer = _convert_restorer(restorer) - self.port_promise = Promise()._init(helpers.connectServerRestorer(deref(self._task_set), deref(self._restorer.thisptr), loop.thisptr, temp_string)) - else: - self._bootstrap = bootstrap - Py_INCREF(self._bootstrap) - schema = bootstrap.schema - self.port_promise = Promise()._init(helpers.connectServer(deref(self._task_set), helpers.server_to_client(schema.thisptr, bootstrap), loop.thisptr, temp_string)) + + self._bootstrap = bootstrap + Py_INCREF(self._bootstrap) + schema = bootstrap.schema + self.port_promise = Promise()._init(helpers.connectServer(deref(self._task_set), helpers.server_to_client(schema.thisptr, bootstrap), loop.thisptr, temp_string)) def _decref(self): Py_DECREF(self._bootstrap) - Py_DECREF(self._restorer) Py_INCREF(self._pipe) Py_DECREF(self._orig_stream) Py_DECREF(self._stream) @@ -2589,11 +2488,6 @@ cdef class _Schema: cpdef as_enum(self): return _EnumSchema()._init(self.thisptr.asEnum()) - cpdef get_dependency(self, id): - '.. warning:: This method is deprecated and will be removed in the 0.6 release. You can access the fields directly from the schema now, so this method is superfluous and deprecated upstream' - _warnings.warn('This method is deprecated and will be removed in the 0.6 release. You can access the fields directly from the schema now, so this method is superfluous and deprecated upstream', UserWarning) - return _Schema()._init(self.thisptr.getDependency(id)) - cpdef get_proto(self): return _NodeReader().init(self.thisptr.getProto()) @@ -2676,11 +2570,6 @@ cdef class _StructSchema: def __get__(self): return _DynamicStructReader()._init(self.thisptr.getProto(), self) - cpdef get_dependency(self, id): - '.. warning:: This method is deprecated and will be removed in the 0.6 release. You can access the fields directly from the schema now, so this method is superfluous and deprecated upstream' - _warnings.warn('This method is deprecated and will be removed in the 0.6 release. You can access the fields directly from the schema now, so this method is superfluous and deprecated upstream', UserWarning) - return _Schema()._init(self.thisptr.getDependency(id)) - def __richcmp__(_StructSchema self, _StructSchema other, mode): if mode == 2: return self.thisptr == other.thisptr @@ -2814,11 +2703,6 @@ cdef class _InterfaceSchema: def __get__(self): return _DynamicStructReader()._init(self.thisptr.getProto(), self) - cpdef get_dependency(self, id): - '.. warning:: This method is deprecated and will be removed in the 0.6 release. You can access the fields directly from the schema now, so this method is superfluous and deprecated upstream' - _warnings.warn('This method is deprecated and will be removed in the 0.6 release. You can access the fields directly from the schema now, so this method is superfluous and deprecated upstream', UserWarning) - return _Schema()._init(self.thisptr.getDependency(id)) - def __repr__(self): return '' % self.node.displayName @@ -2991,20 +2875,13 @@ cdef _new_message(self, kwargs, num_first_segment_words): msg.from_dict(kwargs) return msg -class _RestorerImpl(object): - pass - class _StructModuleWhich(object): pass class _StructModule(object): def __init__(self, schema, name): - def _restore(self, obj): - return self.restore(obj.as_struct(self.schema)) self.schema = schema - self.Restorer = type(name + '.Restorer', (_RestorerImpl,), {'schema':schema, '_restore':_restore}) - # Add enums for union fields for field, raw_field in zip(schema.node.struct.fields, schema.fields_list): if field.which() == 'group': diff --git a/test/test_examples.py b/test/test_examples.py index d247549..1223549 100644 --- a/test/test_examples.py +++ b/test/test_examples.py @@ -10,7 +10,22 @@ examples_dir = os.path.join(os.path.dirname(__file__), '..', 'examples') def run_subprocesses(address, server, client): server = subprocess.Popen([os.path.join(examples_dir, server), address]) - time.sleep(1) # Give the server some small amount of time to start listening + retries = 30 + addr, port = address.split(':') + while True: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + result = sock.connect_ex((addr, int(port))) + if result == 0: + break + sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + result = sock.connect_ex((addr, int(port))) + if result == 0: + break + # Give the server some small amount of time to start listening + time.sleep(0.1) + retries -= 1 + if retries == 0: + assert False, "Timed out waiting for server to start" client = subprocess.Popen([os.path.join(examples_dir, client), address]) ret = client.wait() diff --git a/test/test_rpc.py b/test/test_rpc.py index 3d0ac40..535cba1 100644 --- a/test/test_rpc.py +++ b/test/test_rpc.py @@ -1,3 +1,7 @@ +''' +rpc test +''' + import pytest import capnp import socket @@ -7,103 +11,28 @@ import test_capability_capnp class Server(test_capability_capnp.TestInterface.Server): - def __init__(self, val=1): + def __init__(self, val=100): self.val = val def foo(self, i, j, **kwargs): return str(i * 5 + self.val) -def restore_func(ref_id): - return Server(100) - - -class SimpleRestorer(test_capability_capnp.TestSturdyRefObjectId.Restorer): - - def restore(self, ref_id): - assert ref_id.tag == 'testInterface' - return Server(100) - - -def test_simple_rpc(): - read, write = socket.socketpair(socket.AF_UNIX) - - restorer = SimpleRestorer() - _ = capnp.TwoPartyServer(write, restorer) - client = capnp.TwoPartyClient(read) - - ref = test_capability_capnp.TestSturdyRefObjectId.new_message(tag='testInterface') - cap = client.restore(ref) - cap = cap.cast_as(test_capability_capnp.TestInterface) - - remote = cap.foo(i=5) - response = remote.wait() - - assert response.x == '125' - - def test_simple_rpc_with_options(): read, write = socket.socketpair(socket.AF_UNIX) - restorer = SimpleRestorer() - _ = capnp.TwoPartyServer(write, restorer) + _ = capnp.TwoPartyServer(write, bootstrap=Server()) # This traversal limit is too low to receive the response in, so we expect # an exception during the call. client = capnp.TwoPartyClient(read, traversal_limit_in_words=1) - ref = test_capability_capnp.TestSturdyRefObjectId.new_message(tag='testInterface') with pytest.raises(capnp.KjException): - cap = client.restore(ref) - cap = cap.cast_as(test_capability_capnp.TestInterface) + cap = client.bootstrap().cast_as(test_capability_capnp.TestInterface) remote = cap.foo(i=5) _ = remote.wait() -def test_simple_rpc_restore_func(): - read, write = socket.socketpair(socket.AF_UNIX) - - _ = capnp.TwoPartyServer(write, restore_func) - client = capnp.TwoPartyClient(read) - - ref = test_capability_capnp.TestSturdyRefObjectId.new_message(tag='testInterface') - cap = client.restore(ref) - cap = cap.cast_as(test_capability_capnp.TestInterface) - - remote = cap.foo(i=5) - response = remote.wait() - - assert response.x == '125' - - -def text_restore_func(objectId): - text = objectId.as_text() - assert text == 'testInterface' - return Server(100) - - -def test_ez_rpc(): - read, write = socket.socketpair(socket.AF_UNIX) - - _ = capnp.TwoPartyServer(write, text_restore_func) - client = capnp.TwoPartyClient(read) - - cap = client.ez_restore('testInterface') - cap = cap.cast_as(test_capability_capnp.TestInterface) - - remote = cap.foo(i=5) - response = remote.wait() - - assert response.x == '125' - - cap = client.restore(test_capability_capnp.TestSturdyRefObjectId.new_message()) - cap = cap.cast_as(test_capability_capnp.TestInterface) - - remote = cap.foo(i=5) - - with pytest.raises(capnp.KjException): - response = remote.wait() - def test_simple_rpc_bootstrap(): read, write = socket.socketpair(socket.AF_UNIX) diff --git a/test/test_rpc_calculator.py b/test/test_rpc_calculator.py index 6beea16..d5b3d10 100644 --- a/test/test_rpc_calculator.py +++ b/test/test_rpc_calculator.py @@ -23,7 +23,35 @@ def test_calculator(): def run_subprocesses(address): server = subprocess.Popen([examples_dir + '/calculator_server.py', address]) - time.sleep(2) # Give the server some small amount of time to start listening + retries = 30 + if 'unix' in address: + addr = address.split(':')[1] + while True: + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + result = sock.connect_ex(addr) + if result == 0: + break + # Give the server some small amount of time to start listening + time.sleep(0.1) + retries -= 1 + if retries == 0: + assert False, "Timed out waiting for server to start" + else: + addr, port = address.split(':') + while True: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + result = sock.connect_ex((addr, int(port))) + if result == 0: + break + sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + result = sock.connect_ex((addr, int(port))) + if result == 0: + break + # Give the server some small amount of time to start listening + time.sleep(0.1) + retries -= 1 + if retries == 0: + assert False, "Timed out waiting for server to start" client = subprocess.Popen([examples_dir + '/calculator_client.py', address]) ret = client.wait() diff --git a/test/test_threads.py b/test/test_threads.py index 218557b..b53e2c0 100644 --- a/test/test_threads.py +++ b/test/test_threads.py @@ -44,7 +44,7 @@ class Server(test_capability_capnp.TestInterface.Server): ''' Server ''' - def __init__(self, val=1): + def __init__(self, val=100): self.val = val def foo(self, i, j, **kwargs): @@ -54,19 +54,6 @@ class Server(test_capability_capnp.TestInterface.Server): return str(i * 5 + self.val) -class SimpleRestorer(test_capability_capnp.TestSturdyRefObjectId.Restorer): - ''' - SimpleRestorer - ''' - - def restore(self, ref_id): - ''' - Restore - ''' - assert ref_id.tag == 'testInterface' - return Server(100) - - @pytest.mark.skipif( platform.python_implementation() == 'PyPy', reason="pycapnp's GIL handling isn't working properly at the moment for PyPy" @@ -81,8 +68,7 @@ def test_using_threads(): read, write = socket.socketpair(socket.AF_UNIX) def run_server(): - restorer = SimpleRestorer() - _ = capnp.TwoPartyServer(write, restorer) + _ = capnp.TwoPartyServer(write, bootstrap=Server()) capnp.wait_forever() server_thread = threading.Thread(target=run_server) @@ -90,10 +76,7 @@ def test_using_threads(): server_thread.start() client = capnp.TwoPartyClient(read) - - ref = test_capability_capnp.TestSturdyRefObjectId.new_message(tag='testInterface') - cap = client.restore(ref) - cap = cap.cast_as(test_capability_capnp.TestInterface) + cap = client.bootstrap().cast_as(test_capability_capnp.TestInterface) remote = cap.foo(i=5) response = remote.wait()