How to serve multiple interfaces in Capnproto - capnproto

In the calculator example, I have added a new interface in the capnp file like below:
interface Main {
getCalculator #0 () -> (calculator :Calculator);
}
My objective is to make use of multiple interfaces through one implementation Main. How can I achieve this? The extra client code is below (when I try to use calculator it throws a null capability exception):
capnp::EzRpcClient client1(argv[1]);
Main::Client main = client1.getMain<Main>();
auto& waitScope1 = client1.getWaitScope();
auto request1 = main.getCalculatorRequest();
auto evalPromise1 = request1.send();
auto response1 = evalPromise1.wait(waitScope1);
auto calculator = response1.getCalculator();
auto request = calculator.evaluateRequest();
request.getExpression().setLiteral(123);
// Send it, which returns a promise for the result (without blocking).
auto evalPromise = request.send();
// Using the promise, create a pipelined request to call read() on the
// returned object, and then send that.
auto readPromise = evalPromise.getValue().readRequest().send();
// Now that we've sent all the requests, wait for the response. Until this
// point, we haven't waited at all!
auto response = readPromise.wait(waitScope1);
KJ_ASSERT(response.getValue() == 123);
Changes to the server's main implementation file are given below:
class MainImpl : public Main::Server {
public:
kj::Promise<void> getCalculator(GetCalculatorContext context) override {
context.getResults();
return kj::READY_NOW;
}
};
The main function in server serves MainImpl. I do get the calculator object but how can I further invoke methods on that object?

