I have a list of 30 objects for which I need to call API. I then add the result of all API calls and return as answer. But it gives 503 error after few calls.
override suspend fun getScoreboard(docId: String): ScoreboardResult {
val scoreboardResult = ScoreboardResult()
try {
withContext(Dispatchers.IO) {
val cfHandles = getCfHandles(docId = docId)
val contests = getContests(docId = docId).split(";")
Log.d(TAG, "contests size = ${contests.size} ===> $contests")
Log.d(TAG, Thread.currentThread().toString())
for(contest in contests) {
val options = hashMapOf("contestId" to contest, "handles" to cfHandles)
Log.d(TAG, "Doing contest: $contest")
lateinit var contestScore: PartiesScore
////delay(1500)//todo: Avoid using this delay
launch {
Log.d(TAG, Thread.currentThread().toString())
contestScore = getPartiesScore(options= options)//suspend function (Api call)
if (contestScore.status == Constants.CF_API_SUCCESS_STATUS) {
Log.d(TAG, "Success $contest")
scoreboardResult.updateScore(contestScore.result.rows)
} else {
throw (CustomException(message = "Failed at contest: $contest"))
}
}
}
}
Log.d(TAG, "Everything went well")
return scoreboardResult
} catch (exception: Exception) {
Log.d(TAG, "Something bad happened : ${exception.message}")
scoreboardResult.exception = exception
return scoreboardResult
}
}
This is my logcat:---
18:20:51.491 D contests size = 30 ===\> \[1711, 1714, 1713, 1712, 1722, 1717, 1726, 1729, 1733, 1738, 1737, 1736, 1741, 1742, 1746, 1743, 1732, 1759, 1761, 1760, 1758, 1764, 1771, 1766, 1762, 1767, 1774, 1772, 1770, 1731\]
18:20:51.491 D Thread\[DefaultDispatcher-worker-2,5,main\]
18:20:51.492 D Doing contest: 1711
18:20:51.493 D Doing contest: 1714
18:20:51.494 D Thread\[DefaultDispatcher-worker-3,5,main\]
18:20:51.494 D Doing contest: 1713
18:20:51.495 D Thread\[DefaultDispatcher-worker-1,5,main\]
18:20:51.496 D Doing contest: 1712
18:20:51.496 D Thread\[DefaultDispatcher-worker-4,5,main\]
18:20:51.497 D Doing contest: 1722
18:20:51.497 D Thread\[DefaultDispatcher-worker-7,5,main\]
18:20:51.498 D Doing contest: 1717
18:20:51.498 D Thread\[DefaultDispatcher-worker-6,5,main\]
18:20:51.499 D Doing contest: 1726
18:20:51.501 D Thread\[DefaultDispatcher-worker-5,5,main\]
18:20:51.502 D Doing contest: 1729
18:20:51.503 D Doing contest: 1733
18:20:51.503 D Thread\[DefaultDispatcher-worker-10,5,main\]
18:20:51.503 D Thread\[DefaultDispatcher-worker-8,5,main\]
18:20:51.503 D Doing contest: 1738
18:20:51.503 D Thread\[DefaultDispatcher-worker-11,5,main\]
18:20:51.504 D Doing contest: 1737
18:20:51.504 D Thread\[DefaultDispatcher-worker-9,5,main\]
18:20:51.504 D Doing contest: 1736
18:20:51.504 D Thread\[DefaultDispatcher-worker-13,5,main\]
18:20:51.504 D Doing contest: 1741
18:20:51.505 D Thread\[DefaultDispatcher-worker-12,5,main\]
18:20:51.506 D Doing contest: 1742
18:20:51.506 D Thread\[DefaultDispatcher-worker-14,5,main\]
18:20:51.511 D Doing contest: 1746
18:20:51.511 D Thread\[DefaultDispatcher-worker-4,5,main\]
18:20:51.511 D Thread\[DefaultDispatcher-worker-14,5,main\]
18:20:51.512 D Doing contest: 1743
18:20:51.512 D Doing contest: 1732
18:20:51.513 D Doing contest: 1759
18:20:51.514 D Thread\[DefaultDispatcher-worker-7,5,main\]
18:20:51.514 D Doing contest: 1761
18:20:51.515 D Thread\[DefaultDispatcher-worker-13,5,main\]
18:20:51.516 D Doing contest: 1760
18:20:51.516 D Thread\[DefaultDispatcher-worker-12,5,main\]
18:20:51.516 D Thread\[DefaultDispatcher-worker-16,5,main\]
18:20:51.517 D Doing contest: 1758
18:20:51.517 D Thread\[DefaultDispatcher-worker-4,5,main\]
18:20:51.518 D Doing contest: 1764
18:20:51.518 D Thread\[DefaultDispatcher-worker-15,5,main\]
18:20:51.518 D Thread\[DefaultDispatcher-worker-9,5,main\]
18:20:51.520 D Doing contest: 1771
18:20:51.521 D Doing contest: 1766
18:20:51.521 D Thread\[DefaultDispatcher-worker-12,5,main\]
18:20:51.521 D Thread\[DefaultDispatcher-worker-15,5,main\]
18:20:51.522 D Doing contest: 1762
18:20:51.523 D Doing contest: 1767
18:20:51.523 D Thread\[DefaultDispatcher-worker-14,5,main\]
18:20:51.525 D Doing contest: 1774
18:20:51.525 D Thread\[DefaultDispatcher-worker-9,5,main\]
18:20:51.527 D Doing contest: 1772
18:20:51.527 D Doing contest: 1770
18:20:51.527 D Thread\[DefaultDispatcher-worker-4,5,main\]
18:20:51.528 D Thread\[DefaultDispatcher-worker-12,5,main\]
18:20:51.528 D Thread\[DefaultDispatcher-worker-14,5,main\]
18:20:51.528 D Doing contest: 1731
18:20:51.530 D Thread\[DefaultDispatcher-worker-2,5,main\]
18:20:52.936 D Success 1712
18:20:52.964 D Something bad happened : HTTP 503
If I give some deliberate delay of around 1000-2000ms (just before the launch block) then all the API calls are successful but without delay it gives error. I feel it is too many coroutines being created which causes 503 response.
Since I have 30 contests and using delay for each one of them would give a terrible User Experience.
Is there any way that all API calls are done successfully without using delay ?
contestScorevariable. So in any one coroutine, it can write to the variable, and then later when it reads to the variable, it could have been changed by another one of the sibling coroutines. Secondly,ScoreboardResult.updateScore()needs to be internally safe via mutex locking if you're using it this way. If it's not thread safe at all, it will have unexpected results. If synchronized, it will be blocking coroutine threads which is undesirable.contestScorevariable is not threadsafe.