HTTP.Request() and binding to response

Hi all…

I’m developing an HTTP REST api in C++. For the sake of simplicity lets say that I have a website that has these end points where each endpoint takes some JSON data.

  • Website/StartProcess
  • Website/EndProcess
  • Website/GetProcessStatus

In my code, I have a single class that wraps the functionality of making these calls. This class has a single FHttpRequestPtr variable. _httpReq;

When making the actual HTTP request for any one of those end points, it pretty much looks like this.

  1. Create the URL for _httpReq
  2. Create the header _httpReq
  3. Bind _httpReq->OnProcessRequestComplete() for the given http call to _httpReq to the proper callback function.
  4. Make the http request

My callbacks look like this ( not showing param list ), basically there is a 1:1 relationship between the HTTP Endpoint being called and the callback function being bound to the _httpReq->OnProcessRequestComplete() binding.

  • OnStartProcess_Complete(…)
  • OnEndProcess_Complete(…)
  • OnGetProcessStatus_Complete(…)

That’s the setup and it actually seems to be working properly…

HOWEVER!

I have a couple questions about this because I am never unbinding anything.

  1. Right now, lets say that I call StartProcess 5 times in a row, the _httpReq->OnProcessComplete() would be bound to the same function every call.
    Is that bad? Or do we need to unbind at the end of every response event especially if we are switching up what callback functions are being bound?

  2. Lets say I have two http calls that are getting created at roughly the same time… A race condition so to speak.
    call-1 kicks off and calls /StartProcess. _httpReq->OnProcessComplete() is bound to OnStartProcess_Complete()
    …. call-1 is running, has not complete
    call-2 kicks off and calls /EndProcess. _httpReq->OnProcessComplete() is bound to OnEndProcess_Complete()

Keeping in mind that the last _httpReq->OnProcessComplete() was bound to OnEndProcess_Complete()
call-1 completes and calls the response callback is triggered. Will the wrong callback be called? OR, is the FHttpRequestPtr object smart enough to know what callback was registered at the time each http request was sent?
It’s starting to feel like, because I have one class handling different endpoints and callbacks, that I might need to have a separate FHttpRequestPtr for each http endpoint/callback that I am using. I hope that’s not the case, because what if you had 30+ endpoints you needed to manage, that would be a lot of FHttpRequestPtr objects to maintain.

Any help will be GREATLY appreciated!

If you’re already in the C++ source, you can just use F12 to navigate to the implementation of OnProcessRequestComplete() to see how it’s used.

In general, until an object gets garbage collected, it will retain memory. However, if there’s only one of the objects, and it will be re-used later, then that’s OK.

OnProcessRequetsComplete() returns a reference to a FHttpRequestCompleteDelegate which is a single-call delegate instance. Each call to Bind() it will implicitly remove the previous binding. You can tell, because it’s declared with DECLARE_DELEGATE_ThreeParam and not something like DECLARE_MULTICAST_DELEGATE... You can look at the implementation of TDelegate<> for more details.

If you retain the IHttpRequest and it is in turn bound to some UObject function, then this will keep that UObject alive in garbage collection, so if you rely on garbage collection to clean up your UObjects, you need to un-bind the object when you’re done.

Note that the “request” is a single request. If you want to run multiple requests in parallel, you need multiple request objects.

Hi jwatte…

Thanks for the reply… Just as a FYI, i revised my post a bit to try and be more clear.
However based on what you just mentioned, it sounds like (based on a single instance of FHttpRequestPtr shared in my data access class)

  • FHttpRequestPtr can only have 1 reqest running at a time.
  • If that is the case, what happens if a second request to a different endpoint comes in while the first request is still running? Does the code just stop on the OnProcessRequest() function call until the response has completed? Or does something really bad happen like a crash?

In looking at how this all works a bit closer, it seems like what I SHOULD be doing is, every time I need to make a new http request to a URL, I should:

  1. Construct a brand new FHttpRequestPtr
  2. Setup the httpPtr as I usually do, header info, url info, OnProcessRequestComplete( myCallbackFunc )
  3. Call httPtr->ProcessReqest()
  4. Then in the callback function, which has as one of it’s parameters an instance of FHttpRequestPtr (which I assume is the same pointer created in step 1), unbind, then destroy it. Or will GC auto destroy it since I created a local copy in a class function on my main class?

FHttpRequestPtr represents a single request. You should construct a new one with every request you make, regardless of the endpoint. You are not meant to reuse them.

All the request delegates (eg. RequestComplete) include the FHttpRequestPtr as a parameter, so you don’t need to store them in variables. Just use the parameter. It’s all handled by the http manager.

And since each request is its own dedicated object, no need to unbind delegates.

jwatte, Chatouille

Thanks so much for your guys help! It allowed me to catch and fix a HUGE potential bug before it ever reared it’s ugly head!

I have it now where I create a local instance of FHttpRequestPtr in a function, I’m not storing it in a class variable any more. Every time a new request needs to be made, I create a new FHttpRequestPtr, set it up with everything call ProcessRequest()… Seems to be working perfectly as expected!