Firebreath Events Acknowledgement - c++

I have created the plugin which is based on the Firebreath Framework. Implemented the Events to achieve the proper functionality of the Plugin.
Firebreath Events get fired asynchronously from JSAPIAuto.cpp class of the below method :
void FB::JSAPIAuto::fireAsyncEvent( const std::string& eventName, const std::vector<variant>& args )
I also used the same .but I want to get an acknowledgement of the same event when it is fired in the JSAPIAuto.cpp via some callback or anything ..
So that I can handle my next functionality in the PluginAPI.cpp based on the same result.
Any help would be appreciated !!!

If you read the text of the function, you'll see that the word "async" appears in it =] As that suggests, firing an even like this in FireBreath is asynchronous and does not allow you to give it a return value in any way. Because of the way events are implemented on some browsers there is no reasonable way to change that.
That said, you can do your own thing by having a function that you pass in a FB::JSObjectPtr to be stored and used as a callback; if you call that callback using Invoke with "" as the method name it will call the javascript function and return the value, like so:
bool MyScriptingAPI::setCallback(const FB::JSObjectPtr& callback) {
FB::variant res = callback->Invoke("", FB::variant_list_of("some")(3)("arguments"));
return res.convert_cast<bool>();
}
This will call your callback, cast the result to bool (true/false) and return the result to javascript. Obviously if something that can't cast to a bool is returned, an exception will be thrown, but you should get the general idea.

Related

Idiomatic way to handle request and asynchronous response in c++

I am working on a project that requires me to make use of 3rd party library. This library has a api to make a request for some data and register a callback that will be called when data is available. To link a request to it's response a unique integer tag is returned when a request is placed and same tag is returned when callback is invoked. Following is a signature of request creation api and callback.
void make_request(RequestData& data, (*cb)(int tag, Message *msg, void* closure), void* closure, int& tag)
Here closure parameter is something that we can set when making a request and same is returned as one of the parameter to callback.
My questions are -
What is a standard way of handling this type of communication in c++ (I am using c++17).
What is a name for such type of design. I need to know it so that I can study more about it.

freediameter - how to handle request messages outside of dispatch function

