Hi,
Thanks for taking the time to respond.  I was doing all of those things,
simple communication works fine but it breaks when trying to pass a client
capability to the server for it to use in the "publish" phase.
I eventually figured out if I add in a

kj::NEVER_DONE.wait( client.getWaitScope() );

at the end everything works, but locks at the end of the test fixture (as
you would expect).  I think I fundamentally misunderstood where the event
loop processing is done. I thought this was performed on a separate thread,
so a simple "this_thread::sleap_for(...)" would allow all the handlers in
the queue to finish (not the most optimal I know but I wanted to make sure
everything worked first).  I now know (think?) there must be a "wait()"
_somewhere_ to enter the event loop again on the current thread and clear
the queue.

Since I'm using this in test fixtures, NEVER_DONE is not an option because
I want to return control and carry on with other tests.

- Is there a way with the ez-rpc interfaces to process everything currently
in the queue and then return control?  I see EventLoop has a "run()" method
but I don't see a way to get the EventLoop from the EzRpcServer/Client.
- If not, is there something like "kj::DO_UNTIL.wait( seconds(1),
client.getWaitScope() )"; or a std::condition_variable style notification
to stop?
- With both client and server on the same event loop, there's no difference
between "client.getWaitScope()" and "server.getWaitScope()" right?

It does seem to be a great library by the way, the bits I've managed to get
working.

Thanks,

Mark.

On 25 August 2016 at 18:38, Kenton Varda <[email protected]> wrote:

> Hi Mark,
>
> Terminology note: Think of "capability" as meaning the same thing as
> "pointer", except it's a pointer that cannot be forged and without which
> you cannot otherwise access the target object. An "interface" describes the
> methods implemented by an object to which a capability points.
>
> What you describe should work, but there are a number of ways you might be
> getting it wrong. It's hard to say which without seeing your code, but here
> are some things to check:
>
> - Are you tearing down the RPC client too early? Once the network
> connection closes, all capabilities delivered through it become
> disconnected. Make sure you construct the RPC client (e.g. EzRpcClient)
> once, not every time you want to make a call.
>
> - Are you discarding promises before they complete? When you have a
> kj::Promise<T> representing an asynchronous task which hasn't completed
> yet, and you allow that promise to go out-of-scope (without calling .then()
> or anything else on it), the asynchronous task will be canceled. To prevent
> this, create a kj::TaskSet and add promises to the set -- the TaskSet
> ensures that the task runs to completion (unless you destroy the TaskSet,
> of course). For example:
>
>     void doThings(kj::TaskSet& tasks) {
>       kj::Promise<void> task1 = doSomething().then(...).then(...);
>       kj::Promise<void> task2 = doSomething().then(...).then(...);
>
>       tasks.add(kj::mv(task1));
>     }
>
> In the code above, only task1's .then()s will ever execute -- task2 will
> be canceled when the function returns.
>
> - Another reason why a .then() continuation might not execute is if an
> exception was thrown. You can catch exceptions by providing a second
> callback to .then() which takes kj::Exception as the parameter. Note that
> when creating a kj::TaskSet, you will be forced to provide an error
> callback which will be used whenever a task throws an exception -- I
> usually do KJ_LOG(ERROR, exception) inside that callback.
>
> -Kenton
>
> On Thu, Aug 25, 2016 at 3:14 AM, <[email protected]> wrote:
>
>> Hi,
>> I'm trying to develop an application that replicates remote objects
>> locally and keeps them updated.  This effectively boils down to a
>> publication-subscription model where the local proxy object sends an
>> interface (capability in capnp speak?) to the server that can be used to
>> send it notifications.  The server stores this interface pointer and
>> responds with an "okay", then later uses the interface to send the local
>> object notifications if the server-side object changes.
>> It doesn't work however.  If I use the interface pointer after the
>> original "subscription" call has resolved, the message is never received on
>> the client.  If I use the interface _during_ the subscription request the
>> message is received by the client, but the "then(...)" block on the server
>> is not executed.  I've looked through the calculator example, but that uses
>> the client-side interface immediately.
>>
>> - Can the interface pointers (capabilities right?) given in one call be
>> stored for later use?  I assume this must be the case but I can't be doing
>> it correctly.
>> - I'm using the ez-rpc interfaces.  Is this one of the use cases not
>> supported by them?
>> - As this is my most basic test case, both the client and server are in
>> the same compilation unit.  I don't do any thread manipulation myself so I
>> assume they're on the same event loop.  Is this an issue?  If so, I want
>> the single process use case for testing, so is starting one or the other on
>> a different thread sufficient?
>>
>> I can reduce the code to a simple example, but before going to the effort
>> I wanted to make sure I'm not misunderstanding something.
>>
>> Thanks,
>>
>> Mark.
>>
>> Cap'n Proto version 0.5.3
>>
>> --
>> 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].
>> Visit this group at https://groups.google.com/group/capnproto.
>>
>
>

-- 
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].
Visit this group at https://groups.google.com/group/capnproto.

Reply via email to