Hi all,
I've been having fun playing around with Cap'n Proto and attempting to
create simple subscriber/publisher classes using Cap'n Proto RPC and KJ.
I've created simple server/client pub/sub applications that use
TwoPartyServer and TwoPartyClient classes. I've attempted to wrap the
server app I made into it's own class using the constructor to setup the
connection/listening logic. My current method has been to copy the
implementation of the TwoPartyServer code and modify where needed.
The issue I'm facing is keeping the `listen()` promise alive to accept new
incoming connections whilst I continue to do other work in the rest of the
application.
Code for my normal working application:
```
kj::UnixEventPort::captureSignal(SIGINT);
auto io_context = kj::setupAsyncIo();
auto addrPromise =
io_context.provider->getNetwork().parseAddress("unix:/tmp/capnp-server-example");
auto addr = addrPromise.wait(io_context.waitScope);
auto addrListen = addr->listen();
capnp::TwoPartyServer server(kj::heap<PublisherImpl<capnp::Text>>(sub_map));
auto server_listen = server.listen(*addrListen);
auto& timer = io_context.provider->getTimer();
auto pub = publishLoop(timer, 1);
io_context.unixEventPort.onSignal(SIGINT).wait(io_context.waitScope);
std::cout << "Shutting down Publisher\n";
```
Code for my wrapped class application constructor (the rest of the class is
effectively the TwoPartyServer code):
```
template <typename T>
Publisher<T>::Publisher(const std::string& connection_address,
kj::AsyncIoContext& io_context)
: tasks_(*this), connection_address_(connection_address),
io_context_(io_context) {
auto listener =
io_context_.provider->getNetwork().parseAddress(connection_address);
auto addr = listener.wait(io_context.waitScope);
auto addrListen = addr->listen();
addTask(listen(*addrListen));
}
```
This builds fine but I get an exception when I run the server.
```
error: exception = kj/async.c++:2714: failed: PromiseFulfiller was
destroyed without fulfilling the promise.
```
I'm assuming the normal main application works because the `listen()`
promise remains in scope but when I attempt to add the `kj::Promise<void>`
to the member variable kj::TaskSet something isn't quite right.
My ideal situation would be this.
```
int main(int argc, const char** argv) {
// setup event loop etc.
auto io_context = kj::setupAsyncIO();
// Instantiate a publisher that accepts incoming connections
asynchronously.
auto pub = Publisher<capnp::Text>("unix:/tmp/capnp-server-example",
io_context);
// Start publishing at a specific frequency. Implementation involves a
kj::Timer with afterDelay().
pub.publishAtFrequency("Hello Subscribers", 1);
// Spin on this publisher. It should continue to accept new subscribers
whilst publishing.
pub.spin()
}
```
I hope I've given enough context and information. Please let me know if you
need more information and thank you for this awesome library!
Dan
--
You received this message because you are subscribed to the Google Groups
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/capnproto/3de22823-a51e-48e3-b0f1-d7fcc9538930n%40googlegroups.com.