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 funciones dependan del 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 características por RPC que no están documentadas aquí.

Tiempo de espera

La biblioteca de Java proporciona una plataforma para establecer 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 del tiempo máximo para una llamada a la API.

Para usar esta función, debes utilizar el objeto que admite llamadas directamente. Por ejemplo, si se llama 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 la situación en la que una solicitud de larga duración falla y la única forma de recuperarla es volver a activar la solicitud desde el principio.

Configuración de reintentos

La biblioteca de Java también proporciona una plataforma para configurar los ajustes de reintento en un nivel por llamada. Para usar esta función, debes utilizar el objeto que admite llamadas directamente. Por ejemplo, si se llama a GoogleAdsService.searchStream(), la configuración de reintentos se establecería 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 de 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 crear 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 al inicio, antes de entregar solicitudes de usuarios.

  2. Envía algunas solicitudes de preparación a la API de Google Ads cuando se inicie el proceso 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 del cliente de servicio reutilizará automáticamente las clases precargadas.

Reutilización del cliente de servicio

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

Debes asegurarte de cerrar el cliente cuando ya no sea necesario. Esto se puede hacer en un bloque de prueba con recursos o con una llamada 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 del 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 por cada archivo subido. El JAR de google-ads será considerablemente más grande que este, incluso más si se usan implementaciones de sombreado/shadow jar. Si implementas los archivos jar manualmente, podrías obtener 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, realiza la implementación con el complemento de Gradle de AppEngine o el complemento de Maven. Cada uno tiene una opción para enableJarSplitting, que dividirá cada archivo jar en fragmentos de 10 MB y los subirá.

Dependencias de sombras

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

Maven

mvn dependency:tree

Gradle

./gradlew dependencies

Si es inviable resolver conflictos de dependencias, puedes depender de la versión shaded de la biblioteca.

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'