private getAllPingsWithoutSurplus()

in glean/src/core/pings/database.ts [190:258]


  private getAllPingsWithoutSurplus(
    maxCount = 250,
    maxSize = 10 * 1024 * 1024 // 10MB
  ): PingArray {
    const allPings = this.getAllPings();
    // Separate deletion-request from other pings.
    const pings = allPings
      .filter(([_, ping]) => !isDeletionRequest(ping))
      // We need to calculate the size of the pending pings database
      // and delete the **oldest** pings in case quota is reached.
      // So, we sort them in descending order (newest -> oldest).
      .reverse();
    const deletionRequestPings = allPings.filter(([_, ping]) => isDeletionRequest(ping));

    const total = pings.length;
    // TODO (bug 1722682): Record `glean.pending_pings` metric.
    if (total > maxCount) {
      log(
        PINGS_DATABASE_LOG_TAG,
        [
          `More than ${maxCount} pending pings in the pings database,`,
          `will delete ${total - maxCount} old pings.`
        ],
        LoggingLevel.Warn
      );
    }

    let deleting = false;
    let pendingPingsCount = 0;
    let pendingPingsDatabaseSize = 0;
    const remainingPings: PingArray = [];
    for (const [identifier, ping] of pings) {
      pendingPingsCount++;
      pendingPingsDatabaseSize += getPingSize(ping);

      if (!deleting && pendingPingsDatabaseSize > maxSize) {
        log(
          PINGS_DATABASE_LOG_TAG,
          [
            `Pending pings database has reached the size quota of ${maxSize} bytes,`,
            "outstanding pings will be deleted."
          ],
          LoggingLevel.Warn
        );
        deleting = true;
      }

      // Once we reach the number of allowed pings we start deleting,
      // no matter what size. We already log this before the loop.
      if (pendingPingsCount > maxCount) {
        deleting = true;
      }

      if (deleting) {
        // Delete ping from database.
        this.deletePing(identifier);

        // TODO (bug 1722685): Record `deleted_pings_after_quota_hit` metric.
      } else {
        // Add pings in reverse order so the final array is in ascending order again.
        remainingPings.unshift([identifier, ping]);
      }
    }

    // TODO(bug 1722686): Record `pending_pings_directory_size` metric.

    // Return pings to original order.
    return [...deletionRequestPings, ...remainingPings];
  }