diff --git a/capnp/lib/capnp.pyx b/capnp/lib/capnp.pyx
index 84f357c..709cfe3 100644
--- a/capnp/lib/capnp.pyx
+++ b/capnp/lib/capnp.pyx
@@ -1814,13 +1814,16 @@ cdef class TwoPartyServer:
try:
self.on_disconnect().wait()
(clientsocket, address) = self._server_socket.accept()
+ self._orig_stream = clientsocket
self._stream = _FdAsyncIoStream(clientsocket.fileno())
self._network = _TwoPartyVatNetwork()._init(deref(self._stream.thisptr), capnp.SERVER)
self.thisptr = new RpcSystem(makeRpcServer(deref(self._network.thisptr), deref(self._restorer.thisptr)))
+ Py_INCREF(self._orig_stream)
+ Py_INCREF(self._stream)
+ Py_INCREF(self._network) # TODO:MEMORY: attach this to onDrained, also figure out what's leaking
except KeyboardInterrupt:
break
-
# TODO: add restore functionality here?
cdef class _FdAsyncIoStream:
diff --git a/docs/index.rst b/docs/index.rst
index 10c1dec..80ecfdf 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,6 +1,6 @@
.. capnp documentation master file
-Welcome to capnp's documentation!
+Welcome to pycapnp's documentation!
=================================
This is a python wrapping of the C++ implementation of the `Cap'n Proto `_ library. Here is a short description, quoted from its docs:
diff --git a/docs/install.rst b/docs/install.rst
index c4720d5..0a93527 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -28,7 +28,7 @@ On some systems you will have to install Python's headers before doing any of th
sudo apt-get install python-dev
-You can control what compiler is used with the environment variable CC, ie. `CC=gcc-4.8 pip install pycapnp`. You only need to run the setuptools line if you have a setuptools older than v0.8.0, and the cython line if you have a version older than v0.19.1.
+You can control what compiler is used with the environment variable CC, ie. `CC=gcc-4.8 pip install pycapnp`, and flags with CCFLAGS. You only need to run the setuptools line if you have a setuptools older than v0.8.0, and the cython line if you have a version older than v0.19.1.
From Source
---------------------
@@ -43,8 +43,6 @@ or::
cd pycapnp
python setup.py install
-If you don't use pip, you will need to manually install Cython, and a setuptools with a version >= .8.
-
Development
-------------------
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
index 7cd9f8a..76c6e9d 100644
--- a/docs/quickstart.rst
+++ b/docs/quickstart.rst
@@ -303,29 +303,21 @@ The examples below will be using `calculator.capnp `_ if you don't know what this means::
+
calculator = client.ez_restore('calculator').cast_as(calculator_capnp.Calculator)
There's two things worth noting here. First, we used the simpler `ez_restore` function. For servers that use a struct type as their Restorer, you will have to do the following instead::
@@ -383,35 +375,18 @@ You can also chain promises with `then` and the same pipelining will occur::
Server
~~~~~~~~~~~~~~
-Making a socket
-#################
-
-Again, any socket-like object will work, but here's how to do it with the :py:mod:`socket` module::
-
- host = '' # this will bind to all interfaces
- port = 60000
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
- # Optionally set TCP_NODELAY on socket to disable Nagle's algorithm
- s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
-
- s.bind((host, port))
- s.listen(1) # service only 1 client at a time
-
-Then, you will have to accept connections one at a time::
-
- (sock, address) = s.accept()
-
Starting a Server
##################
Once you have a socket, it's quite simple to start a server::
- server = capnp.TwoPartyServer(sock, restore)
+ server = capnp.TwoPartyServer('*:60000', restore)
server.run_forever()
-See the `Restore`_ section
+See the `Restore`_ section for an explanation of what the `restore` object needs to looks like.
+
+.. note:: You can also pass a socket with a `fileno()` method to TwoPartyServer. In that case, `run_forever` will not work, and you will have to use `on_disconnect.wait()`.
Implementing a Server
#######################
diff --git a/examples/calculator_client.py b/examples/calculator_client.py
index bc8adca..b1e04e1 100755
--- a/examples/calculator_client.py
+++ b/examples/calculator_client.py
@@ -32,8 +32,8 @@ at the given address and does some RPCs')
return parser.parse_args()
-def main(sock):
- client = capnp.TwoPartyClient(sock)
+def main(host):
+ client = capnp.TwoPartyClient(host)
# Pass "calculator" to ez_restore (there's also a `restore` function that
# takes a struct or AnyPointer as an argument), and then cast the returned
@@ -282,11 +282,4 @@ def main(sock):
print("PASS")
if __name__ == '__main__':
- host, port = parse_args().host.split(':')
-
- sock = socket.create_connection((host, port))
-
- # Set TCP_NODELAY on socket to disable Nagle's algorithm. This is not
- # neccessary, but it speeds things up.
- sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
- main(sock)
+ main(parse_args().host)
diff --git a/examples/calculator_server.py b/examples/calculator_server.py
index 248e701..ffd9867 100755
--- a/examples/calculator_server.py
+++ b/examples/calculator_server.py
@@ -138,35 +138,8 @@ def restore(ref):
def main():
address = parse_args().address
- if ':' in address:
- address, port = address.split(':')
- port = int(port)
- else:
- port = random.randint(60000, 61000)
-
- if address == '*':
- address = ''
-
- print("Listening on port: {}".format(port))
-
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
- # Set TCP_NODELAY on socket to disable Nagle's algorithm. This is not
- # neccessary, but it speeds things up.
- s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
-
- s.bind((address, port))
- s.listen(1) # service only 1 client at a time
-
- while True:
- try:
- (clientsocket, address) = s.accept()
- server = capnp.TwoPartyServer(clientsocket, restore)
-
- server.run_forever()
- print("client disconnected")
- except KeyboardInterrupt:
- break
+ server = capnp.TwoPartyServer(address, restore)
+ server.run_forever()
if __name__ == '__main__':
main()