def run_batch_operation(instances)
      instances.map do |instance|
        begin
          attempt = 0
          result = nil
          while attempt < @max_attempts
            # sleep idempotently except for the first attempt
            sleep(INITIAL_RETRY_SEC * 2 ** attempt) if attempt != 0
            result = yield(instance)
            break if result.nil? # nil indicates success
            attempt += 1
          end
          result # result for this instance is nil or returned exception
        rescue => e
          e # result for this instance is caught exception
        end
      end
    end
def run_batch_operation(instances)
      instances.map do |instance|
        begin
          attempt = 0
          result = nil
          while attempt < @max_attempts
            # sleep idempotently except for the first attempt
            sleep(INITIAL_RETRY_SEC * 2 ** attempt) if attempt != 0
            result = yield(instance)
            break if result.nil? # nil indicates success
            attempt += 1
          end
          result # result for this instance is nil or returned exception
        rescue => e
          e # result for this instance is caught exception
        end
      end
    end
Return a Hash of instance => error. Empty hash indicates "no error"
 for code block:
   - if block returns nil, success
   - if block returns non-nil value (e.g., exception), retry 3 times w/ backoff
   - if block raises exception, fail