Abhijeet Sridhar
Abhijeet Sridhar

Reputation: 89

How to make an API call wait until the previous calls have been completed

I have an API in c# (MYAPI) which takes a request, and makes an API call to Unity (UNITYAPI) to perform some action.

The flow should be like this

Client -> MYAPI -> UnityAPI -> performs task -> response from UnityAPI to MYAPI -> response to client.

Now, A client can call MYAPI through different threads. MYAPI should wait for the previous MYAPI calls to complete (which in turn means that the UNITYAPI completed some action). MYAPI "CANNOT" send any request to UNITYAPI until the previous calls of MYAPI are responed back to the client.

Function in MYAPI to make api calls to UNITY API:

static async Task<string> PostURI(HttpContent c)
        {
            Uri uri = new Uri("http://localhost:4444");
            var response = string.Empty;
            using (var client = new HttpClient())
            {
                HttpResponseMessage result = null;

                try
                {
                    result = await client.PostAsync(uri, c);

                }
                catch (Exception ex)
                {
                    throw ex;
                }

                if (result.IsSuccessStatusCode)
                {
                    response = result.StatusCode.ToString();
                }
            }
            return response;
        }

Function in MYAPI which handles all the calls:

public void ProcessCalls(string operation)
        {

            HttpContent next = new StringContent(operation);

            while (isBlocked == true)
            {

            }

            isBlocked = true;

            var t = Task.Run(() => PostURI(next));
            t.Wait();

            isBlocked = false;

        }

Here, you can see the workaround I did. I just used a static variable isBlocked to make any call wait in an infinite while loop until any other operation is being done.

This works fine when I send 2 parallel calls to MYAPI. The second call waits for the first to complete, then proceeds to send call to UNITYAPI and waits. But when I send 3 calls in parallel, it breaks. The first call completes in unity but no response is received for any call. There must be an elegant way to do this.

So what i want is: -The client should be able to send multiple requests to MYAPI. -Each request should be made to wait till ALL the previous requests have sent a response back to client.

Thanks in advance.

EDIT 1: The method which calls ProcessCalls:


        [HttpPost]
        [Route("MyPostRoute")]
        public async void  MyPostRoute()
        {
            var request = new StreamReader(Request.Body).ReadToEnd();

            // Doing some validations on the request
            if (request.isValid())
            {
                await helperobject.ProcessCalls(request);
                //helperobject is an object of the class which has the two functions mentioned above.
            }
            else
                throw new Exception("Input was not in Correct format");
        }

Upvotes: 0

Views: 4358

Answers (1)

Fildor
Fildor

Reputation: 16104

Using a Semaphore, you need to make it static, so all instances of that class use the same one. Then you can go like this:

private static SemaphoreSlim processCallsSemaphore = new SemaphoreSlim(1,1);
// new SemaphoreSlim(1,1); => start with 1 count available and allow at max 1.

public async Task ProcessCalls(string operation)
{

    HttpContent next = new StringContent(operation);

    try
    {
        await processCallsSemaphore.WaitAsync();
        await PostURI(next);  // Assuming this is also an async API or can be made one.
    }
    finally
    {
        processCallsSemaphore.Release();
    }
}

Upvotes: 1

Related Questions