4

I was reading the topic of using iterator and iterabel Interface - https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_iterable.htm

It says :

If you do not want to use a custom iterator with a list, but instead want to create your own data structure, you can use the Iterable interface to generate the data structure.

The am trying to understand how the below code works with the Batch Class. ( Example given at link - https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_iterable.htm )

The Batch Class:

global class batchClass implements Database.batchable<Account>{ 
   global Iterable<Account> start(Database.batchableContext info){ 
       return new foo(); 
   }     
   global void execute(Database.batchableContext info, List<Account> scope){ 
       List<Account> accsToUpdate = new List<Account>(); 
       for(Account a : scope){ 
           a.Atextfield__c = 'Abc'; 
           accsToUpdate.add(a); 
       } 
       update accsToUpdate; 
   }     
   global void finish(Database.batchableContext info){     
   } 
}

The Foo Class which implements Iterable:

global class foo implements iterable<Account>{
   global Iterator<Account> Iterator(){
      return new CustomIterable();
   }
}

Finally the class that implements Iterator:

global class CustomIterable 
   implements Iterator<Account>{ 

   List<Account> accs {get; set;} 
   Integer i {get; set;} 

   public CustomIterable(){ 
       accs = 
       [SELECT Id, Name, 
       NumberOfEmployees 
       FROM Account 
       WHERE Name Like 'A%']; 
       i = 0; 
   }   

   global boolean hasNext(){ 
       if(i >= accs.size()) {
           return false; 
       } else {
           return true; 
       }
   }    

   global Account next(){ 
       // 8 is an arbitrary 
       // constant in this example
       // that represents the 
       // maximum size of the list.
       if(i == 8){return null;} 
       i++; 
       return accs[i-1]; 
   } 
}

Questions:

  1. In Foo Class we are returning only an object of type return new CustomIterable(); , where does the hasNext() and Next() when returning just a new object of type CustomIterable.

  2. How does the scope gets all the list of Account? From what I understand the Start() method return new foo(); which in turn return new CustomIterable();. Instantiation an object of CustomIterable Class only invokes it's constructor. How does the scope gets assigned a List of Accounts here?

4

The overall answer to this is that there is an Apex Batch Handler which controls batch class execution. You could think of it like a method that calls your start method, then launches threads which call your execute method and handles the result of those threads, and finally calls your finish method once all execute threads have completed. With this in mind:

  1. The handler mentioned may be implemented something like:

    Batchable<Account> myBatch = batchFromBatchExecuteCall;
    Iterator<Account> queryResult = myBatch.start().iterator();
    while(queryResult.hasNext())
    {
        List<Account> scope = new List<Account>{queryResult.next()};
        for(integer i = 1; i < scopeSize && queryResult.hasNext(); ++i)
        {
            scope.add(queryResult.next());
        }
        launchThread(myBatch.execute, scope);
    }
    

    Of course, the above is very simplified to what the handler likely actually has to do, but this should demonstrate how it can take an iterator and use it to execute scopes

  2. Both List and queryLocator already implement the iterable() interface, so the caller can just use the iterable method whether it gets back one of those types or a custom Iterable type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.