Idiomatic way to handle request and asynchronous response in c++ - 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.

Related

Is it possible to compile a static library with an external dependancy that is unresolvable at compilation time?

I've created a web server using C and C++, which works in the following way:
First, it initialize the socket for the connection.
Then, when the server receives an HTTP request, it calls a function that will retrieve the data form the request, and create an object which will parse the incoming request. (The object contains the request's parameters and headers).
Then, it calls a function named HandleRequest, and gives him the object created. The object's type is Request, which I wrote myself.
The HandleRequest function will analyze the request, generate an HTML document, and returns the whole document as a string.
Finally, The server takes the string returned by the HandleRequest function and send it back to the client.
Now, if I want to create another site, the only code I will have to changed is the HandleRequest function.
My point is I want to pack the server itself in a static library, and then when I want to make a new website, I only have to write the HandleRequest function and link the static library when compiling to make the server.
Of course, when I try to do so, I have the error
undefined reference to 'HandleRequest'
So is it possible to make the library compile, knowing that a function has its code written outside of the library ?
Edit: I tried to compile the .cpp file with without the -c option, so that the library already have the linking done. I am aware that with the -c option, everything works fine.
Also, I tried to put
extern std::string HandleRequest(Request request);
before the function that calls HandleRequest but it didn't worked.
Quick and easy solution
Make HandleRequest a global variable that’s function pointer:
std::string (*HandleRequest)(Request);
You can move the functionality of the old HandleRequest function into something like DefaultHandleRequest, and you can even initialize the function pointer using the DefaultHandleRequest:
std::string DefaultHandleRequest(Request request)
{
// stuff
}
std::string (*HandleRequest)(Request) = DefaultHandleRequest;
If you do this, you won’t have to change any other code, but you’ll be able to update HandleRequest whenever you like.
More thorough solution
We can make this solution much more general, enabling you to have multiple servers running in the same program.
In order to do this, make a Server class, which acts as the server. An instance of this class will act as your server. Have Server store a std::function<std::string(Request)> that handles incoming requests. You can assign or update this at any time, as necessary.
Design Server so that there can be multiple instances at once, each representing a different server/service with it’s own HandleRequest function.

Thread Safety in Jax-WS Request-Response Payload Logging

I am working on a SoapHandler implementation. Basically my aim is to get both request and response payloads and insert them to the database.
Although I can get the request and response payloads, I couldn't make sure if my code is working thread-safe. In other words, I am not sure if responses match with the proper requests.
public boolean handleMessage(SOAPMessageContext mContext) {
boolean isResponse = (Boolean) mContext
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (!isResponse) {
try {
mContext.put("currentStream", new ByteArrayOutputStream());
mContext.getMessage().writeTo((OutputStream) mContext.get("currentStream"));
} catch (SOAPException | IOException e) {
e.printStackTrace();
}
} else {
try {
mContext.getMessage().writeTo(
(OutputStream) mContext.get("currentStream"));
System.out.println(((OutputStream) mContext.get("currentStream"))
.toString());
((OutputStream) mContext.get("currentStream")).flush();
} catch (SOAPException | IOException e) {
e.printStackTrace();
}
}
return true;
}
I found this in JCP specs:
9.3.3 Handler Implementation Considerations
Handler instances may be pooled by a JAX-RPC runtime system. All instances of a specific handler are
considered equivalent by a JAX-RPC runtime system and any instance may be chosen to handle a particular
message. Different handler instances may be used to handle each messages of an MEP. Different threads
may be used for each handler in a handler chain, for each message in an MEP or any combination of the
two. Handlers should not rely on thread local state to share information. Handlers should instead use the
message context, see section 9.4.
9.4 Message Context
Handlers are invoked with a message context that provides methods to access and modify inbound and
outbound messages and to manage a set of properties.
Different types of handler are invoked with different types of message context. Sections 9.4.1 and 9.4.2
describe MessageContext and LogicalMessageContext respectively. In addition, JAX-RPC bindings 12
may define a message context subtype for their particular protocol binding that provides access to protocol
specific features. Section10.3 describes the message context subtype for the JAX-RPC SOAP binding.
http://download.oracle.com/otn-pub/jcp/jaxrpc-2.0-edr2-spec-oth-JSpec/jaxrpc-2_0-edr2-spec.pdf?AuthParam=1431341511_1ac4403a34d7db108bce79eda126df49
Does this imply that a new MessageContext object is created for each request (in which case I think the code will be thread safe), or the same MessageContext object can be used for multiple requests (then my code will not be thread safe).
Any help / alternative solution will be appreciated.
Rule of thumb: a FooContext object is contextual by definition, relating to a specific execution context. EJBContext relating to a single EJB; FacesContext relating to a single Faces request context; SOAPMessageContext relating to a single SOAPMessage. From the JSR-109 documentation:
The container must share the same MessageContext instance across all Handler instances and the target endpoint that are invoked during a single request and response or fault processing on a specific node.
So, you can be sure that there's one new SOAPMessageContext instance per request. Within the context of a single request however, that instance is yours to mangle. So the question really is, what do you mean by "threadsafety"? Do you plan to have multiple threads processing a single SOAPMessageContext during each request? I don't recommend it
EDIT: While the specification doesn't state in black and white that a MessageContext is threadsafe, it's implied throughout the specification. The following is an excerpt from the section of the spec that states what's possible on a MessageContext, within a handler:
Handlers may manipulate the values and scope of properties within the message context as desired. E.g. ... a handler in a server-side SOAP binding might add application scoped properties tot he message context from the contents of a header in a request SOAP message...
SOAP handlers are passed a SOAPMessageContext when invoked. SOAPMessageContext extends MessageContext with methods to obtain and modify the SOAP message payload
The specification won't be expecting programmers to modify the content of the context if it weren't safe to do so.

Passing parameters in Client server model

I have a Client that communicate with the Server using web-services.
The Model layer is implemented in the server side,
and I wonder what is the right way to pass parameters in the web-service methods.
Should it pass primitive types (and DataSets) or Objects?
For example, If I have the object Pesron, and I want my web-service to add new person
Should I pass the Object to the web-service method (i.e. AddNewMethod(Person newPerson)) or,
should I pass Primitives to the web-service method (i.e. AddNewMethod(int pId, String pName))
Thanks.
you should use AddNewMethod(Person newPerson)).
Reasons:
1. Cleaner code.
2. Less prone to errors.
3. You can use data model client side.
4. You are not going for overloading of functions? AddNewMethod(int pId, String pName) gives you options for overloading.

