Size: a a a

Kotlin Community

2020 September 03

AH

Ayrat Hudaygulov in Kotlin Community
Было бы здорово если б в котлине чот такое было
источник

AH

Ayrat Hudaygulov in Kotlin Community
попроще чем свой движок саспендов
источник

AM

Andrew Mikhaylov in Kotlin Community
Пишите KEEP :)
источник

RI

Ruslan Ibragimov in Kotlin Community
Ruslan Ibragimov
Сейчас опциональная да, но все идет к тому что они везде пролезают и будут куда более востребованы чем работа с thread api. И соответсвенно код становится более вербозный. Я говорю о том что этот дефолт был хорош на старте, но сейчас хочется сделать обратный.

Есть три вида функций:

1. suspend
2. regular
3. blocking

В языке сейчас есть средства только чтобы пометить suspend. И таких функций становится большинство. Соотвественно если теперь suspend это норма, то хотелось бы чтобы

1. suspend fun -> fun
2. regular (fun) -> nosuspend fun (для оптизиций, можно и не вводить такой keyword)
3. blocking (fun) -> blocking fun - те функции которые по каким-то причинам блокируют поток, и их важно не вызвать на основном пуле
Может в каком-нибудь апдейте сделают флажок на модуль, которые что-то подобное и будет делать, надеюсь на это
источник

AM

Andrew Mikhaylov in Kotlin Community
Ruslan Ibragimov
Может в каком-нибудь апдейте сделают флажок на модуль, которые что-то подобное и будет делать, надеюсь на это
Насколько я помню, дизайнеры языка стараются целенаправленно избегать ситуаций, когда какие-то флажки в билд-конфигурации меняли бы семантику котлин-кода с валидного на другой валидный. Чтобы всё было однозначно.
источник

AM

Andrew Mikhaylov in Kotlin Community
Возможно, Kotlin 2.0 таки быть когда-нибудь :)
источник

АЕ

Алексей Ершов... in Kotlin Community
звучит очень странно, на самом деле.
1) Исходное утверждение спорное, в каких-то проектах может и становится всё suspend, а в каких-то нет.
2) suspend-функции, хоть они и несравнимо круче обычных потоков, сложнее правильно писать чем regular, нужно хорошо прошарить корутины чтобы ими нормально пользоваться.
3) Как всё-таки отличить blocking от regular? IO понятно, а вычисление чего-нибудь тяжелого, это blocking или regular? А если от параметра зависит, будет функция тяжелой или нет?
4) И самое главное: зачем это всё? Чтобы в проекте стало на 1000 слов suspend меньше?
источник

RI

Ruslan Ibragimov in Kotlin Community
Алексей Ершов
звучит очень странно, на самом деле.
1) Исходное утверждение спорное, в каких-то проектах может и становится всё suspend, а в каких-то нет.
2) suspend-функции, хоть они и несравнимо круче обычных потоков, сложнее правильно писать чем regular, нужно хорошо прошарить корутины чтобы ими нормально пользоваться.
3) Как всё-таки отличить blocking от regular? IO понятно, а вычисление чего-нибудь тяжелого, это blocking или regular? А если от параметра зависит, будет функция тяжелой или нет?
4) И самое главное: зачем это всё? Чтобы в проекте стало на 1000 слов suspend меньше?
1. Я бы сказал что вся индустрия к этому движется, андроидные API afaik переходя на корутины, весь Srping переписали на реактивщину+корутины. Понятно что есть легаси которое никогда туда не перейдет, но я даже там где корутины как бы и не нужны (простые скрипты для ingest данных) уже тоже пишу с корутинами, потому что тот же ktor-client на них. У меня вообще корутины с первых версий везде, и я просто не пишу уже thread-на-реквест-код с тех пор, и не понимаю зачем сегодня кто-то так будет писать.

2. Не сложнее. Нужно сравнивать одинаковые операции. Оркестировать десятки потоков, передавать данные, синхронизировать, иметь что-то на подобии structured concurency с потоками куда сложнее. Создать поток и корутину одинаково просто. Работать поверх сервера который выполняет код в корутине или в треде одинаково просто. Обычно сложности возникают на стыке тредов и корутин, но это уходит в прошлое с каждым днем.

