4

I have a requirement where user is sending one record at a time to a third party system using SOAP API. @future is used to send out web calls. Once the request goes out, I need to poll third party server to get the status of my webservice.

I have tried two approach for polling. I tried introducing delay between webservice callout and polling function using

 while(System.Now().millisecond()< delay+1000){}

However this method results in reaching 200000 apex line limit.

If I try not to include the delay, I am hitting 10 callout limit.

I am not sure how to tackle this problem.

3 Answers 3

5

There are a couple of options to consider for this type of polling. Unfortunately Apex does not have a native 'sleep' type call, so you must do this via a client / VF polling approach or using Batch Apex.

  • "apex:actionPoller", this is a Visualforce page feature and can be used to trigger some Apex code in your controller class after a set interval. You can retain the id or reference returned from your first web service call in your controller and poll the web service each time the controller method is called.
  • "Batch Apex", instead of using @future (which does not allow other @future calls to be made), utilise a Batch Apex job that issues the original web service call, then in the finish method poll your web service again. If there is still no response, you can start a Batch Apex job. This approach requires a good understanding of Batch Apex however. You will likely need to use it with a customer iterator.
2
  • Thanks for the reply @AndrewFawcett, I am planning to go with the apex:actionPoller approach which will call a function to get status from the third party server. Is it possible to tell the poller to abort when a certain status is returned?
    – Yash Mehta
    Commented May 2, 2013 at 19:28
  • I have found the best approach is to use the 'rendered' attribute. I've used this in the following example where the Salesforce Metadata API (also a Web Service) returns an AsyncResult. Take a look at this for a general idea of what i did, github.com/financialforcedev/apex-mdapi/blob/master/apex-mdapi/… Commented May 3, 2013 at 12:14
5

A couple of other strategies if you have any control over the behaviour of the webservice on the other end.

  1. If you can get the webservice to do it's work and then return the status I believe you can have up to 120seconds between sending the request and getting the response. So instead of polling, you just wait for the webservice to reply with success details.
    HTTPResponse res = http.send(req);
  2. Alternatively, if the destination webservice is long running or runs on a schedule, you could try having a callback from that service once it is finished. So you would write an incoming webservice on Salesforce which the external system could call into with the results of the processing whenever it is finished.

If you don't have any influence over the behaviour of the external system webservice then Andrews suggestions are the way to go.

1

I think Andrew's answer is a good one. If you have a Visualforce page to work from, then using the actionPoller approach is the way to go. But if you don't have a VF page open at this time, you could also consider leveraging an hourly schedule that "wakes up" and checks to see if work needs to be done.

Or adding to what Andrew suggested, you could use a custom object with, for example, 500 records in it. Set the batch size to 1 record per batch like this:

YourBatchClass ybc = new YourBatchClass();
Database.executeBatch(ybc, 1);

Then it can try the callout once per record, calling out as many times as you wish. Simply create as many records as you would like to try calling out with. Make your batch Apex stateful and allow callouts, like this:

global class YourBatchClass implements Database.Batchable<sObject>, Database.Stateful, Database.AllowsCallouts

Then in your finish method you can determine if your callout succeeded based on a saved value in one of your member variables, like response.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .