override fun applyTaskChanges()

in plugin-azure-server/src/main/kotlin/jetbrains/buildServer/clouds/azure/arm/throttler/AzureThrottlerStrategyImpl.kt [29:96]


    override fun applyTaskChanges() {
        if (myFlow.get() == AzureThrottlerFlow.Suspended) {
            return
        }
        myLock.lock();
        try {
            val taskList = taskContainer.getTaskList()

            val currentResourceRequestsCount = adapter.getDefaultReads()
            val operableResourceRequestsCount = afterReservation(currentResourceRequestsCount)

            val currentRemainingRequestsCount = adapter.getRemainingReads()
            val operableRemainingRequestsCount = afterReservation(currentRemainingRequestsCount)

            val windowStartTime = adapter.getWindowStartDateTime()
            val windowWidthInMs = adapter.getWindowWidthInMilliseconds()

            if (operableRemainingRequestsCount > 0) {
                val randomTasksStatistics = taskList
                        .filter { it.timeExecutionType == AzureThrottlerTaskTimeExecutionType.Random }
                        .map { it.getStatistics(windowStartTime) }

                val currentRandomResourceRequestsCount = randomTasksStatistics.map { it.resourceRequestsCount ?: 0 }.sum()
                val totalRandomResourceRequestsReservation = max(
                        currentRandomResourceRequestsCount,
                        operableResourceRequestsCount * randomTasksResourceReservationInPercentsFunc() / 100)
                val remainingRandomResourceRequestsReservation = max(totalRandomResourceRequestsReservation - currentRandomResourceRequestsCount, 0)
                val remainingPeriodicalResourceRequestsCount = operableRemainingRequestsCount - remainingRandomResourceRequestsReservation

                if (remainingPeriodicalResourceRequestsCount > 0) {
                    val periodicalTasksStatistics = taskList
                            .filter { it.timeExecutionType == AzureThrottlerTaskTimeExecutionType.Periodical }
                            .map { it to it.getStatistics(windowStartTime) }
                            .sortedBy { it.second.resourceRequestsCount ?: 0 }

                    if (periodicalTasksStatistics.isNotEmpty()) {
                        val remainingPeriodicalResourceRequestsCountPerTask = remainingPeriodicalResourceRequestsCount / periodicalTasksStatistics.size

                        for ((task, statistics) in periodicalTasksStatistics) {
                            val executionCallCount = statistics.executionCallCount ?: 0
                            val resourceRequestsCount = statistics.resourceRequestsCount ?: 0
                            if (executionCallCount > 0 && resourceRequestsCount > 0) {
                                val callCount = floor(1.0 * remainingPeriodicalResourceRequestsCountPerTask * executionCallCount / resourceRequestsCount).toLong()
                                val taskTimeout = windowWidthInMs / (1000 * (callCount + 1))
                                task.setCacheTimeout(taskTimeout, AzureThrottlingSource.Throttler)
                            } else {
                                task.setCacheTimeout(0, AzureThrottlingSource.Throttler)
                            }
                        }
                    }
                }
            }

            var adapterThrottlerTimeInMs = 0L
            if (currentRemainingRequestsCount > 0
                    && currentResourceRequestsCount > 0
                    && currentRemainingRequestsCount * 100 / currentResourceRequestsCount <= 100 - enableAggressiveThrottlingWhenReachLimitInPercentsFunc()) {
                adapterThrottlerTimeInMs = windowWidthInMs / currentRemainingRequestsCount
            } else if (operableRemainingRequestsCount == 0L) {
                adapterThrottlerTimeInMs = windowWidthInMs
            }
            var resultAdaptherThrottlerTimeInMs = min(max(adapterThrottlerTimeInMs, defaultAdapterThrottlerTimeInMsFunc()), maxAdapterThrottlerTimeFunc())
            adapter.setThrottlerTime(resultAdaptherThrottlerTimeInMs)
        }
        finally {
            myLock.unlock()
        }
    }