Your getCalculator() function on the server side does not do anything right now. You need to actually set the result if you want the Calculator to get back to the client. That's why you get your "null capability exception".
Something like this:
class MainImpl : public Main::Server {
public:
kj::Promise<void> getCalculator(GetCalculatorContext context) override {
context.getResults().setCalculator(<the calculator capability>);
return kj::READY_NOW;
}
};
That will require you to create the Calculator client on the server side (i.e. you won't do Calculator::Client calculator = client.getMain<Calculator>(); on the client side anymore, since calculator will come from getCalculator()).

Related

Mutiny Uni Convert to Primitive Type

Up until now I have done very basic things with smallrye Mutiny in Quarkus. Basically, I have one or two very small web services which only interact with a web application. These services return a Uni<Response>.
Now I'm writing a logging service I want my others to pass information to. In this logging service, I need to return a value to calling services. The logging service will return this value as a Uni<Integer>. What I'm struggling with is how to extract the return value in the calling service as an int.
Here is the function in the logging service
#GET
#Path("/requestid")
#Produces(MediaType.TEXT_PLAIN)
public Uni<Integer> getMaxRequestId(){
return service.getMaxRequestId();
}
public Uni<Integer> getMaxRequestId() {
Integer result = Integer.valueOf(em.createQuery("select MAX(request_id) from service_requests").getFirstResult());
if(result == null) {
result = 0;
}
return Uni.createFrom().item(result += 1);
}
And here is the client side code in the calling service
#Path("/requests")
public class RequestIdResource {
#RestClient
RequestIdServices service;
#GET
#Path("/requestid")
#Produces(MediaType.TEXT_PLAIN)
public Uni<Integer> getMaxRequestId(){
return service.getMaxRequestId();
}
}
public void filter(ContainerRequestContext requestContext) throws IOException {
int requestid = client.getMaxRequestId();
rm.name = ConfigProvider.getConfig().getValue("quarkus.application.name", String.class);
rm.server = requestContext.getUriInfo().getBaseUri().getHost();
rm.text = requestContext.getUriInfo().getPath(true);
rm.requestid = requestid;
}
Basically everything I have tried creates another Uni. Maybe I am simply using the concept all wrong. But how do I get the Integer out of the Uni so I can get the intValue?
You need to invoke a terminal operation, or use the value and continue the chain.
If you want to invoke a terminal operator you can invoke the await operation to make your code blocking and wait for the response.
If you want to merge this reactive invocation with another that is present in your client code, you can join or combine your actual Mutiny stream with the on coming from the response by using the combine method.
If you just want to use the value and do not retrieve it, you can suscribe and get the result.
If you have a multi you can call directly the method toList
Assuming that you want to have some timeouts involved and you want to get the actual Integer, you can go with the await method and a timeout.

rx subject onNext() without parameter typescript

Im using an observable to set a value in a different component. So in my NavigationComponent I have:
import toggleAside$ = SomeService.toggleAside$;
public toggleAdditionalInformation() {
toggleAside$.onNext(false);
}
And in the other component I have:
export const toggleAside$ = new Rx.Subject();
public showAside: boolean;
private toggleAsideView(): void {
toggleAside$.subscribe(() => {
this.showAside = !this.showAside;
});
}
I have a button the calls the toggleAdditionalinformation() function. This will create a stream with a false boolean value. In my other component I subscribe to the toggleAside$ stream. When something happens it will change the class propperty showAside. My code works as I want. But the value in the onNext() is not being used for anything. But it requires 1 parameter.
So am I abusing the onNext() function for this or is there a different solution with the parameters? An empy null object or something?
I'm using rx-lite Release 4.0.8

Fallback callback when calling unavailable function

Is it possible to set a fallback callback which is called when the user wants to call a function which does not exists? E.g.
my_object.ThisFunctionDoesNotExists(2, 4);
Now I want that a function is getting called where the first parameter is the name and a stack (or something like that) with the arguments passed. To clarify, the fallback callback should be a C++ function.
Assuming your question is about embedded V8 engine which is inferred from tags, you can use harmony Proxies feature:
var A = Proxy.create({
get: function (proxy, name) {
return function (param) {
console.log(name, param);
}
}
});
A.hello('world'); // hello world
Use --harmony_proxies param to enable this feature. From C++ code:
static const char v8_flags[] = "--harmony_proxies";
v8::V8::SetFlagsFromString(v8_flags, sizeof(v8_flags) - 1);
Other way:
There is a method on v8::ObjectTemplate called SetNamedPropertyHandler so you can intercept property access. For example:
void GetterCallback(v8::Local<v8::String> property,
const v8::PropertyCallbackInfo<v8::Value>& info)
{
// This will be called on property read
// You can return function here to call it
}
...
object_template->SetNamedPropertyHandler(GetterCallback);

Recursive call to IObservable in Windows Phone 7 application using Rx

We have a Windows Phone 7 application which uses a set of 3 service methods using Reactive Extensions, defined as follows:
public static class ServiceClient
{
public static IObservable<string> LookupImage(byte[] image) {...}
public static IObservable<XDocument> GetDefinition(string id) {...}
public static IObservable<Dictionary<string, byte[]>> GetFiles(string id, string[] fileNames) {...}
}
We need the WP7 application to keep calling LookupImage in the above client (each time with different set of byte[] image data) until the returned IObservable<string> is nonempty. After we get the Observable string we have to call GetDefinition and GetFiles methods (in that order).
The calls to LookupImage should happen as often as the service response is returned as opposed to being controlled by a timer as it will vary depending on network connection speed and we need to be able to send as many of these as possible.
I'd appreciate any pointers to what might be a solution to the above. As a start I have the following
private void RunLookupAndRenderLogic()
{
byte[] imageBytes = GetImageBytes();
// There are some cases where the image was not 'interesting' enough in which case GetImageBytes() returns null
if (pictureBytes != null)
{
// Where we have image data, send this to LookupImage service method
var markerLookup = ServiceClient.LookupImage(imageBytes);
markerLookup.Subscribe(id =>
{
// If the id is empty, we need to call this again.
if (String.IsNullOrEmpty(id))
{
???
}
// If we have an id, call GetDefinition and GetFiles methods of the service. No further calls to LookupImage should take place.
RenderLogic(id);
});
}
else
// If no interesting image was returned, try again
RunRecognitionAndRenderLogic();
}
Apologies if I get this wrong, but if I understand it correctly you want to Retry the call to LookupImage with the exact same argument, until it returns a value?
A naive way of solving this would be to simply call repeat and then take(1):
ServiceClient.LookupImage(imageBytes)
.Repeat()
.Take(1)
.Subscribe(id => ....);
However as Rx is single threaded by default, there is no point in this context that allows us to inject our disposal call (implicit from the Take(1)-->OnComplete()-->Auto disposal of subscription).
You can dodge this by offering some breathing space between subsequent re-subscriptions by using the CurrentThread Scheduler.
Observable.Defer(()=>
ServiceClient.LookupImage(imageBytes)
.ObserveOn(Scheduler.CurrentThread)
)
.Repeat()
.Take(1)
.Subscribe(id => ....);
There are other ways of achieving this with some good understanding of Rx and some creativity. (Most I would imagine a Scheduler)
To give you some inspriation check out the chapter on Scheduling and Threading. It covers recursion and building your own iterator which is effectively what you are trying to do.
Full code sample:
private void RunLookupAndRenderLogic()
{
byte[] imageBytes = GetImageBytes();
// There are some cases where the image was not 'interesting' enough in which case GetImageBytes() returns null
if (pictureBytes != null)
{
// Where we have image data, send this to LookupImage service method
var subscription = Observable
.Defer(()=>
ServiceClient.LookupImage(imageBytes)
.ObserveOn(Scheduler.CurrentThread)
)
.Where(id=>!String.IsNullOrEmpty(id))
.Repeat()
.Take(1)
.Subscribe(id =>
{
// If we have an id, call GetDefinition and GetFiles methods of the service. No further calls to LookupImage should take place.
RenderLogic(id);
});
//TODO: You dont offer any way to cancel this (dispose of the suscription).
//This means you could loop forever :-(
}
else
{
// If no interesting image was returned, try again
RunRecognitionAndRenderLogic();
}
}
(Disclosure: I am the author of IntroToRx.com)

V8: Passing object from JavaScript to uv_work function

OK, I have a function in C++ that I need to call from JavaScript, and one of the parameters is a JavaScript object. The JavaScript looks like this:
var message = {
fieldA: 42,
fieldB: "moo"
};
myObj.send(message, function (err) { console.log("Result: " + err); });
In the send() routine I need to call a native function in another C library that may block. All functions in this library may block so I've been using uv_queue_work extensively.
This routine is the first time I've hit an issue and it is because of the JavaScript object. The C++ code looks like this:
struct SendMessageRequest
{
Persistent<Object> message;
Persistent<Function> callback;
int result;
};
Handle<Value> MyObj::Send(const Arguments& args)
{
HandleScope scope;
// Parameter checking done but not included here
Local<Object> message = Local<Object>::Cast(args[0]);
Local<Function> callback = Local<Function>::Cast(args[1]);
// Send data to worker thread
SendMessageRequest* request = new SendMessageRequest;
request->message = Persistent<Object>::New(message);
request->callback = Persistent<Function>::New(callback);
uv_work_t* req = new uv_work_t();
req->data = request;
uv_queue_work(uv_default_loop(), req, SendMessageWorker, SendMessageWorkerComplete);
return scope.Close(Undefined());
}
This is all fine, the problem comes when I try to access request->message in the SendMessageWorker function.
void SendMessageWorker(uv_work_t* req)
{
SendMessageRequest* request = (SendMessageRequest*)req->data;
Local<Array> names = request->message->GetPropertyNames();
// CRASH
It seems that calling methods off of request->message causes an Access Violation on a really small address (probably a NULL pointer reference somewhere in V8/node). So using request->message directly must be wrong. I know to access the callback function I need to do this:
request->callback->Call(Context::GetCurrent()->Global(), 1, argv);
Do I need to use Context::GetCurrent()->Global() in order to access methods off of the Object class that is wrapped by the Persistent template? If so how do I do that?
The code in SendMessageWorker is not executed on the JavaScript - what uv_queue_work does is execute your SendMessageWorker in a separate thread, so it can let the node.js code run as well, and when it's ready, SendMessageWorkerComplete is executed back on the JavaScript thread.
So you can't use JavaScript variables in SendMessageWorker - if you really need to, you'd have to convert them to e.g. C++ string before calling uv_queue_work.

Resources