مراحل استفاده از پردازش دستهای به شرح زیر است:
ایجاد کار دستهای جدید
برای ایجاد منبع BatchJob،
MutateBatchJob را فراخوانی کنید. وقتی شیء
BatchJob را میسازید، میتوانید بهطور اختیاری
metadata.execution_limit_seconds را روی یک عدد صحیح مثبت تنظیم کنید تا
یک حد بالای تقریبی، برحسب ثانیه، برای مدت زمانی که کار میتواند اجرا شود
قبلاز لغو خودکار پیکربندی کنید (به
راهنمای استفاده اضافی مراجعه کنید).
جاوا
private String createBatchJob(BatchJobServiceClient batchJobServiceClient, long customerId) { BatchJobOperation operation = BatchJobOperation.newBuilder().setCreate(BatchJob.newBuilder().build()).build(); String batchJobResourceName = batchJobServiceClient .mutateBatchJob(Long.toString(customerId), operation) .getResult() .getResourceName(); System.out.printf("Created a mutate job with resource name: '%s'.%n", batchJobResourceName); return batchJobResourceName; }
C#
private static string CreateBatchJob(BatchJobServiceClient batchJobService, long customerId) { BatchJobOperation operation = new BatchJobOperation() { Create = new BatchJob() { } }; string batchJobResourceName = batchJobService.MutateBatchJob(customerId.ToString(), operation) .Result.ResourceName; Console.WriteLine($"Created a batch job with resource name: " + $"'{batchJobResourceName}'."); return batchJobResourceName; }
PHP
private static function createBatchJob( BatchJobServiceClient $batchJobServiceClient, int $customerId ): string { // Creates a batch job operation to create a new batch job. $batchJobOperation = new BatchJobOperation(); $batchJobOperation->setCreate(new BatchJob()); // Issues a request to the API and get the batch job's resource name. $batchJobResourceName = $batchJobServiceClient->mutateBatchJob( MutateBatchJobRequest::build($customerId, $batchJobOperation) )->getResult()->getResourceName(); printf( "Created a batch job with resource name: '%s'.%s", $batchJobResourceName, PHP_EOL ); return $batchJobResourceName; }
Python
def create_batch_job( batch_job_service: BatchJobServiceClient, customer_id: str, batch_job_operation: BatchJobOperation, ) -> str: """Creates a batch job for the specified customer ID. Args: batch_job_service: an instance of the BatchJobService message class. customer_id: a str of a customer ID. batch_job_operation: a BatchJobOperation instance set to "create" Returns: a str of a resource name for a batch job. """ try: response: MutateBatchJobResponse = batch_job_service.mutate_batch_job( customer_id=customer_id, operation=batch_job_operation ) resource_name: str = response.result.resource_name print(f'Created a batch job with resource name "{resource_name}"') return resource_name except GoogleAdsException as exception: handle_googleads_exception(exception) # This line will likely not be reached due to sys.exit(1) in handle_googleads_exception # but to satisfy the type checker, we add a return statement. return "" # Or raise an exception
Ruby
def create_batch_job(client, batch_job_service, customer_id) # Creates a batch job operation to create a new batch job. operation = client.operation.create_resource.batch_job # Issues a request to the API and get the batch job's resource name. response = batch_job_service.mutate_batch_job( customer_id: customer_id, operation: operation ) batch_job_resource_name = response.result.resource_name puts "Created a batch job with resource name: '#{batch_job_resource_name}'" batch_job_resource_name end
پرل
sub create_batch_job { my ($batch_job_service, $customer_id) = @_; # Create a batch job operation. my $batch_job_operation = Google::Ads::GoogleAds::V26::Services::BatchJobService::BatchJobOperation-> new({create => Google::Ads::GoogleAds::V26::Resources::BatchJob->new({})}); my $batch_job_resource_name = $batch_job_service->mutate({ customerId => $customer_id, operation => $batch_job_operation })->{result}{resourceName}; printf "Created a batch job with resource name: '%s'.\n", $batch_job_resource_name; return $batch_job_resource_name; }
curl
# Creates a batch job. # # Variables: # API_VERSION, # CUSTOMER_ID, # MANAGER_CUSTOMER_ID, # OAUTH2_ACCESS_TOKEN: # See https://developers.google.com/google-ads/api/rest/auth#request_headers # for details. curl -f --request POST \ "https://googleads.googleapis.com/v${API_VERSION}/customers/${CUSTOMER_ID}/batchJobs:mutate" \ --header "Content-Type: application/json" \ --header "login-customer-id: ${MANAGER_CUSTOMER_ID}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --data @- <<EOF { "operation": { "create": {} } } EOF
در این مرحله از فرایند، status کار
PENDING است.
افزودن عملیات جهش به کار دستهای
با فراخوانی AddBatchJobOperations، یک یا چند شیء MutateOperation را به کار دستهای ایجادشده در مرحله قبل اضافه کنید. سپس
پاسخ حاوی موارد زیر است:
total_operations: تعداد کل عملیات اضافهشده تاکنون برای این کار.next_sequence_token: توکن توالی برای ارسال در فیلدsequence_tokenوقتی که این روش را دوباره برای افزودن عملیات بیشتر فراخوانی میکنید.
اولین درخواست AddBatchJobOperations برای کار دستهای باید sequence_token را حذف کند. وقتی دوباره
AddBatchJobOperations را برای افزودن عملیاتهای بیشتر فراخوانی میکنید،
توکن توالی قبلاً دریافتشده را در فیلد
sequence_token
درخواست مشخص کنید. فراخوانی روش با فهرست خالی
mutate_operations خطای
BatchJobError.EMPTY_OPERATIONS را برمیگرداند، فراخوانی آن با هر
نشان توالی دیگری غیراز نشان توالی قبلی خطای
BatchJobError.INVALID_SEQUENCE_TOKEN را برمیگرداند، و
تلاش برای افزودن عملیات پساز شروع اجرای کار خطای
BatchJobError.CANNOT_MODIFY_JOB_AFTER_JOB_STARTS_RUNNING
را برمیگرداند.
درحالیکه status کار دستهای
PENDING است، sequence_token نیز بهعنوان
next_add_sequence_token در منبع
BatchJob دردسترس است که میتوانید بعداً آن را بازیابی
کنید.
اگر درحال ایجاد اشیای وابسته هستید، مثلاً یک پویش کامل که شامل یک پویش جدید و گروههای آگهی، آگهیها، و کلیدواژههای مربوطه است، میتوانید از شناسههای موقت برای مشخص کردن نام منبع استفاده کنید.
جاوا
private void addAllBatchJobOperations( BatchJobServiceClient batchJobServiceClient, long customerId, String batchJobResourceName) { AddBatchJobOperationsResponse response = batchJobServiceClient.addBatchJobOperations( AddBatchJobOperationsRequest.newBuilder() .setResourceName(batchJobResourceName) .addAllMutateOperations(buildAllOperations(customerId)) .build()); System.out.printf( "%d mutate operations have been added so far.%n", response.getTotalOperations()); // You can use this next sequence token for calling addBatchJobOperations() next time. System.out.printf( "Next sequence token for adding next operations is '%s'.%n", response.getNextSequenceToken()); }
C#
private static void AddAllBatchJobOperations(BatchJobServiceClient batchJobService, long customerId, string batchJobResourceName) { AddBatchJobOperationsResponse response = batchJobService.AddBatchJobOperations( new AddBatchJobOperationsRequest() { ResourceName = batchJobResourceName, MutateOperations = { BuildAllOperations(customerId) } }); Console.WriteLine($"{response.TotalOperations} mutate operations have been added" + $" so far."); // You can use this next sequence token for calling AddBatchJobOperations() next time. Console.WriteLine($"Next sequence token for adding next operations is " + $"'{response.NextSequenceToken}'."); }
PHP
private static function addAllBatchJobOperations( BatchJobServiceClient $batchJobServiceClient, int $customerId, string $batchJobResourceName ): void { $response = $batchJobServiceClient->addBatchJobOperations( AddBatchJobOperationsRequest::build( $batchJobResourceName, '', self::buildAllOperations($customerId) ) ); printf( "%d mutate operations have been added so far.%s", $response->getTotalOperations(), PHP_EOL ); // You can use this next sequence token for calling addBatchJobOperations() next time. printf( "Next sequence token for adding next operations is '%s'.%s", $response->getNextSequenceToken(), PHP_EOL ); }
Python
def add_all_batch_job_operations( batch_job_service: BatchJobServiceClient, operations: List[MutateOperation], resource_name: str, ) -> None: """Adds all mutate operations to the batch job. As this is the first time for this batch job, we pass null as a sequence token. The response will contain the next sequence token that we can use to upload more operations in the future. Args: batch_job_service: an instance of the BatchJobService message class. operations: a list of a mutate operations. resource_name: a str of a resource name for a batch job. """ try: response: AddBatchJobOperationsResponse = ( batch_job_service.add_batch_job_operations( resource_name=resource_name, sequence_token=None, # type: ignore mutate_operations=operations, ) ) print( f"{response.total_operations} mutate operations have been " "added so far." ) # You can use this next sequence token for calling # add_batch_job_operations() next time. print( "Next sequence token for adding next operations is " f"{response.next_sequence_token}" ) except GoogleAdsException as exception: handle_googleads_exception(exception)
Ruby
def add_all_batch_job_operations( client, batch_job_service, customer_id, batch_job_resource_name) response = batch_job_service.add_batch_job_operations( resource_name: batch_job_resource_name, mutate_operations: build_all_operations(client, customer_id), ) puts "#{response.total_operations} mutate operations have been added so far." # You can use this next sequence token for calling # add_all_batch_job_operations() next time puts "Next sequence token for adding next operations is " \ "'#{response.next_sequence_token}'" end
پرل
sub add_all_batch_job_operations { my ($batch_job_service, $customer_id, $batch_job_resource_name) = @_; my $add_batch_job_operations_response = $batch_job_service->add_operations({ resourceName => $batch_job_resource_name, sequenceToken => undef, mutateOperations => build_all_operations($customer_id)}); printf "%d batch operations have been added so far.\n", $add_batch_job_operations_response->{totalOperations}; # You can use this next sequence token for calling add_operations() next time. printf "Next sequence token for adding next operations is '%s'.\n", $add_batch_job_operations_response->{nextSequenceToken}; }
curl
# Adds operations to a batch job. # # Variables: # API_VERSION, # CUSTOMER_ID, # MANAGER_CUSTOMER_ID, # OAUTH2_ACCESS_TOKEN: # See https://developers.google.com/google-ads/api/rest/auth#request_headers # for details. # BATCH_JOB_RESOURCE_NAME: # The resource name of the batch job to which the operations should be added # as returned by the previous step. curl -f --request POST \ "https://googleads.googleapis.com/v${API_VERSION}/${BATCH_JOB_RESOURCE_NAME}:addOperations" \ --header "Content-Type: application/json" \ --header "login-customer-id: ${MANAGER_CUSTOMER_ID}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --data @- <<EOF { "mutateOperations": [ { "campaignBudgetOperation": { "create": { "resourceName": "customers/${CUSTOMER_ID}/campaignBudgets/-1", "name": "batch job budget #${RANDOM}", "deliveryMethod": "STANDARD", "amountMicros": 5000000 } } }, { "campaignOperation": { "create": { "advertisingChannelType": "SEARCH", "status": "PAUSED", "name": "batch job campaign #${RANDOM}", "campaignBudget": "customers/${CUSTOMER_ID}/campaignBudgets/-1", "resourceName": "customers/${CUSTOMER_ID}/campaigns/-2", "manualCpc": { } } }, } ] } EOF
برای دیدن محتوای تابع عملیات ساخت در GitHub برای کتابخانه کارخواهتان، کلیک کنید:
جاوا
buildAllOperations()
C#
BuildAllOperations()
PHP
buildAllOperations()
Python
build_all_operations()
Ruby
build_all_operations()
پرل
build_all_operations
اجرای کار دستهای
پساز افزودن همه عملیات، میتوانید از Google Ads API درخواست کنید تا با فراخوانی RunBatchJob در عملیات بارگذاریشده، کار دستهای را اجرا کند.
فراخوانی RunBatchJob پساز شروع اجرای کار، خطای BatchJobError.CANNOT_MODIFY_JOB_AFTER_JOB_STARTS_RUNNING را برمیگرداند.
جاوا
private OperationFuture runBatchJob( BatchJobServiceClient batchJobServiceClient, String batchJobResourceName) { OperationFuture operationResponse = batchJobServiceClient.runBatchJobAsync(batchJobResourceName); // BEWARE! The above call returns an OperationFuture. The execution of that future depends on // the thread pool which is owned by batchJobServiceClient. If you use this future, you *must* // keep the service client in scope too. // See https://developers.google.com/google-ads/api/docs/client-libs/java/lro for more detail. System.out.printf( "Mutate job with resource name '%s' has been executed.%n", batchJobResourceName); return operationResponse; }
C#
private Operation<Empty, BatchJobMetadata> RunBatchJob( BatchJobServiceClient batchJobService, string batchJobResourceName) { Operation<Empty, BatchJobMetadata> operationResponse = batchJobService.RunBatchJob(batchJobResourceName); Console.WriteLine($"Batch job with resource name '{batchJobResourceName}' has been " + $"executed."); return operationResponse; }
PHP
private static function runBatchJob( BatchJobServiceClient $batchJobServiceClient, string $batchJobResourceName ): OperationResponse { $operationResponse = $batchJobServiceClient->runBatchJob(RunBatchJobRequest::build($batchJobResourceName)); printf( "Batch job with resource name '%s' has been executed.%s", $batchJobResourceName, PHP_EOL ); return $operationResponse; }
Python
def run_batch_job( batch_job_service: BatchJobServiceClient, resource_name: str ) -> Operation: """Runs the batch job for executing all uploaded mutate operations. Args: batch_job_service: an instance of the BatchJobService message class. resource_name: a str of a resource name for a batch job. Returns: a google.api_core.operation.Operation instance. """ try: response: Operation = batch_job_service.run_batch_job( resource_name=resource_name ) print( f'Batch job with resource name "{resource_name}" has been ' "executed." ) return response except GoogleAdsException as exception: handle_googleads_exception(exception) # This line will likely not be reached due to sys.exit(1) in handle_googleads_exception # but to satisfy the type checker, we add a return statement. # In a real application, you might want to return a dummy Operation or raise an error. return Operation( op_type_name="type.googleapis.com/google.protobuf.Empty", complete=True, done_callbacks=[], metadata_type=None, result_type=None, ) # type: ignore
Ruby
def run_batch_job(batch_job_service, batch_job_resource_name) operation_response = batch_job_service.run_batch_job( resource_name: batch_job_resource_name, ) puts "Batch job with resource name '#{batch_job_resource_name}' " \ "has been executed." operation_response end
پرل
sub run_batch_job { my ($batch_job_service, $batch_job_resource_name) = @_; my $batch_job_lro = $batch_job_service->run({resourceName => $batch_job_resource_name}); printf "Batch job with resource name '%s' has been executed.\n", $batch_job_resource_name; return $batch_job_lro; }
curl
# Runs a batch job. # # Variables: # API_VERSION, # CUSTOMER_ID, # MANAGER_CUSTOMER_ID, # OAUTH2_ACCESS_TOKEN: # See https://developers.google.com/google-ads/api/rest/auth#request_headers # for details. # BATCH_JOB_RESOURCE_NAME: # The resource name of the batch job to run as returned by the previous step. curl -f --request POST \ "https://googleads.googleapis.com/v${API_VERSION}/${BATCH_JOB_RESOURCE_NAME}:run" \ --header "Content-Type: application/json" \ --header "login-customer-id: ${MANAGER_CUSTOMER_ID}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --data @- <<EOF {} EOF
پاسخ برگرداندهشده یک شیء طولانیمدتOperation است که
حاوی فراداده کار دستهای شما و اطلاعات مربوط به وضعیت کار است.
وضعیت کار دستهای را تا زمانی که انجام شود نظرسنجی کنید
وضعیت کار دستهای را با روش
Operations.GetOperation در سرویس
google.longrunning.Operations (جدا از
BatchJobService) نظرسنجی کنید تا زمانی که
فیلد Operation.done true شود. در Google Ads API،
Operations.GetOperation تنها روش پشتیبانیشده در
google.longrunning.Operations است (WaitOperation،
ListOperations، CancelOperation، و DeleteOperation
UNIMPLEMENTED را برمیگردانند):
- کتابخانههای کارخواه: کمککننده نظرسنجی یا انتظار را در پوشاننده عملیات طولانیمدت که توسط
RunBatchJobبرگردانده شده است فراخوانی کنید (یا نام عملیات را بهOperationService::poll_until_doneدر کتابخانه کارخواه Perl مبتنی بر REST ارسال کنید)، که تا زمانی که عملیات تکمیل شود (یا تا زمانی که زماناتمام نظرسنجی پیکربندیشده منقضی شود؛ در Perl، قبلاز فهرست کردن نتایج، تأیید کنید کهdoneدر درهمسازی برگرداندهشدهtrueاست)Operations.GetOperationرا نظرسنجی میکند. در Java،BatchJobServiceClientرا تا زمانی کهOperationFutureتمام شود باز نگه دارید. - REST: درخواست HTTP
GETرا بهhttps://googleads.googleapis.com/v26/OPERATION_NAME(که در آنOPERATION_NAMEنام منبعOperation.nameاست، با قالبcustomers/CUSTOMER_ID/operations/OPERATION_ID) با عقبنشینی نمایی ارسال کنید تا زمانی که فیلدOperation.donetrueشود.
جاوا
private void pollBatchJob(OperationFuture operationResponse) { try { operationResponse.get(MAX_TOTAL_POLL_INTERVAL_SECONDS, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { System.err.printf("Failed polling the mutate job. Exception: %s%n", e); System.exit(1); } }
C#
private static void PollBatchJob(Operation<Empty, BatchJobMetadata> operationResponse) { PollSettings pollSettings = new PollSettings( Expiration.FromTimeout(TimeSpan.FromSeconds(MAX_TOTAL_POLL_INTERVAL_SECONDS)), TimeSpan.FromSeconds(1)); operationResponse.PollUntilCompleted(pollSettings); }
PHP
private static function pollBatchJob(OperationResponse $operationResponse): void { $operationResponse->pollUntilComplete( [ 'initialPollDelayMillis' => self::POLL_FREQUENCY_SECONDS * 1000, 'totalPollTimeoutMillis' => self::MAX_TOTAL_POLL_INTERVAL_SECONDS * 1000 ] ); }
Python
def poll_batch_job( operations_response: Operation, event: asyncio.Event ) -> None: """Polls the server until the batch job execution finishes. Sets the initial poll delay time and the total time to wait before time-out. Args: operations_response: a google.api_core.operation.Operation instance. event: an instance of asyncio.Event to invoke once the operations have completed, alerting the awaiting calling code that it can proceed. """ loop: asyncio.AbstractEventLoop = asyncio.get_event_loop() def done_callback(future: Coroutine[Any, Any, Any]) -> None: # The operations_response object will call callbacks from a daemon # thread so we must use a threadsafe method of setting the event here # otherwise it will not trigger the awaiting code. loop.call_soon_threadsafe(event.set) # operations_response represents a Long-Running Operation or LRO. The class # provides an interface for polling the API to check when the operation is # complete. Below we use the asynchronous interface, but there's also a # synchronous interface that uses the Operation.result method. # See: https://googleapis.dev/python/google-api-core/latest/operation.html operations_response.add_done_callback(done_callback) # type: ignore
Ruby
def poll_batch_job(operation_response) operation_response.wait_until_done! end
پرل
sub poll_batch_job { my ($operation_service, $batch_job_lro) = @_; $operation_service->poll_until_done({ name => $batch_job_lro->{name}, pollFrequencySeconds => POLL_FREQUENCY_SECONDS, pollTimeoutSeconds => POLL_TIMEOUT_SECONDS }); }
curl
# Gets the status of a batch job. # # Variables: # API_VERSION, # CUSTOMER_ID, # MANAGER_CUSTOMER_ID, # OAUTH2_ACCESS_TOKEN: # See https://developers.google.com/google-ads/api/rest/auth#request_headers # for details. # BATCH_JOB_OPERATION_NAME: # The operation name of the running batch job as returned by the previous # step. curl -f --request GET \ "https://googleads.googleapis.com/v${API_VERSION}/${BATCH_JOB_OPERATION_NAME}" \ --header "Content-Type: application/json" \ --header "login-customer-id: ${MANAGER_CUSTOMER_ID}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \
یا منبع batch_job را با روش
GoogleAdsService.Search یا
GoogleAdsService.SearchStream جستوجو کنید و
batch_job.status و زیرفیلدهای خاص
BatchJobMetadata (مانند
batch_job.metadata.estimated_completion_ratio و
batch_job.metadata.executed_operation_count) را انتخاب کنید تا
batch_job.status به DONE تبدیل شود. هر
Operations.GetOperation یا درخواست GAQL غیرصفحهبندیشده
بهعنوان یک عملیات در سهمیه روزانه میانای برنامهسازی کاربردی شما محسوب میشود؛ وقتی چندین کار دستهای همزمان را نظارت میکنید، یک پُرسمان GAQL (WHERE batch_job.id IN
(...) یا WHERE batch_job.status = 'RUNNING') همه آنها را در یک
درخواست بررسی میکند، بهجای اینکه هر عملیات طولانیمدت را بهصورت جداگانه نظرسنجی کند.
وقتی Operation.done true باشد، عملیات طولانیمدت پاسخ خالی بدون خطاهای هر عملیات برمیگرداند—برای بررسی نتایج عملیات تکی، ListBatchJobResults را فراخوانی کنید.
بازیابی عملیات طولانیمدت موجود
اگر برنامه شما کارهای دستهای را از فرایندی جداگانه نظرسنجی میکند یا لازم است
نظرسنجی را پساز بازراهاندازی ازسر بگیرد، میتوانید نام عملیات طولانیمدت را بااستفاده از
GoogleAdsService.Search یا
GoogleAdsService.SearchStream بازیابی کنید:
منبع
batch_jobرا برای خواندن فیلدlong_running_operationآن پرسمان کنید:SELECT batch_job.id, batch_job.status, batch_job.long_running_operation FROM batch_job WHERE batch_job.id = BATCH_JOB_IDBATCH_JOB_IDرا با شناسه عددی کار دستهای جایگزین کنید.تأیید کنید که
batch_job.statusRUNNINGیاDONEاست (long_running_operationدرحالیکه کارPENDINGاست تنظیم نشده است زیرا هیچ عملیات طولانیمدتی تا زمانی کهRunBatchJobفراخوانی نشود وجود ندارد)، و رشتهlong_running_operationرا از شیءBatchJobبرگرداندهشده بخوانید.بااستفاده از رشته نام آن عملیات، عملیات را نظرسنجی یا بازرسی کنید:
- کتابخانههای کارخواه: کارخواه عملیات را از کارخواه
BatchJobServiceخود دریافت کنید (getOperationsClient()در Java و PHP،RunBatchJobOperationsClientدر C#،transport.operations_clientدر Python،operations_clientدر Ruby، یا$api_client->OperationService()در Perl) تا اصالتسنجی Google Ads و سرصفحههایlogin-customer-idبهطور خودکار پیکربندی شوند، بهجای اینکه یکOperationsClientمستقل را نمونهسازی کنید. برای بررسی یک وضعیت،Operations.GetOperation(یاOperationService::getدر Perl) را فراخوانی کنید، یا از نام عملیات برای ازسر گرفتن پوشاننده عملیات طولانیمدت استفاده کنید و تا زمان تکمیل نظرسنجی کنید (runBatchJobOperationCallable().resumeFutureCallدر Java،PollOnceRunBatchJobدر C#،resumeOperationدر PHP،google.api_core.operation.from_gapicدرOperationبرگرداندهشده توسطget_operationدر Python،wait_until_done!درGapic::Operationبرگرداندهشده توسطget_operationدر Ruby، یاnameدرOperationService::poll_until_doneدر Perl). - REST: درخواست HTTP
GETرا بهhttps://googleads.googleapis.com/v26/OPERATION_NAMEارسال کنید.
چون
OPERATION_NAMEنسخه اصلی میانای برنامهسازی کاربردی را کهBatchJobدر آن ایجاد شده است کدبندی میکند،Operations.GetOperation(حتی ازطریق نقطه پایانی فعالv26REST) با خطایRequestError.UNSUPPORTED_VERSIONمواجه میشود اگر آن نسخه از آن زمان برچیده شده باشد. درعوض، پُرسمانbatch_job.statusرا مستقیماً باGoogleAdsServiceانجام دهید.- کتابخانههای کارخواه: کارخواه عملیات را از کارخواه
آشنایی با فراداده عملیات
وقتی عملیات طولانیمدت را نظرسنجی میکنید یا منبع
batch_job را پرسمان میکنید،
BatchJobMetadata جزئیاتی درباره پیشرفت کار دستهای
ارائه میدهد:
creation_date_time: مُهر زمان ایجاد کار دستهای.start_date_time: مُهر زمان شروع اجرای کار دستهای (وقتیbatch_job.metadata.start_date_timeرا باGoogleAdsServiceپُرسمان میکنید، تکمیل میشود؛ ازOperation.metadataدرRunBatchJobوOperations.GetOperationحذف میشود).completion_date_time: مُهر زمان پایان کار دستهای (فقط درصورتی وجود دارد که کار تمام شده باشد).estimated_completion_ratio: تخمینی از بخشی از کار (از ۰٫۰ تا ۱٫۰) که تکمیل شده است.operation_count: تعداد کل عملیاتها در کار دستهای.executed_operation_count: تعداد عملیاتی که تاکنون اجرا شده است.execution_limit_seconds: حد بالای تقریبی، به ثانیه، برای مدت زمانی که کار دستهای میتواند قبلاز لغو شدن اجرا شود (زمانی کهbatch_job.metadata.execution_limit_secondsرا باGoogleAdsServiceپُر میکنید، اگر حد مثبتی در زمان ایجاد کار تنظیم شده باشد؛ ازOperation.metadataدرRunBatchJobوOperations.GetOperationحذف شده است).
این فیلدها، بهویژه estimated_completion_ratio
و تعداد عملیات، میتوانند به شما کمک کنند پیشرفت کار را بسنجید، زمان باقیمانده را تخمین بزنید، و فرکانس نظرسنجی خود را تنظیم کنید. برای مثال، وقتی estimated_completion_ratio کم است، ممکن است کمتر نظرسنجی کنید و وقتی به ۱٫۰ نزدیک میشود، بیشتر نظرسنجی کنید.
فهرست کردن همه نتایج کار دستهای
وقتی کار دستهای تمام شد،
ListBatchJobResults را فراخوانی کنید تا وضعیت و
پاسخ هر عملیات در کار را بازیابی کنید:
جاوا
private void fetchAndPrintResults( BatchJobServiceClient batchJobServiceClient, String batchJobResourceName) { System.out.printf( "Mutate job with resource name '%s' has finished. Now, printing its results...%n", batchJobResourceName); // Gets all the results from running mutate job and prints their information. ListBatchJobResultsPagedResponse batchJobResults = batchJobServiceClient.listBatchJobResults( ListBatchJobResultsRequest.newBuilder() .setResourceName(batchJobResourceName) .setPageSize(PAGE_SIZE) .build()); for (BatchJobResult batchJobResult : batchJobResults.iterateAll()) { System.out.printf( "Mutate job #%d has a status '%s' and response of type '%s'.%n", batchJobResult.getOperationIndex(), batchJobResult.getStatus().getMessage().isEmpty() ? "N/A" : batchJobResult.getStatus().getMessage(), batchJobResult .getMutateOperationResponse() .getResponseCase() .equals(ResponseCase.RESPONSE_NOT_SET) ? "N/A" : batchJobResult.getMutateOperationResponse().getResponseCase()); } }
C#
private static void FetchAndPrintResults(BatchJobServiceClient batchJobService, string batchJobResourceName) { Console.WriteLine($"batch job with resource name '{batchJobResourceName}' has " + $"finished. Now, printing its results..."); ListBatchJobResultsRequest request = new ListBatchJobResultsRequest() { ResourceName = batchJobResourceName, PageSize = PAGE_SIZE, }; ListBatchJobResultsResponse resp = new ListBatchJobResultsResponse(); // Gets all the results from running batch job and prints their information. foreach (BatchJobResult batchJobResult in batchJobService.ListBatchJobResults(request)) { if (!batchJobResult.IsFailed) { Console.WriteLine($"batch job result #{batchJobResult.OperationIndex} is " + $"successful and response is of type " + $"'{batchJobResult.MutateOperationResponse.ResponseCase}'."); } else { Console.WriteLine($"batch job result #{batchJobResult.OperationIndex} " + $"failed with error message {batchJobResult.Status.Message}."); foreach (GoogleAdsError error in batchJobResult.Failure.Errors) { Console.WriteLine($"Error found: {error}."); } } } }
PHP
private static function fetchAndPrintResults( BatchJobServiceClient $batchJobServiceClient, string $batchJobResourceName ): void { printf( "Batch job with resource name '%s' has finished. Now, printing its results...%s", $batchJobResourceName, PHP_EOL ); // Gets all the results from running batch job and print their information. $batchJobResults = $batchJobServiceClient->listBatchJobResults( ListBatchJobResultsRequest::build($batchJobResourceName)->setPageSize(self::PAGE_SIZE) ); foreach ($batchJobResults->iterateAllElements() as $batchJobResult) { /** * @var BatchJobResult $batchJobResult */ printf( "Batch job #%d has a status '%s' and response of type '%s'.%s", $batchJobResult->getOperationIndex(), $batchJobResult->getStatus() ? $batchJobResult->getStatus()->getMessage() : 'N/A', $batchJobResult->getMutateOperationResponse() ? $batchJobResult->getMutateOperationResponse()->getResponse() : 'N/A', PHP_EOL ); } }
Python
def fetch_and_print_results( client: GoogleAdsClient, batch_job_service: BatchJobServiceClient, resource_name: str, ) -> None: """Prints all the results from running the batch job. Args: client: an initialized GoogleAdsClient instance. batch_job_service: an instance of the BatchJobService message class. resource_name: a str of a resource name for a batch job. """ print( f'Batch job with resource name "{resource_name}" has finished. ' "Now, printing its results..." ) list_results_request: ListBatchJobResultsRequest = client.get_type( "ListBatchJobResultsRequest" ) list_results_request.resource_name = resource_name list_results_request.page_size = 1000 # Gets all the results from running batch job and prints their information. batch_job_results: ListBatchJobResultsResponse = ( batch_job_service.list_batch_job_results(request=list_results_request) ) for batch_job_result in batch_job_results: status: str = batch_job_result.status.message status = status if status else "N/A" result: Any = batch_job_result.mutate_operation_response result = result or "N/A" print( f"Batch job #{batch_job_result.operation_index} " f'has a status "{status}" and response type "{result}"' )
Ruby
def fetch_and_print_results(batch_job_service, batch_job_resource_name) puts "Batch job with resource name '#{batch_job_resource_name}' has " \ "finished. Now, printing its results..." \ # Gets all the results from running batch job and print their information. batch_job_results = batch_job_service.list_batch_job_results( resource_name: batch_job_resource_name, page_size: PAGE_SIZE, ) batch_job_results.each do |result| puts "Batch job ##{result.operation_index} has a status " \ "#{result.status ? result.status.message : 'N/A'} and response of type " \ "#{result.mutate_operation_response ? result.mutate_operation_response.response : 'N/A'}" end end
پرل
sub fetch_and_print_results { my ($batch_job_service, $batch_job_resource_name) = @_; printf "Batch job with resource name '%s' has finished. " . "Now, printing its results...\n", $batch_job_resource_name; # Get all the results from running batch job and print their information. my $list_batch_job_results_response = $batch_job_service->list_results({ resourceName => $batch_job_resource_name, pageSize => PAGE_SIZE }); foreach my $batch_job_result (@{$list_batch_job_results_response->{results}}) { printf "Batch job #%d has a status '%s' and response of type '%s'.\n", $batch_job_result->{operationIndex}, $batch_job_result->{status} ? $batch_job_result->{status}{message} : "N/A", $batch_job_result->{mutateOperationResponse} ? [keys %{$batch_job_result->{mutateOperationResponse}}]->[0] : "N/A"; } }
curl
# Gets the results of a batch job. # # Variables: # API_VERSION, # CUSTOMER_ID, # MANAGER_CUSTOMER_ID, # OAUTH2_ACCESS_TOKEN: # See https://developers.google.com/google-ads/api/rest/auth#request_headers # for details. # BATCH_JOB_RESOURCE_NAME: # The operation name of the running batch job as returned by the previous # step. curl -f --request GET \ "https://googleads.googleapis.com/v${API_VERSION}/${BATCH_JOB_RESOURCE_NAME}:listResults?pageSize=1000" \ --header "Content-Type: application/json" \ --header "login-customer-id: ${MANAGER_CUSTOMER_ID}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}"
در ListBatchJobResultsRequest،
فیلد page_size بهطور پیشفرض روی حداکثر مقدار 1000 تنظیم میشود اگر
حذف شود یا روی 0 تنظیم شود. تنظیم page_size روی مقداری بزرگتر از
1000 یا کوچکتر از 0 خطای
BatchJobError.INVALID_PAGE_SIZE را برمیگرداند.
هر BatchJobResult عملیات مربوطه را بااستفاده از operation_index، نمایه مبتنی بر ۰ MutateOperation بارگذاریشده در کار دستهای، شناسایی میکند.
- عملیات موفقیتآمیز:
mutate_operation_responseپر شده است (responseآن حاویresource_nameمنبع جهشیافته است، بهعلاوه همه فیلدهای قابلتغییر اگرresponse_content_typeرویMUTABLE_RESOURCEتنظیم شده باشد)، وstatusتنظیم نشده است. - عملیات ناموفق (یا اجرا نشده):
mutate_operation_responseتنظیم نشده است، وstatusحاوی جزئیات خطا برای عملیات است.
لغو یا برداشتن کار دستهای
نحوه توقف یا لغو کار دستهای به این بستگی دارد که آیا
RunBatchJob فراخوانی شده است یا نه:
- قبلاز فراخوانی
RunBatchJob: وقتیstatusکارPENDINGاست، میتوانید کار دستهای را با فراخوانیMutateBatchJobباBatchJobOperation.removeرد کنید. فراخوانیremoveپساز شروع اجرای کار، خطایBatchJobError.CAN_ONLY_REMOVE_PENDING_JOBرا برمیگرداند. - پساز فراخوانی
RunBatchJob: نمیتوانید بهصورت دستی یک کار دستهای درحال اجرا را لغو کنید (Operations.CancelOperationدر Google Ads API پیادهسازی نشده است وUNIMPLEMENTEDرا برمیگرداند). برای محدود کردن زمان اجرا بهطوریکه اگر کار بیشازحد طولانی شد بهطور خودکار لغو شود،metadata.execution_limit_secondsرا روی یک عدد صحیح مثبت (یک حد بالای تقریبی) تنظیم کنید وقتی کار را درMutateBatchJobایجاد میکنید. چون عملیات استاندارد در یک کار دستهای با فعال بودن شکست جزئی اجرا میشود (عملیات در زیردستههای اتمی با هم بازگردانده میشوند)، لغو خودکار عملیاتی را که قبلاً تکمیل شدهاند بازنمیگرداند. Once a canceled (or aborted) job'sstatustransitions toDONE, callingListBatchJobResultsreturnsBatchJobResultentries for the executed prefix (operation_index<executed_operation_count) with their individual execution outcomes, followed byBatchJobResultentries for all remaining unexecuted operations (operation_indexfromexecuted_operation_countthroughoperation_count- 1) withmutate_operation_responseunset andstatusset toABORTEDwithInternalError.INTERNAL_ERRORwhen canceled due toexecution_limit_seconds(or to the job-level error status if the job aborted due to a fatal execution error).
مدیریت کردن خطا
BatchJobService عملیات استاندارد را با فعال بودن
شکست جزئی اجرا میکند (عملیات موفقیتآمیز حتی اگر
عملیات دیگر در همان کار ناموفق باشد، بهجز در
زیردستههای اتمی، انجام میشود) و بهطور خودکار
عملیاتی را که بهدلیل خطاهای گذرا ناموفق بودهاند دوباره امتحان میکند. بااینحال، نمیتوان از همه سناریوهای خرابی اجتناب کرد. عملیاتی که بهدلیل خطاهای اعتبارسنجی ناموفق بودهاند را میتوان اصلاح کرد و
در کار دستهای جدیدی دوباره ارسال کرد. بههمین ترتیب، وقتی کار دستهای قبلاز تکمیل همه عملیات
لغو یا متوقف میشود، میتوانید
عملیات اجرا نشده (operation_index
>= executed_operation_count) را بههمراه هرگونه عملیات ناموفق
از پیشوند اجراشده در کار دستهای جدید دوباره ارسال کنید.