So, I've advertised for DCCA application in my extension via fd_disp_register and I can parse and prepare the response message and at the end sending them from my callback function with no issue.
This always works if the answer message is prepared inside of callback function. But what if i want to reply the request message outside of my callback function ?
So, I tried it with a sample code. I changed the callback function logic so there were no sending message from it and instead another thread tries to fetch some information and send out the response.
This absolutely failed, because as soon as callback returns (with 0), the next action gonna take place (according to disp_action value) which is not in my favor.
So, I'd like to ask what is your solution to handle such case, I mean sending out the response messages outside of the callback function ?
Thanks.
I'm not sure I've ever done this before, but looking at libfdproto.h...
enum disp_action {
DISP_ACT_CONT, /* The next handler should be called, unless *msg == NULL. */
DISP_ACT_SEND, /* The updated message must be sent. No further callback is called. */
DISP_ACT_ERROR /* An error must be created and sent as a reply -- not valid for callbacks, only for fd_msg_dispatch. */
};
...it sounds like you want to set *act = DISP_ACT_CONT; and *msg = NULL; (because you've taken ownership of the message).
Does that work?

Deadlock when dispatching notification in notification handler using Poco::NotificationCenter

I'm using Poco as part of a C++ app and I've run into an issue I don't quite understand. The app was translated from Obj-C and made heavy use of Apple's NSNotificationCenter.
To make the transition as painless as possible, I decided to use Poco's NotificationCenter instead. It works fine but I had some users reporting deadlocks I'm now trying to resolve.
Just a quick heads-up for those not familiar with NotificationCenter. You signup for a notification like this:
Poco::NotificationCenter& nc = Poco::NotificationCenter::defaultCenter();
nc.addObserver(Poco::NObserver<MyClass, MyNotification>(*this, &MyClass::onNotification));
and post a notification like this:
Poco::NotificationCenter& nc = Poco::NotificationCenter::defaultCenter();
nc.postNotification(new MyNotification());
The postNotification() method is defined like this:
void NotificationCenter::postNotification(Notification::Ptr pNotification)
{
poco_check_ptr (pNotification);
ScopedLockWithUnlock<Mutex> lock(_mutex);
ObserverList observersToNotify(_observers);
lock.unlock();
for (ObserverList::iterator it = observersToNotify.begin(); it != observersToNotify.end(); ++it)
{
(*it)->notify(pNotification);
}
}
And NObserver::notify() like this:
void notify(Notification* pNf) const
{
Poco::Mutex::ScopedLock lock(_mutex);
if (_pObject)
{
N* pCastNf = dynamic_cast<N*>(pNf);
if (pCastNf)
{
NotificationPtr ptr(pCastNf, true);
(_pObject->*_method)(ptr);
}
}
}
This is all really simple and doesn't involve any black magic.
Given the fact that the postNotification method always iterates over all observers (AFTER locking one and before checking if the type of the notification matches using a dynamic typecast) I'm assuming that this MUST always cause a deadlock when a notification is sent from a notification handler as it would also try to access the observer where itself is called from and will wait forever on the lock in NObserver::notify()?
From the process samples my users sent me it looks like my assumption is correct.
But for some reason this doesn't appear to deadlock in most cases (I never experienced it ever myself). I just stepped through with the debugger and couldn't make it lock up. Does anyone have an explanation why this only locks up under certain circumstances?

Facebook JavaScript API: run a line of code once asynch calls are completed

I have a piece of code which makes multiple nested calls to FB.api to retrieve certain information. Eventually, it creates an object called "myfriends" and stores my desired information in that object.
What I want to do is to use that object, after it is filled in with data (i.e. after all asynch calls are done), to run something else. In other words, I need a way for my code to know that those calls are complete. How can I do that?
call 'myfriends' after async request has completed.
Example:
FB.api('/me', function(response) {
alert('Your name is ' + response.name);
// Use 'myfriends' object here
});
I ended up using callback functions. The other problem I had was that my inner API call was in a loop; I ended up using an asynchronous looping function. This combination solved my problem.

Questions about QuickFIX message cracking

VERY basic questions from a FIX newbie
Looking at the documentation at http://www.quickfixengine.org and reading posts here on stackoverflow I see lots of talk about message 'cracking'. I think I sort of get the idea, but feel like I'm still not totally clear.
Can some explain in general what exactly this is (why is it necessary? it sounds like a hack), why it only seems relates to received FIX messages, and is not used at all when using Python?
Thank you!
In practice, all you need to know is this:
Your fromApp() callback gets a Message object. That message is actually a NewOrderSingle or ExecutionReport or something. Rather than making you figure it out, QF lets you inherit from MessageCracker. To use it, call crack() in your fromApp(), as follows:
void fromApp( const FIX::Message& message, const FIX::SessionID& sessionID )
throw( FIX::FieldNotFound&, FIX::IncorrectDataFormat&, FIX::IncorrectTagValue&, FIX::UnsupportedMessageType& )
{
crack(message, sessionID);
}
What crack() does is this:
Converts your Message into the proper subclass (e.g. NewOrderSingle, ExecutionReport, etc)
Calls your user-defined onMessage(subtype) callback, if defined. If not defined, it throws an UnsupportedMessageType exception and your app will automatically send a BusinessMessageReject (35=j) to the counterparty.
So, do you want to handle NewOrderSingle messages? Great, just define an onMessage(NewOrderSingle) callback.
void onMessage( const FIX42::NewOrderSingle& message, const FIX::SessionID& )
{
// Do whatever you want with your NewOrderSingle message's content.
// Note that this message and the one passed to crack() are the same, content-wise.
}
Do you want to handle ExecutionReports? Define onMessage(ExecutionReport). And so on.
But what about those message types you don't want to handle? It would suck if you had to add handlers to reject all those other message types, but luckily, you don't have to. As I said earlier, if you don't define an onMessage(), QF will reject it for you. (If you want to swallow a particular message type and ignore it without rejection, then just define an onMessage() call with no body.)
Does that clear it up a bit? Perhaps now this page in the QF docs might read a little easier -- the bottom section talks about the MessageCracker.
Note: The MessageCracker does not handle session-level (aka "admin") messages. If you want to add custom handling for, say, Logon or Heartbeat messages, you must do it explicitly in fromAdmin() (see this question for more info).
I use quickfixj for Java. The cracking uses and interface to return the cracked message to the interface implementation. The implementor will over ride the interface's methods so that it can handle each message type individually.
Message cracker takes a plain message and returns the message as a specifically typed message. The advantage of this is that the dictionary will confine the fields of the message so that it is easier to look up each field.