function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
VRKVRK 

System.calloutException:IO Exception:ReadTimeout

Hi i am performing picklist Update thorugh Metadata API...
it works for less data , But when we perform bulk data through Data
loader getting below error :
System.calloutException:IO Exception:ReadTimeout
i set Max 120 sec..But issue not solved for Bulk upload data.
Any ideas how to resolve
public class  MetadataApiCallout {
    //-------create new picklist value using metadata api call--------
    //-------use below method for bulk insert&Deactivate Values.    
    @future(callout = true)
    public static void createPicklistValue(String serializedObjectAPIMap, String serializedMap) {
        Map < String, Map < String, String >> ObjectFieldApiMap = (Map < String, Map < String, String >> ) JSON.deserialize(serializedObjectAPIMap, Map < String, Map < String, String >> .class);
        Map < String, Map < String, String >> picklistValueMap = (Map < String, Map < String, String >> ) JSON.deserialize(serializedMap, Map < String, Map < String, String >> .class); //----adding new values coming from compass helper.....        
        MetadataService.MetadataPort service = createService(); //-----Calling service method...        
        Map < String, String > schemaValueMap = new Map < String, String > ();
        //Collect recordtypes for each object in required format
        Map<String, List<String>> ObjectRtMap = new Map<String, List<String>>();
        List<String> rtValueList = new List<String>();
        for(RecordType rt : [SELECT Id, Name, developerName, SobjectType FROM RecordType WHERE SobjectType =:ObjectFieldApiMap.keySet()]){
            rtValueList.add(rt.SobjectType + '.' + rt.developerName);
            if(ObjectRtMap.containsKey(String.valueOf(rt.SobjectType).toUpperCase())){
                List<String> rtValues = new List<String>();
                rtValues = ObjectRtMap.get(String.valueOf(rt.SobjectType).toUpperCase());
                rtValues.add(String.valueOf(rt.SobjectType + '.' + rt.developerName).toUpperCase());
                ObjectRtMap.put(String.valueOf(rt.SobjectType).toUpperCase(), rtValues);
            }
            else{
                List<String> rtValues = new List<String>();
                rtValues.add(String.valueOf(rt.SobjectType + '.' + rt.developerName).toUpperCase());
                ObjectRtMap.put(String.valueOf(rt.SobjectType).toUpperCase(), rtValues); 
            }        
        }
        
        Map<String, List<MetadataService.PickListValue>> objFldMetaPickListValueMap = new Map<String, List<MetadataService.PickListValue>>();

        List<MetadataService.CustomField> customFieldListToUpdate = new List<MetadataService.CustomField>();        
        for (String objectApiName: ObjectFieldApiMap.keySet()) {            
            for (String fieldAPi: ObjectFieldApiMap.get(objectApiName).keySet()) {
                SobjectType objType = Schema.getGlobalDescribe().get(objectApiName);
                Map < String, Schema.SObjectField > objFields = objType.getDescribe().fields.getMap();
                SObjectField fieldName = objFields.get(fieldAPi);
                Schema.DescribeFieldResult fieldResult = fieldName.getDescribe();
                fieldResult = fieldResult.getSObjectField().getDescribe();
                List < Schema.PicklistEntry > ple = fieldResult.getPicklistValues();
                for (Schema.PicklistEntry pl: ple) {
                    if (pl.isActive()) {
                        schemaValueMap.put(pl.getValue(), pl.getLabel());
                    }
                }               
                MetadataService.CustomField customField = new MetadataService.CustomField();
                customField.fullName = objectApiName + '.' + fieldAPi;
                customField.label = ObjectFieldApiMap.get(objectApiName).get(fieldAPi);
                customField.type_x = 'Picklist';
                MetadataService.ValueSet picklistValueSet = new MetadataService.ValueSet();
                MetadataService.ValueSetValuesDefinition valueDefinition = new MetadataService.ValueSetValuesDefinition();
                List < MetadataService.CustomValue > values = new List < MetadataService.CustomValue > ();
                List<MetadataService.PickListValue>  fldPickListValueList =  new List<MetadataService.PickListValue>();
                //Add Existing values back in
                //condition for adding new values 
                //---for loop for adding new values from list-----------                
                for (String picklistValueInsert: picklistValueMap.get(fieldAPi).keySet()) {                    
                    MetadataService.CustomValue existingPLValue = new MetadataService.CustomValue();
                    existingPLValue.fullName = picklistValueInsert;
                    existingPLValue.default_x = false;
                    existingPLValue.label = picklistValueMap.get(fieldAPi).get(picklistValueInsert);
                    values.add(existingPLValue);

                    MetadataService.PickListValue fldPickListValue = new MetadataService.PickListValue();
                    fldPickListValue.fullName = picklistValueInsert;
                    fldPickListValue.default_x = false;
                    fldPickListValueList.add(fldPickListValue); 
                    System.debug(picklistValueInsert);
                }
                objFldMetaPickListValueMap.put(objectApiName+'.'+fieldAPi, fldPickListValueList);                    

                //------for loop for value deactivation.------------
                for (String picklistValue: schemaValueMap.keySet()) {
                    if (!picklistValueMap.get(fieldAPi).containsKey(picklistValue)) { //---condition check. not adding those existing value which is not coming from helper code. 
                        MetadataService.CustomValue existingPLValue = new MetadataService.CustomValue();
                        existingPLValue.fullName = picklistValue;
                        existingPLValue.isActive = False;
                        existingPLValue.default_x = false;
                        existingPLValue.label = schemaValueMap.get(picklistValue);
                        values.add(existingPLValue);
                    }
                }
                valueDefinition.value = values;
                valueDefinition.sorted = false;
                picklistValueSet.valueSetDefinition = valueDefinition;
                customField.valueSet = picklistValueSet;
                schemaValueMap.clear();
                
                  customFieldListToUpdate.add(customField);              
            }
        }
        //Update PicklistFields with new values        
        updateMetadata(service, splitMetadataIntoLists((MetadataService.Metadata[]) customFieldListToUpdate));
        
        List<List<String>> combinedRtValueList = new List<List<String>>();
        //Splitting into size of 10 to avoid limit
        combinedRtValueList = splitListIntoLists(rtValueList);
        List<MetadataService.RecordType> rtMetaList = new List<MetadataService.RecordType>();        
        for(Integer i=0; i<combinedRtValueList.size(); i++){
            if(!Test.isRunningTest())
                //read recordtype
                rtMetaList.addAll((List<MetadataService.RecordType>) service.readMetadata('RecordType', combinedRtValueList[i]).getRecords());            
        }
        Map<String, MetadataService.RecordType> rtMetaRTMap = new Map<String, MetadataService.RecordType>();        
        for(MetadataService.RecordType mRT : rtMetaList){            
            rtMetaRTMap.put(String.valueOf(mRT.fullName).toUpperCase(), mRT);            
        }
        List<MetadataService.RecordType> recordTypeListToUpdate = new List<MetadataService.RecordType>();
        for (String objectApiName: ObjectFieldApiMap.keySet()) {
            for(String rt : ObjectRtMap.get(objectApiName.toUpperCase())){
                MetadataService.RecordType recordType = new MetadataService.RecordType();
                recordType = rtMetaRTMap.get(rt);
                for (String fieldAPi: ObjectFieldApiMap.get(objectApiName).keySet()) { 
                   
                       // initialize the list of record type picklist values
                       MetadataService.RecordTypePicklistValue[] rtPickValues = new MetadataService.RecordTypePicklistValue[]{};
                       MetadataService.RecordTypePicklistValue rtPickValue = new MetadataService.RecordTypePicklistValue();
                       // Create the recordtypepicklist and add the list of picklist fields to the record type
                       rtPickValue.picklist = fieldAPi;
                       rtPickValue.values = objFldMetaPickListValueMap.get(objectApiName+'.'+fieldAPi);
                       System.debug(rtPickValue.values);
                       rtPickValues.add(rtPickValue);
                       if(!Test.isRunningTest())
                           recordType.picklistValues.addAll(rtPickValues);
                                            
                }              
                
        System.debug(recordType.picklistValues.size());
                recordTypeListToUpdate.add(recordType);
            } 
        }
        //Update RecordTypes             
        updateMetadata(service, splitMetadataIntoLists((MetadataService.Metadata[]) recordTypeListToUpdate));        
                         
    }
   
