Background Task for interacting with a third party API

0
0

What is the best way to pass Json objects to and from multiple clients for processing by a background task?

I need to have a background task that can process these Json objects on behalf of each client, using a third party API and a common key generated by an initial call to the third party. The key once generated is valid for several hours.

This key is used to allow the third party to process these Json objects and return a response to the background task.

The background task then needs to pass the response back to the client that originally called the background task with the requested Json object(response).

The Client will then modify use the Json object as a basis to create a new Json object and pass it back to the background task for processing by the third party.

NB the key will be invalid if the client calls the third party Api directly.

Many thanks for your help

  • You must to post comments
0
0

Hi Ewan,

The JSON objects you refer can be serialized/deserialized as strings. So you are looking for some way to share plain string.

There are several ways to share data among several sessions. Using Wisej you can use a static variable/property as explained in Global Variables thread.

Of course you can use database or some memory based cache like Redis.

HTH

  • You must to post comments
0
0

From the description I don’t think you need a background task. A background task is a thread that executes code and then ends or runs in a loop. It’s not something that is listening to requests. That’s a handler.

I would create an ashx handler and process the requests as they come in. The handler can obtain the key on first use and save it – remember to lock tje block that gets the key. If you mark the handler as reusable, the server will always use the same instance so you don’t even need statics.

It’s basically just a web service.

  • You must to post comments
0
0

Looks like I need to create and async hander to cope with the volume. Should be interesting as this is new territory for me!

 

  • Ewan Walker
    How do you lock the block?
  • Luca (ITG)
    The async handler only helps if the code in the handler is also async, otherwise it makes no difference. Every new request is always a new thread anyway. To lock a block of code simply use the lock keyword. In your case it’s necessary to synchronize the acquisition of the token since if has to be done only once.
  • You must to post comments
0
0

Hi Luca

With 2500 staff registering coming on / off shift at various times of the day at private locations across the country is there not a danger of running out of threads? I thought the aysnc handler made more efficient use of threads.

Does registering the handler as synchronised effectively achieve synchronisation of the token?

Value your thoughts

Ewan

  • You must to post comments
0
0

There is no “synchronized” handler. Every request is passed on a thread – so if you have shared resources your code has to be thread safe. You should simply create an ashx page in your Wisej app or in a separate asp.net app (makes no difference). This is the easiest way and doesn’t require any registration in web.config. Return true for the IsReusable property so only 1 instance is created to handle the requests.

You can save the token in an instance field and retrieve it in a synchronized block (lock block). Don’t worry about the threads, that’s handled by asp.net and the thread pool. You can tweak the thread pool settings in the web.config file, but I’d leave it alone.

The async IHttpAsyncHandler you are referring to doesn’t change anything in terms of requests and threads. All it does is to allow the code in the handler to return the thread to the thread pool when/if it has to wait for another thread to finish, like an external process or an async db request. It doesn’t save threads and doesn’t optimize much.

Wisej uses the IHttpAsyncHandler for the HTTP requests because it allows us to return from the request while suspending the thread when entering the server modal state for modal dialogs.

 

  • You must to post comments
0
0

Hi Luca

Many thanks for your help.

How do I set the HttpContext that my Handler requires?

Tried

context = HttpContext.Current; Set on the client Page

PPapiHandler obj = new PPapiHandler();
obj.ProcessRequest(context);

But this does not work because the fields within the context such as the response type cannot be changed by the handler.

I have tried all I can think of. The issue is generating a client context (that can be edited by the ASHX handler), that can be sent to the ASHX Handler so the response is received by the client.

Commands such as context.Response.ContentType = “text/plain”; fail because the HTTP headers are fixed.

As usual there is always a ‘Magic’ part for anything like this that you can’t guess.

The order of events needs to be

  1. client gets geo Location – OK
  2. geo location event is discontinued once location obtained
  3. Handler is called to get available shifts from third party
  4. Handler is called with chosen shift to update third party (that coincides with the geo location)

The issue is getting the VS generated handler to work by just returning a simple text message to start with.

  • You must to post comments
0
0

After much battling this appears to work, question is will it return the right responses to the correct clients?

  private void textLat_TextChanged(object sender, EventArgs e)
{
if (textLat.Text != “”)
{
Staffgeolocation.PositionChanged -= Staffgeolocation_PositionChanged;
    using (var nullWriter = new StreamWriter(Stream.Null))
{
var newRequestUri = new Uri(@context.Request.Url.GetLeftPart(UriPartial.Authority).ToString() + “/PPapiHandler.ashx”);
var newRequest = new HttpRequest(“”, newRequestUri.ToString(), newRequestUri.Query);
     var newResponse = new HttpResponse(nullWriter);
var newContext = new HttpContext(newRequest, newResponse);
newContext.Handler = obj;
newContext.Items.Add(“Sent”, “Message Sent”);
     obj.ProcessRequest(newContext);
     textResult.Text = newContext.Items[“Sent”].ToString();
    }
}
}
  • Luca (ITG)
    I don’t see the response part in the code snippet. The client in this snippet is the Wisej session that received the TextChanged event. I don’t understand why you are creating the HttpRequest and HttpResponse to use the ashx handler. I thought you needed the clients to use the ashx handler URL. You can simply use WebClient instead of creating everything in your code. Additionally, whetever it’s done in the ashx handler can be done in TextChanged – adding an handler like this is not necessary unless you want to do the request asynchronously.
  • You must to post comments
0
0
Hi Luca
 I found that this works with the context variable being set during the page load event.
  private void textLat_TextChanged(object sender, EventArgs e)
{
if (textLat.Text != “”)
{
Staffgeolocation.PositionChanged -= Staffgeolocation_PositionChanged;
context.ClearError();
    context.Items.Add(“Sent”, “Message Sent”);
obj.ProcessRequest(context);
textResult.Text = context.Items[“Str”].ToString(); [One of a set of response values]
   }
}
I could not get the ASHX to make any changes to the context, except by the addition of Items, so by adding items before calling the hander I can process them in the handler and add new items in the handler which the client can receive. I am probably missing something somewhere.
However this also works:
    WebClient webClient;
using (webClient = new WebClient())
{
string test = webClient.DownloadString(@”Http://” + context.Request.Url.Authority + “/PPapiHandler.ashx?P=New Message”);
}
Which will result in the API calls originating from the server?
< If you mark the handler as reusable, the server will always use the same instance so you don’t even need statics.>
Does this mean that the handler executes in a new thread but retains the previously set variable values contained within it?
  • You must to post comments
Showing 8 results
Your Answer

Please first to submit.