private def adjustPrewarmedContainer()

in core/invoker/src/main/scala/org/apache/openwhisk/core/containerpool/v2/FunctionPullingContainerPool.scala [448:513]


  private def adjustPrewarmedContainer(init: Boolean, scheduled: Boolean): Unit = {
    if (!shuttingDown) {
      if (scheduled) {
        //on scheduled time, remove expired prewarms
        ContainerPoolV2.removeExpired(poolConfig, prewarmConfig, prewarmedPool).foreach { p =>
          prewarmedPool = prewarmedPool - p
          p ! Remove
        }
        //on scheduled time, emit cold start counter metric with memory + kind
        coldStartCount foreach { coldStart =>
          val coldStartKey = coldStart._1
          MetricEmitter.emitCounterMetric(
            LoggingMarkers.CONTAINER_POOL_PREWARM_COLDSTART(coldStartKey.memory.toString, coldStartKey.kind))
        }
      }

      ContainerPoolV2
        .increasePrewarms(
          init,
          scheduled,
          coldStartCount,
          prewarmConfig,
          prewarmedPool,
          prewarmStartingPool,
          prewarmConfigQueue)
        .foreach { c =>
          val config = c._1
          val currentCount = c._2._1
          val desiredCount = c._2._2
          if (prewarmCreateFailedCount.get() > poolConfig.prewarmMaxRetryLimit) {
            logging.warn(
              this,
              s"[kind: ${config.exec.kind}, memory: ${config.memoryLimit.toString}] prewarm create failed count exceeds max retry limit: ${poolConfig.prewarmMaxRetryLimit}, currentCount: ${currentCount}, desiredCount: ${desiredCount}")
          } else {
            if (currentCount < desiredCount) {
              (currentCount until desiredCount).foreach { _ =>
                poolConfig.prewarmContainerCreationConfig match {
                  case Some(_) =>
                    prewarmConfigQueue =
                      prewarmConfigQueue.enqueue((config.exec, config.memoryLimit, config.reactive.map(_.ttl)))
                  case None =>
                    prewarmContainer(config.exec, config.memoryLimit, config.reactive.map(_.ttl))
                }
              }
            }
          }
        }

      // run queue consumer
      poolConfig.prewarmContainerCreationConfig.foreach(config => {
        logging.info(
          this,
          s"prewarm container creation is starting with creation delay configuration [maxConcurrent: ${config.maxConcurrent}, creationDelay: ${config.creationDelay.toMillis} millisecond]")
        if (preWarmScheduler.isEmpty) {
          preWarmScheduler = Some(
            context.system.scheduler
              .scheduleAtFixedRate(0.seconds, config.creationDelay, self, PrewarmContainer(config.maxConcurrent)))
        }
      })

      if (scheduled) {
        //   lastly, clear coldStartCounts each time scheduled event is processed to reset counts
        coldStartCount = immutable.Map.empty[ColdStartKey, Int]
      }
    }
  }