3. Если функция может выполняться долго то это уже кандитат на модификатор blocking. Лучше сделать бесполезный context switch, чем заблокировать io тред сервера, и задача этого модификатора уберечь от таких ошибок.

4. Чтобы убрать визуальный шум да, особенно в светлом будущем, где среднему разработчику не придется использовать треды, как сейчас нету в коде приложения драйверов для устройств ввода 🙂
источник

EP

Eugene P. in Kotlin Community
Можно ли как-то узнать, был ли Continuation из suspendCoroutine resumed? Пытался проверить по контексту continuation.context.isActive но там true, почему-то даже после вызова`resumeWithException`
источник

АЕ

Алексей Ершов... in Kotlin Community
2. Про треды вопросов нет, я сравнивал что их сложнее писать чем обычный блокирующий код.

В общем, интересная идея, но я бы у себя такой флажок не применил)
источник

EP

Eugene P. in Kotlin Community
Вот, набросал тест
 @Test
   fun testContinuationState() = runBlocking<Unit> {
       val scope = CoroutineScope(Dispatchers.Default + Job(coroutineContext[Job]))
       val value = suspendCoroutine<Boolean> { continuation ->
           scope.launch {
               continuation.resume(true)
               println("suspendCoroutine resumed")
               delay(1000)
               println("suspendCoroutineStillActive ${continuation.context.isActive}")
               scope.cancel()
           }
       }
       println("suspendCoroutineValue $value")
   }

Выводит
suspendCoroutine resumed
suspendCoroutineValue true
suspendCoroutineStillActive true

ЧЯДНТ?
источник

EP

Eugene P. in Kotlin Community
Или suspendCoroutine использует parent context?
источник

BP

Bogdan Panchenko in Kotlin Community
Ruslan Ibragimov
Лум сделает так что не будет вообще блокирующих API
(нет) просто это скроют от пользователя
источник

RI

Ruslan Ibragimov in Kotlin Community
Eugene P.
Вот, набросал тест
 @Test
   fun testContinuationState() = runBlocking<Unit> {
       val scope = CoroutineScope(Dispatchers.Default + Job(coroutineContext[Job]))
       val value = suspendCoroutine<Boolean> { continuation ->
           scope.launch {
               continuation.resume(true)
               println("suspendCoroutine resumed")
               delay(1000)
               println("suspendCoroutineStillActive ${continuation.context.isActive}")
               scope.cancel()
           }
       }
       println("suspendCoroutineValue $value")
   }

Выводит
suspendCoroutine resumed
suspendCoroutineValue true
suspendCoroutineStillActive true

ЧЯДНТ?
Ну пожалуй стоит начать с того что так suspendCoroutine не стоит использовать, он для других целей. Или это чисто для демонстрации код?
источник

BP

Bogdan Panchenko in Kotlin Community
Ayrat Hudaygulov
В котлине стейт машины похоже тоже только за суспенд функциями захардкожены.
Ну это не значит что будет сгенерировано стейт машина
источник

EP

Eugene P. in Kotlin Community
Ruslan Ibragimov
Ну пожалуй стоит начать с того что так suspendCoroutine не стоит использовать, он для других целей. Или это чисто для демонстрации код?
Для демонстрации. Из другого потока передается значение
источник

EP

Eugene P. in Kotlin Community
в реале из listener'а библиотеки
источник

EP

Eugene P. in Kotlin Community
Похоже там все запривачено в Continuation, никак текущий стейт не прочитаешь, чтобы не словить "java.lang.IllegalStateException: Already resumed"
источник

RI

Ruslan Ibragimov in Kotlin Community
Eugene P.
Для демонстрации. Из другого потока передается значение
context тут скорее всего прилетает из runBlocking, в тот момент когда проверяется его статус он очевидно все еще выполняется. Но я так и не понял где тут смысл и зачем вообще это смотреть
источник

BP

Bogdan Panchenko in Kotlin Community
Ну можно посмотреть на go, там функции по умолчанию имеют ассинхроность
источник