Size: a a a

2019 October 22

RI

Ruslan Ibragimov in Kotlin Moscow
Delay идёт в event-loop, какой вразумительный стектрейс ты можешь увидеть когда корутина резюмится с диспетчера?
источник

VS

Vladimir Sitnikov in Kotlin Moscow
delay вызывалось из какого кода? Из прикладного. Это и есть вразумительный стектрейс
источник

RI

Ruslan Ibragimov in Kotlin Moscow
Так это уже задним числом. Корутину после delay будет default dispatcher резюмить. Там стектрейс будет:

Я тред
Я диспетчер
Ой, а корутина уже закэнселина
источник

VS

Vladimir Sitnikov in Kotlin Moscow
нет
источник

VS

Vladimir Sitnikov in Kotlin Moscow
тов. Руслан, вы не понимаете как работают корутины и не понимаете смысл слов «cancellation is cooperative»
источник

VS

Vladimir Sitnikov in Kotlin Moscow
прикладной код (например, метод test) вызывал Java функцию delay?
источник

VS

Vladimir Sitnikov in Kotlin Moscow
вызывал
источник

VS

Vladimir Sitnikov in Kotlin Moscow
куда денется этот Java frame?
источник

VS

Vladimir Sitnikov in Kotlin Moscow
сам собой он не пропадёт
источник

RI

Ruslan Ibragimov in Kotlin Moscow
В корутинах фреймы не сохраняются, это не loom
источник

RI

Ruslan Ibragimov in Kotlin Moscow
Как работает поддержка async-stacktrace не скажу, но самим корутинам ничего не нужно сохранять для работы
источник

VS

Vladimir Sitnikov in Kotlin Moscow
suspend fun test() {
   println("test.begin")
   delay(5000)
   println("test.end")
}


delay это вызов метода в JVM?
Что произойдёт с тем фреймом, который вызывал delay?

Практика показывает, что если обернуть delay в try-catch, то при cancellation из delay вылетает CancellationException.
Иными словами, «даже после отмены корутины она продолжает выполняться».  «какой ужас».

Ещё раз: когда мы (или котлин) делает cancellation, то он «просто» подсылает CancellationException в корутину (грубо говоря resumeWithException(CancellationException()) )
И дальше она сама раскручивается.

Так вот: исходный вызов delay как был обычным jvm вызовом, так и остался. И сам собой со стека он не пропадёт => он пропадёт либо если delay вернёт значение, либо кинет исключение. Так вот: когда delay завершится у нас будет возможность получить нормальный стектрейс.


И тут есть как минимум 2 варианта:
1) На уровне Kotlin компилятора оборачивать все suspended вызовы в try-catch и добавлять к ним «new throwable()» чтобы получать актуальный стек
2) В автомат состояний добавлять доп. информацию. Как-никак, код всё равно «разрезан» по suspended call’ам, значит, мы точно знаем на какой строке кода находились на основе «switch label’а». И мы можем в exception добавить информацию: «кстати, когда пришло cancellation мы находились на такой-то строке кода такого-то метода». Это может быть «дешевле», чем генерировать целиковое исключение
источник

RI

Ruslan Ibragimov in Kotlin Moscow
Тот фрейм который вызвал delay положит в диспетчер условный "раннабл" и раскрутит трейс до корутин билдера
источник

RI

Ruslan Ibragimov in Kotlin Moscow
И уже диспетчер будет резюмить корутину в которой был delay, и в момент резьюма и будет такой трейс который я показал выше
источник

VS

Vladimir Sitnikov in Kotlin Moscow
Ruslan Ibragimov
Тот фрейм который вызвал delay положит в диспетчер условный "раннабл" и раскрутит трейс до корутин билдера
https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/cancellation-and-timeouts.md#closing-resources-with-finally

> Cancellable suspending functions throw CancellationException on cancellation which can be handled in the usual way
источник

VS

Vladimir Sitnikov in Kotlin Moscow
английским по белому написано, что выбрасывается CancellationException
источник

SM

Sergey Morgunov in Kotlin Moscow
Почему-то слова Руслана наводят меня на мысль, что восстановить стек проснувшейся корутины невозможно в принципе, а не только при кансел. Но ведь эта мысль на столько ужасна, что просто не может быть правдой 😱😂
источник

RI

Ruslan Ibragimov in Kotlin Moscow
Стек можно восстанавливать и нужно и это уже работает: https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/debugging.md#stacktrace-recovery-machinery
источник

RI

Ruslan Ibragimov in Kotlin Moscow
Тут вопрос в том что я не вижу понимания как работают корутины
источник

RI

Ruslan Ibragimov in Kotlin Moscow
О, кстати там чуть выше и показано как без recovery стек выглядит, что я и пытаюсь донести
источник