Friday, July 28, 2017

What is Synchronous and Asynchronous in Salesforce.



Apex can be executed synchronously or asynchronously.

Synchronous:


In a Synchronous call, the thread will wait until it completes its tasks before proceeding to next. In a Synchronous call, the code runs in single thread.

Example:

Trigger
Controller Extension
Custom Controller


Asynchronous:

An asynchronous process can execute a task "in the background" without the user having to wait for the task to finish. Force.com features such as asynchronous Apex, Bulk API, and Reports and Dashboards use asynchronous processing to efficiently process requests.

In a Asynchronous call, the thread will not wait until it completes its tasks before proceeding to next. Instead it proceeds to next leaving it run in separate thread. In a Asynchronous call, the code runs in multiple threads which helps to do many tasks as background jobs.

Example:

Batch
@future Annotation

Tuesday, July 25, 2017

Call webservice class from batch apex:

global class IBPortal_Manual_MT4Linker{

  WebService  static void Link_IBPortalMT4(Id ids) {
  Account ac;
   ac = [select IBPortalID__c,SF_LeadID__c  from Account where id=:ids];
   for (ADSS_Platform_Account__c ld: [select id, Name, Account__c,IB_ID__c,Instance__c from ADSS_Platform_Account__c where Account__c=:ids])
    {

       System.debug('--> IBPortal Manual MT4Linker');
         IBPortal_LinkMT4Account.Link_MT4AccountPort stub= new  IBPortal_LinkMT4Account.Link_MT4AccountPort();
        String output = stub.Link_Account(String.valueof(ac.IBPortalID__c),ld.Name,ac.id,ld.Instance__c,ld.IB_ID__c);
               System.debug('--> AccountUpdater'+output);
        }
  }
  }
  global class linkltoMT4batch implements Database.Batchable<sObject>,Database.AllowsCallouts{
    global set<id> accids;    
    global linkltoMT4batch(){
               // Batch Constructor
    }
    // Start Method
    global Database.QueryLocator start(Database.BatchableContext BC){
     return Database.getQueryLocator([select id from Account]);
    }
  // Execute Logic
   global void execute(Database.BatchableContext BC, List<sObject>scope){
          // Logic to be Executed batch wise   
          List<Account> acclist = (List<Account>)scope;
          for(account a :acclist){
              IBPortal_Manual_MT4Linker.Link_IBPortalMT4(a.id);
          }
   }
   global void finish(Database.BatchableContext BC){
        // Logic to be Executed at finish
   }
}  

Invoke an apex class from Batch class

 global void execute(Database.BatchableContext BC, List<sObject> scope)
{
    // if public/global and not static
    YourOtherClass instance = new YourOtherClass();
    instance.myMethod((List <Case>)scope);

    // if static
    // YourOtherClass.myMethod((List <Case>)scope);
}
And your other class' method should look like this:
 public static void(List <Case> cases)
{
    // do something with the cases
}
-----------
Batch Apex cannot be invoked from a @future method.
You can run a frequently scheduled Apex Class (say every 5-10 mins) that scans a table to check whether it should run.
When your data import finishes, you can set this data, which then indicates to the Batch Job (the next time it runs) that the data is available and it executes.
If the flag is not set, the start method does not populate a QueryLocator, and therefore no processing would occur in the Execute method.
The other alternative is to have a webservice method which can invoke batch apex. This will however need to be externally invoked and is probably more relevant to a data push rather than pull.