    //-----------create Metadata service----------------
    public static MetadataService.MetadataPort createService() {
        MetadataService.MetadataPort service = new MetadataService.MetadataPort();
        service.SessionHeader = new MetadataService.SessionHeader_element();
        service.SessionHeader.sessionId = UserInfo.getSessionId();
       // service.timeout_x = 40000;
        service.timeout_x = 120000;
        return service;
    }
    
    //readMetadata and updateMetdata has a limit of 10 elements per one callout
    //Spliting Metadata into lists of 10 elements to address above limit
    //-----------Split Master List into small lists of size 10 each----------------
    public static List<List<MetadataService.Metadata>> splitMetadataIntoLists(List<MetadataService.Metadata> listToSplit) {
        List<List<MetadataService.Metadata>> metadataListOfLists = new List<List<MetadataService.Metadata>>();        
        for(Integer i = 0 ; i < (listToSplit.size() / 10)+1 ; i++){
            List<MetadataService.Metadata> lstTemp = new List<MetadataService.Metadata>();
            for(Integer j=(i*10);(j<(i*10)+10) && j<listToSplit.size() ; j++){
                lstTemp.add(listToSplit.get(j));
            }
            metadataListOfLists.add(lstTemp);
        }        
        return metadataListOfLists;
    } 

    //-----------Split Master List into small lists of size 10 each----------------
    public static List<List<String>> splitListIntoLists(List<String> listToSplit) {
        List<List<String>> ListOfLists = new List<List<String>>();        
        for(Integer i = 0 ; i < (listToSplit.size() / 10)+1 ; i++){
            List<String> lstTemp = new List<String>();
            for(Integer j=(i*10);(j<(i*10)+10) && j<listToSplit.size() ; j++){
                lstTemp.add(listToSplit.get(j));
            }
            ListOfLists.add(lstTemp);
        }        
        return ListOfLists;
    }
    
    //-----------Update Metadata----------------
    public static void updateMetadata(MetadataService.MetadataPort service, List<List<MetadataService.Metadata>> metadataToUpdate) {
        for(Integer i=0; i<metadataToUpdate.size(); i++){
            if(!Test.isRunningTest()) {
                List<MetadataService.SaveResult> results = service.updateMetadata(metadataToUpdate[i]);  
                for(MetadataService.SaveResult r : results){
                    system.debug(r.errors);
                }
            }
        }
    }    
}
AbhishekAbhishek (Salesforce Developers) 
Hi,

Can you check the below blogs might answer your query

https://developer.salesforce.com/forums/?id=906F00000008riNIAQ

https://salesforce.stackexchange.com/questions/69639/webservice-callout-exception-io-exception-read-timed-out

Thanks.
VRKVRK
thanks Abhishek for your replay...
I verify provided links, But not help for fix this issues
Thanks