@@ -11,34 +11,63 @@ import cromwell.database.sql.SqlConverters.OffsetDateTimeToSystemTimestamp
11
11
import cromwell .database .sql .tables .GroupMetricsEntry
12
12
13
13
import java .time .OffsetDateTime
14
+ import scala .concurrent .Future
15
+ import scala .concurrent .duration .FiniteDuration
14
16
import scala .util .{Failure , Success }
15
17
16
- class GroupMetricsActor (engineDbInterface : EngineSqlDatabase , quotaExhaustionThresholdInMins : Long )
17
- extends Actor
18
+ class GroupMetricsActor (engineDbInterface : EngineSqlDatabase ,
19
+ quotaExhaustionThresholdInMins : Long ,
20
+ loggingInterval : FiniteDuration
21
+ ) extends Actor
18
22
with ActorLogging {
19
23
20
24
implicit val ec : MessageDispatcher = context.system.dispatchers.lookup(Dispatcher .EngineDispatcher )
21
25
26
+ log.info(
27
+ s " ${this .getClass.getSimpleName} configured to log groups experiencing quota exhaustion at interval of ${loggingInterval.toString()}. "
28
+ )
29
+ // initial schedule for logging exhausted groups
30
+ context.system.scheduler.scheduleOnce(loggingInterval)(self ! LogQuotaExhaustedGroups )
31
+
22
32
override def receive : Receive = {
23
33
case RecordGroupQuotaExhaustion (group) =>
24
34
val groupMetricsEntry = GroupMetricsEntry (group, OffsetDateTime .now.toSystemTimestamp)
25
35
engineDbInterface.recordGroupMetricsEntry(groupMetricsEntry)
26
36
()
27
37
case GetQuotaExhaustedGroups =>
28
38
val respondTo : ActorRef = sender()
29
-
30
- // for a group in the GROUP_METRICS_ENTRY table, if the 'quota_exhaustion_detected' timestamp hasn't
31
- // been updated in last X minutes it is no longer experiencing cloud quota exhaustion
32
- val currentTimestampMinusDelay = OffsetDateTime .now().minusMinutes(quotaExhaustionThresholdInMins)
33
- engineDbInterface.getQuotaExhaustedGroups(currentTimestampMinusDelay.toSystemTimestamp) onComplete {
39
+ getQuotaExhaustedGroups() onComplete {
34
40
case Success (quotaExhaustedGroups) => respondTo ! GetQuotaExhaustedGroupsSuccess (quotaExhaustedGroups.toList)
35
41
case Failure (exception) => respondTo ! GetQuotaExhaustedGroupsFailure (exception.getMessage)
36
42
}
43
+ case LogQuotaExhaustedGroups =>
44
+ getQuotaExhaustedGroups() onComplete {
45
+ case Success (quotaExhaustedGroups) =>
46
+ log.info(
47
+ s " Hog groups currently experiencing quota exhaustion: ${quotaExhaustedGroups.length}. Group IDs: [ ${quotaExhaustedGroups.toList
48
+ .mkString(" , " )}]. "
49
+ )
50
+ case Failure (exception) =>
51
+ log.info(
52
+ s " Something went wrong when fetching quota exhausted groups for logging. Will retry in ${loggingInterval
53
+ .toString()}. Exception: ${exception.getMessage}"
54
+ )
55
+ }
56
+ // schedule next logging
57
+ context.system.scheduler.scheduleOnce(loggingInterval)(self ! LogQuotaExhaustedGroups )
58
+ ()
37
59
case other =>
38
60
log.error(
39
61
s " Programmer Error: Unexpected message ${other.toPrettyElidedString(1000 )} received by ${this .self.path.name}. "
40
62
)
41
63
}
64
+
65
+ private def getQuotaExhaustedGroups (): Future [Seq [String ]] = {
66
+ // for a group in the GROUP_METRICS_ENTRY table, if the 'quota_exhaustion_detected' timestamp hasn't
67
+ // been updated in last X minutes it is no longer experiencing cloud quota exhaustion
68
+ val currentTimestampMinusDelay = OffsetDateTime .now().minusMinutes(quotaExhaustionThresholdInMins)
69
+ engineDbInterface.getQuotaExhaustedGroups(currentTimestampMinusDelay.toSystemTimestamp)
70
+ }
42
71
}
43
72
44
73
object GroupMetricsActor {
@@ -47,12 +76,17 @@ object GroupMetricsActor {
47
76
sealed trait GroupMetricsActorMessage
48
77
case class RecordGroupQuotaExhaustion (group : String ) extends GroupMetricsActorMessage
49
78
case object GetQuotaExhaustedGroups extends GroupMetricsActorMessage
79
+ case object LogQuotaExhaustedGroups extends GroupMetricsActorMessage
50
80
51
81
// Responses
52
82
sealed trait GetQuotaExhaustedGroupsResponse
53
83
case class GetQuotaExhaustedGroupsSuccess (quotaExhaustedGroups : List [String ]) extends GetQuotaExhaustedGroupsResponse
54
84
case class GetQuotaExhaustedGroupsFailure (errorMsg : String ) extends GetQuotaExhaustedGroupsResponse
55
85
56
- def props (engineDbInterface : EngineSqlDatabase , quotaExhaustionThresholdInMins : Long ): Props =
57
- Props (new GroupMetricsActor (engineDbInterface, quotaExhaustionThresholdInMins)).withDispatcher(EngineDispatcher )
86
+ def props (engineDbInterface : EngineSqlDatabase ,
87
+ quotaExhaustionThresholdInMins : Long ,
88
+ loggingInterval : FiniteDuration
89
+ ): Props =
90
+ Props (new GroupMetricsActor (engineDbInterface, quotaExhaustionThresholdInMins, loggingInterval))
91
+ .withDispatcher(EngineDispatcher )
58
92
}
0 commit comments