/// <summary> /// Waits while the batch job is pending. /// </summary> /// <param name="batchJobService">The batch job service.</param> /// <param name="batchJob">The batch job.</param> /// <param name="isPending">True, if the job status is pending, false /// otherwise.</param> /// <param name="pollAttempts">The poll attempts to make while waiting for /// batchjob completion or cancellation.</param> private BatchJob WaitWhileJobIsPending(BatchJobService batchJobService, BatchJob batchJob, out bool isPending, out long pollAttempts) { pollAttempts = 0; isPending = true; do { int sleepMillis = (int)Math.Pow(2, pollAttempts) * POLL_INTERVAL_SECONDS_BASE * 1000; Console.WriteLine("Sleeping {0} millis...", sleepMillis); Thread.Sleep(sleepMillis); Selector selector = new Selector() { fields = new string[] { BatchJob.Fields.Id, BatchJob.Fields.Status, BatchJob.Fields.DownloadUrl, BatchJob.Fields.ProcessingErrors, BatchJob.Fields.ProgressStats }, predicates = new Predicate[] { Predicate.Equals(BatchJob.Fields.Id, batchJob.id) } }; batchJob = batchJobService.get(selector).entries[0]; Console.WriteLine("Batch job ID {0} has status '{1}'.", batchJob.id, batchJob.status); isPending = PENDING_STATUSES.Contains(batchJob.status); } while (isPending && ++pollAttempts <= MAX_RETRIES); return(batchJob); }
/// <summary> /// Wait for the job to complete. /// </summary> /// <param name="batchJobId">ID of the job to wait for completion.</param> /// <param name="numMilliSecondsToWait">The number of milliseconds to wait for job /// completion.</param> /// <param name="callback">The callback to be called whenever the method polls the /// server for job status.</param> /// <returns><c>false</c>, if the job is still pending, true otherwise.</returns> public bool WaitForPendingJob(long batchJobId, int numMilliSecondsToWait, WaitCallback callback) { BatchJobService batchJobService = (BatchJobService)User.GetService(AdWordsService.v201802.BatchJobService); long totalMillisecondsWaited = 0; long pollAttempts = 0; bool cancelWait = false; bool isPending = true; do { int sleepMillis = (int)Math.Pow(2, pollAttempts) * POLL_INTERVAL_SECONDS_BASE * 1000; if (totalMillisecondsWaited + sleepMillis > numMilliSecondsToWait) { sleepMillis = (int)(numMilliSecondsToWait - totalMillisecondsWaited); } Thread.Sleep(sleepMillis); totalMillisecondsWaited += sleepMillis; pollAttempts++; Selector selector = new Selector() { fields = new string[] { ApiBatchJob.Fields.Id, ApiBatchJob.Fields.Status, ApiBatchJob.Fields.DownloadUrl, ApiBatchJob.Fields.ProcessingErrors, ApiBatchJob.Fields.ProgressStats }, predicates = new Predicate[] { Predicate.Equals(ApiBatchJob.Fields.Id, batchJobId) } }; ApiBatchJob batchJob = batchJobService.get(selector).entries[0]; isPending = PENDING_STATUSES.Contains(batchJob.status); if (callback != null) { cancelWait = callback(batchJob, totalMillisecondsWaited); } } while (isPending && totalMillisecondsWaited < numMilliSecondsToWait && !cancelWait); return(!isPending); }
/// <summary> /// Runs the code example. /// </summary> /// <param name="user">The AdWords user.</param> public void Run(AdWordsUser user) { // Get the BatchJobService. BatchJobService batchJobService = (BatchJobService)user.GetService( AdWordsService.v201509.BatchJobService); try { // Create a BatchJob. BatchJobOperation addOp = new BatchJobOperation() { @operator = Operator.ADD, operand = new BatchJob() }; BatchJob batchJob = batchJobService.mutate(new BatchJobOperation[] { addOp }).value[0]; // Get the upload URL from the new job. string uploadUrl = batchJob.uploadUrl.url; Console.WriteLine("Created BatchJob with ID {0}, status '{1}' and upload URL {2}.", batchJob.id, batchJob.status, batchJob.uploadUrl.url); // Create the mutate request that will be sent to the upload URL. List <Operation> operations = new List <Operation>(); // Create and add an operation to create a new budget. BudgetOperation budgetOperation = BuildBudgetOperation(); operations.Add(budgetOperation); // Create and add operations to create new campaigns. List <CampaignOperation> campaignOperations = BuildCampaignOperations(budgetOperation.operand.budgetId); operations.AddRange(campaignOperations); // Create and add operations to create new ad groups. List <AdGroupOperation> adGroupOperations = new List <AdGroupOperation>(); foreach (CampaignOperation campaignOperation in campaignOperations) { adGroupOperations.AddRange(BuildAdGroupOperations(campaignOperation.operand.id)); } operations.AddRange(adGroupOperations); // Create and add operations to create new ad group criteria (keywords). foreach (AdGroupOperation adGroupOperation in adGroupOperations) { operations.AddRange(BuildAdGroupAdOperations(adGroupOperation.operand.id)); } // Create and add operations to create new ad group ads (text ads). foreach (AdGroupOperation adGroupOperation in adGroupOperations) { operations.AddRange(BuildAdGroupCriterionOperations(adGroupOperation.operand.id)); } BatchJobUtilities batchJobUploadHelper = new BatchJobUtilities(user); // Use the BatchJobUploadHelper to upload all operations. batchJobUploadHelper.Upload(uploadUrl, operations.ToArray()); long pollAttempts = 0; bool isPending = true; do { int sleepMillis = (int)Math.Pow(2, pollAttempts) * POLL_INTERVAL_SECONDS_BASE * 1000; Console.WriteLine("Sleeping {0} millis...", sleepMillis); Thread.Sleep(sleepMillis); Selector selector = new Selector() { fields = new string[] { BatchJob.Fields.Id, BatchJob.Fields.Status, BatchJob.Fields.DownloadUrl, BatchJob.Fields.ProcessingErrors, BatchJob.Fields.ProgressStats }, predicates = new Predicate[] { Predicate.Equals(BatchJob.Fields.Id, batchJob.id) } }; batchJob = batchJobService.get(selector).entries[0]; Console.WriteLine("Batch job ID {0} has status '{1}'.", batchJob.id, batchJob.status); isPending = PENDING_STATUSES.Contains(batchJob.status); } while (isPending && ++pollAttempts <= MAX_RETRIES); if (isPending) { throw new TimeoutException("Job is still in pending state after polling " + MAX_RETRIES + " times."); } if (batchJob.processingErrors != null) { foreach (BatchJobProcessingError processingError in batchJob.processingErrors) { Console.WriteLine(" Processing error: {0}, {1}, {2}, {3}, {4}", processingError.ApiErrorType, processingError.trigger, processingError.errorString, processingError.fieldPath, processingError.reason); } } if (batchJob.downloadUrl != null && batchJob.downloadUrl.url != null) { BatchJobMutateResponse mutateResponse = batchJobUploadHelper.Download( batchJob.downloadUrl.url); Console.WriteLine("Downloaded results from {0}.", batchJob.downloadUrl.url); foreach (MutateResult mutateResult in mutateResponse.rval) { String outcome = mutateResult.errorList == null ? "SUCCESS" : "FAILURE"; Console.WriteLine(" Operation [{0}] - {1}", mutateResult.index, outcome); } } } catch (Exception e) { throw new System.ApplicationException("Failed to add campaigns using batch job.", e); } }