How to wrap a C++11 callback?

I'm using Casablanca C++ Rest SDK for http connections. Here is a basic piece of code that makes a http request.
Copied from Casablanca documentation:
// Creates an HTTP request and prints the length of the response stream.
pplx::task<void> HTTPStreamingAsync()
{
http_client client(L"http://www.google.com");
// Make the request and asynchronously process the response.
return client.request(methods::GET).then([](http_response response)
{
// Response received, do whatever here.
});
}
This will do an asynchronous request and do a callback when done. I need to make my own class that uses these codes and I want to wrap it to my own callback.
For simplicity, assume that I want to make a class that has method which print html code of google.com.
So I expected something like this:
MyClass myObject;
myObject.getGoogleHTML([](std::string htmlString)
{
std::cout << htmlString;
});
I searched and read related articles like:
C++ class member callback simple examples
C++11 styled callbacks?
Friday Q&A 2011-06-03: Objective-C Blocks vs. C++0x Lambdas: Fight!
But I'm still a bit confused as I get used with completion block in Objective-C. How can I construct such a class that wraps callback?
Take the lambda as a general type. As a bonus, it'll work with any other callable object.
template<typename F>
pplx::task<void> MyClass::getGoogleHTML(F f) {
http_client client(L"http://www.google.com");
return client.request(methods::GET).then(f);
}
You could also perfectly forward f via F &&f and .then(std::forward<F>(f)) if you wish. If you're actually looking to extract something to give to the passed-in lambda, pass a lambda to then that captures f and calls it with that extracted data.

Firebreath Events Acknowledgement

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.