Uso avanzado

En esta guía, se describe cómo personalizar varios de los aspectos más avanzados de la biblioteca cliente de Java. Un patrón común es que muchas de estas características se basan en el Callable subyacente en lugar de los métodos estándar. Por lo general, la función que admite llamadas es un buen lugar para buscar otras funciones por RPC que no están documentadas aquí.

Tiempo de espera

La biblioteca de Java proporciona una plataforma para configurar los tiempos de espera a nivel de cada llamada. El valor predeterminado se establece según la configuración de method_config/timeout en googleads_grpc_service_config.json. Establece un valor más bajo si necesitas aplicar un límite más corto en el tiempo máximo de una llamada a la API.

Para usar esta función, debes usar directamente el objeto que admite llamadas. Por ejemplo, si llamas a GoogleAdsService.searchStream(), el tiempo de espera se establecerá de la siguiente manera:

try (GoogleAdsServiceClient googleAdsServiceClient =
    googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
  // Constructs the SearchGoogleAdsStreamRequest.
  SearchGoogleAdsStreamRequest request = ...

  // Executes the API call, with a timeout of 5 minutes.
  ServerStream<SearchGoogleAdsStreamResponse> result = googleAdsServiceClient
      .searchStreamCallable()
      .call(request,
          GrpcCallContext.createDefault().withTimeout(Duration.of(5, ChronoUnit.MINUTES)));
}

Puedes establecer el tiempo de espera en 2 horas o más, pero es posible que la API agote el tiempo de espera de las solicitudes de larga duración y muestre un error DEADLINE_EXCEEDED. Si esto se convierte en un problema, suele ser mejor dividir la consulta y ejecutar los fragmentos en paralelo. Esto evita una situación en la que una solicitud de larga duración falla y la única forma de recuperarla es activar la solicitud de nuevo desde el principio.

Configuración de reintentos

La biblioteca de Java también proporciona una plataforma para establecer la configuración de reintentos a nivel de cada llamada. Para usar esta función, debes usar directamente el objeto que admite llamadas. Por ejemplo, si se llama a GoogleAdsService.searchStream(), la configuración de reintento se establecerá de la siguiente manera:

// Creates a context object with the custom retry settings.
GrpcCallContext context = GrpcCallContext.createDefault()
    .withRetrySettings(RetrySettings.newBuilder()
    .setInitialRetryDelay(Duration.ofMillis(10L))
    .setMaxRetryDelay(Duration.ofSeconds(10L))
    .setRetryDelayMultiplier(1.4)
    .setMaxAttempts(10)
    .setLogicalTimeout(Duration.ofSeconds(30L))
    .build());

// Creates and issues a search Google Ads stream request.
ServerStream<SearchGoogleAdsStreamResponse> stream =
    googleAdsServiceClient.searchStreamCallable().call(request, context);

Optimización del rendimiento del tiempo de inicio

Es posible que notes una pequeña demora la primera vez que se crea una instancia GoogleAdsClient. Esto se debe a la interfaz fluida para servicios (GoogleAdsClient.getVersionXX()), que carga todas las clases de API a la vez a fin de proporcionar un mecanismo más conveniente para construir clases de servicio.

Si el rendimiento de la primera solicitud se encuentra en la ruta crítica de tu aplicación, debes seguir estos pasos:

  1. Crea el GoogleAdsClient en el inicio, antes de entregar las solicitudes de los usuarios.

  2. Envía algunas solicitudes de preparación a la API de Google Ads cuando el proceso se inicie por primera vez. Por ejemplo:

    // Runs some warm-up requests.
    try (GoogleAdsServiceClient googleAdsServiceClient =
        googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
      // Runs 5 warm-up requests. In our profiling we see that 90% of performance
      // loss is only experienced on the first API call. After 3 subsequent calls we
      // saw a negligible improvement in performance.
      for (int i = 0; i < 5;   i) {
        // Warm-up queries are run with a nonexistent CID so the calls will fail. If
        // you have a CID that you know will be accessible with the OAuth
        // credentials provided you may want to provide that instead and avoid the
        // try-catch.
        try {
          googleAdsServiceClient.search("-1", "Warm-up query");
        } catch (GoogleAdsException ex) {
          // Do nothing, we're expecting this to fail.
        }
      }
    }
    

Las solicitudes de preparación solo se deben ejecutar una vez por proceso. Cada creación posterior de clientes de servicios reutilizará automáticamente las clases precargadas.

Reutilización del cliente de servicios

Debes volver a usar las instancias de cliente de servicio cuando sea práctico, ya que cada llamada a GoogleAdsClient.getVersionXXX().createYYYServiceClient() creará una nueva conexión TCP.

Debes asegurarte de cerrar el cliente cuando ya no sea necesario. Esto se puede hacer en un bloque try-with-resources o llamando a close() en el cliente de servicio.

Si intentas usar un cliente de servicio cerrado para realizar solicitudes a la API, el método del cliente de servicio arrojará una java.util.concurrent.RejectedExecutionException.

App Engine no se puede implementar si el archivo JAR supera los 32 MB

App Engine tiene una cuota de 32 MB para cada archivo subido. El JAR para google-ads será considerablemente más grande que este, incluso más mediante implementaciones de shadow y shadow jar. Si implementas los jars de forma manual, es posible que recibas errores como los siguientes:

ERROR: (gcloud.app.deploy) Cannot upload file [<your-app>/WEB-INF/lib/google-ads-14.0.0.jar],
which has size [66095767] (greater than maximum allowed size of [33554432])

En su lugar, implementa mediante el complemento de Gradle de App Engine o el complemento de Maven. Cada uno tiene una opción para enableJarSplitting, que dividirá cada jar en fragmentos de 10 MB y los subirá en su lugar.

Dependencias paralelas

Si tu proyecto tiene dependencias que entran en conflicto con las de la biblioteca, debes inspeccionar las dependencias del proyecto con uno de los siguientes comandos y, luego, modificar las dependencias según sea necesario.

Maven

mvn dependency:tree

Gradle

./gradlew dependencies

Si no es posible resolver los conflictos de dependencias, puedes depender de la versión shaded de la biblioteca en su lugar.

Maven

<dependency>
  <groupId>com.google.api-ads</groupId>
  <artifactId>google-ads-shadowjar</artifactId>
  <version>31.0.0</version>
</dependency>

Gradle

implementation 'com.google.api-ads:google-ads-shadowjar:31.0.0'