Войти Регистрация
Конкурентность

32. Выписка по трём картам Т‑Банка с таймаутом

Средняя

Kotlin · 30 строк

У клиента обычно 2–4 карты: дебетовая, кредитная и детская. Операции за месяц по одной карте приходят из старого API operationsBlocking — обычного блокирующего вызова, обычно за 200 мс, иногда за 20 секунд.

Карта, которая не ответила за 3 секунды, должна попасть в failed, а экран — показать остальное. Отметьте строки с ошибками.

В работе: Бэкенд мобильного приложения, экран «Выписка за месяц».

Как проверяем Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Плюс 2 вопроса про поведение программы — на зачёт не влияют. Ответ один на подход: после него показываем разбор.
корутиныChannelwithTimeoutблокирующий вызовгонка

Источник: наша задача на данных Т‑Банка: выписка по картам клиента. Условие пересказано своими словами.

  1. import kotlinx.coroutines.*
  2. import kotlinx.coroutines.channels.Channel
  3. data class Statement(val operations: List<Operation>, val failed: List<String>)
  4. class StatementLoader(private val bank: BankApi) {
  5. suspend fun load(cards: List<String>, month: String): Statement = coroutineScope {
  6. val ch = Channel<Operation>(capacity = 100)
  7. val failed = mutableListOf<String>()
  8. cards.forEach { card ->
  9. launch(Dispatchers.IO) {
  10. try {
  11. withTimeout(3_000) {
  12. bank.operationsBlocking(card, month).forEach { ch.send(it) }
  13. }
  14. } catch (e: TimeoutCancellationException) {
  15. failed.add(card)
  16. }
  17. }
  18. }
  19. val operations = mutableListOf<Operation>()
  20. for (op in ch) {
  21. operations.add(op)
  22. }
  23. Statement(operations.sortedByDescending { it.date }, failed)
  24. }
  25. }