@@ -20,11 +20,13 @@ package org.apache.openwhisk.core.containerpool
20
20
import akka .actor .{Actor , ActorRef , ActorRefFactory , Props }
21
21
import org .apache .openwhisk .common .MetricEmitter
22
22
import org .apache .openwhisk .common .{AkkaLogging , LoggingMarkers , TransactionId }
23
- import org .apache .openwhisk .core .connector .MessageFeed
23
+ import org .apache .openwhisk .core .connector .{ MessageFeed , PrewarmContainerData }
24
24
import org .apache .openwhisk .core .entity ._
25
25
import org .apache .openwhisk .core .entity .size ._
26
+
26
27
import scala .annotation .tailrec
27
28
import scala .collection .immutable
29
+ import scala .collection .mutable .ListBuffer
28
30
import scala .concurrent .duration ._
29
31
import scala .util .Try
30
32
@@ -34,6 +36,9 @@ case object Free extends WorkerState
34
36
35
37
case class WorkerData (data : ContainerData , state : WorkerState )
36
38
39
+ case class PreWarmConfigList (list : List [PrewarmingConfig ])
40
+ object PrewarmQuery
41
+
37
42
case object EmitMetrics
38
43
39
44
/**
@@ -70,6 +75,7 @@ class ContainerPool(childFactory: ActorRefFactory => ActorRef,
70
75
var busyPool = immutable.Map .empty[ActorRef , ContainerData ]
71
76
var prewarmedPool = immutable.Map .empty[ActorRef , ContainerData ]
72
77
var prewarmStartingPool = immutable.Map .empty[ActorRef , (String , ByteSize )]
78
+ var latestPrewarmConfig = prewarmConfig
73
79
// If all memory slots are occupied and if there is currently no container to be removed, than the actions will be
74
80
// buffered here to keep order of computation.
75
81
// Otherwise actions with small memory-limits could block actions with large memory limits.
@@ -279,6 +285,23 @@ class ContainerPool(childFactory: ActorRefFactory => ActorRef,
279
285
case RescheduleJob =>
280
286
freePool = freePool - sender()
281
287
busyPool = busyPool - sender()
288
+ case prewarmConfigList : PreWarmConfigList =>
289
+ latestPrewarmConfig = prewarmConfigList.list
290
+ // Delete prewarmedPool firstly
291
+ prewarmedPool foreach { element =>
292
+ val actor = element._1
293
+ actor ! Remove
294
+ prewarmedPool = prewarmedPool - actor
295
+ }
296
+ prewarmConfigList.list foreach { config =>
297
+ logging.info(this , s " add pre-warming ${config.count} ${config.exec.kind} ${config.memoryLimit.toString}" )(
298
+ TransactionId .invokerWarmup)
299
+ (1 to config.count).foreach { _ =>
300
+ prewarmContainer(config.exec, config.memoryLimit)
301
+ }
302
+ }
303
+ case PrewarmQuery =>
304
+ sender() ! getPrewarmContainer()
282
305
case EmitMetrics =>
283
306
emitMetrics()
284
307
}
@@ -304,7 +327,7 @@ class ContainerPool(childFactory: ActorRefFactory => ActorRef,
304
327
305
328
/** Install prewarm containers up to the configured requirements for each kind/memory combination. */
306
329
def backfillPrewarms (init : Boolean ) = {
307
- prewarmConfig .foreach { config =>
330
+ latestPrewarmConfig .foreach { config =>
308
331
val kind = config.exec.kind
309
332
val memory = config.memoryLimit
310
333
val currentCount = prewarmedPool.count {
@@ -375,6 +398,33 @@ class ContainerPool(childFactory: ActorRefFactory => ActorRef,
375
398
busyPool = busyPool - toDelete
376
399
}
377
400
401
+ /**
402
+ * get the prewarm container
403
+ * @return
404
+ */
405
+ def getPrewarmContainer (): ListBuffer [PrewarmContainerData ] = {
406
+ val containerDataList = prewarmedPool.values.toList.map { data =>
407
+ data.asInstanceOf [PreWarmedData ]
408
+ }
409
+
410
+ var resultList : ListBuffer [PrewarmContainerData ] = new ListBuffer [PrewarmContainerData ]()
411
+ containerDataList.foreach { prewarmData =>
412
+ val isInclude = resultList.filter { resultData =>
413
+ prewarmData.kind == resultData.kind && prewarmData.memoryLimit.toMB == resultData.memory
414
+ }.size > 0
415
+
416
+ if (isInclude) {
417
+ var resultData = resultList.filter { resultData =>
418
+ prewarmData.kind == resultData.kind && prewarmData.memoryLimit.toMB == resultData.memory
419
+ }.head
420
+ resultData.number += 1
421
+ } else {
422
+ resultList += PrewarmContainerData (prewarmData.kind, prewarmData.memoryLimit.toMB, 1 )
423
+ }
424
+ }
425
+ resultList
426
+ }
427
+
378
428
/**
379
429
* Calculate if there is enough free memory within a given pool.
380
430
*
0 commit comments