
John
04.07.2017
12:52:39
понял спс

Михаил
04.07.2017
12:53:08
но можно поглядеть KotlinRx примочки

John
04.07.2017
12:53:20
а где подробнее по лямбдам можно почитать?

Михаил
04.07.2017
12:53:49

Google

Михаил
04.07.2017
12:54:14
https://kotlinlang.org/docs/reference/lambdas.html

John
04.07.2017
12:54:45
ага норм, спасибо!

? animufag ?
04.07.2017
12:55:36
сделать свою функцию принимающую три лямбды и 2 из них с дефолтным значением

John
04.07.2017
12:56:56

Roman
04.07.2017
13:39:48

Igor
04.07.2017
13:40:40
Ну это хорошо, если “extensions/DSLs” есть на все случаи жизни (надеюсь на android это без anko возможно)

Roman
04.07.2017
13:50:41
Я всегда их чаще всего себе сам пишу. Ошибки же обычно централизованно обрабытаюся - одна функция на все приложение. Ну и use использую из stdlib для closeable штук. А зачем нужные try/catch/finally еще? У меня их в коде обычно почти нигде нет

John
04.07.2017
14:17:25
Подскажите еще пожалуйста, есть абстрактный CustomPagerAdapter<T> и есть CustomViewPager<T> . В CustomViewPager<T> есть параметр mAdapter:CustomPagerAdapter<T> и я пишу ему сеттер super.setAdapter(value). когда я пытаюсь присвоить переменной mAdapter пишет что "setter for mAdapter is removed by type projection" где я не прав? как исправить ситуацию?


Ivan
04.07.2017
14:22:43
А разве тут есть ответ на мой вопрос? Я пробежался (хотя я вполне мог что-то пропустить), там в основном про CPS transformation и state machine. Я тут осознал, что мои вопросы не к корутинам, а к ComputableFuture и к select, видимо
@relizarov Роман, не подскажете, я тут прав или нет?
Сам вопрос звучал так:
И если заговорили про корутины, объясните пожалуйста такую вещь: вот запустили корутину на тредпуле и вызвали await, в пуле нашёлся поток и он вызвал, допустим, бд на долго(это насколько я понял будет суспендбл поинт). Что или кто и в какой момент решит, что это на долго и что нужно вернуть поток в пулл? Должен же быть какой-то шедулер, нет? Тоже самое когда пришёл ответ от бд. Когда тред вернётся к начавшейся корутине?
А-то я наконец, прочитал https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md (хотя может что-то пропустил или не правильно понял), но ответов там не нашёл


Roman
04.07.2017
14:24:16
Поток будет освобожден _сразу же_ как только корутина заснула в ожидании чего-либо

Ivan
04.07.2017
14:56:46

Google

Roman
04.07.2017
14:59:25
Проснется тогда, когда та функция, которая её усыпила скажет "пора просыпаться" (вызовет continuation.resume)
Ну обычно мы спим в ожидании когда какой-нибудь async io вызовет какой-нибудь callback. И в коде этого коллбека стоит вызов resume. Смотри вот этот слайд: https://www.slideshare.net/elizarov/introduction-to-kotlin-coroutines/20
Про это же написано в спецификации корутин здесь: https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#wrapping-callbacks

Ivan
04.07.2017
15:05:53
ну т.е. я правильно понимаю что если у нас блокирующее IO то корутины тут не помогут?

Roman
04.07.2017
15:07:04
Смотря в чем вам нужна помощь. Если вы хотите чтобы ваше блокирующее IO вообще потоков не использовало — не помогут. Если вы всего-лишь хотите чтобы во время блокирующего IO не блокировался ваш UI поток — помогут

Руслан
04.07.2017
15:08:03
@relizarov если у нас JDBC, будет ли польза от того что мое приложение начиная от сервера будет асинхронное и неблокирующее, а в базу будет какой-то thread-pool с очередью перед ним?

Ivan
04.07.2017
15:09:30

Roman
04.07.2017
15:11:06
@HeapyHop Польза это очень относительное понятие. Очень зависит от того, какую вы систему пишете. Если у вас большой backend который использует в перемешку JDBC и еще 100500 REST микросервисов, то от корутин _огромная_ польза, так вы сможете четко контролировать сколько у вас одновременно JDBC запросов и коннекций к базе, но при этом масштабироваться на огромное чисто одновременно обрабатываемых запросов, пиша вашу бизнес-логику в совершенно естественном, как бы синхронном стиле

Руслан
04.07.2017
15:11:48

Александр
04.07.2017
15:12:34
По котлину на русском книги есть? В бумажном варианте

Roman
04.07.2017
15:14:39
@qvava Конечно равносильно. Только код будет элегантый. Вы один раз возьмете свою blockingOperation и используя функцию run сконвертируете её в non-blocking написав в одну строчку suspend fun nonBlockingOperation() = run(CommonPool) { blockingOperation() }. После этого можете спокойно использовать nonBlockingOperation из UI-bound корутин, например: launch(UI) { .. do somethin on UI; nonBlockingOperation(); ... do something else on UI ... }. То есть вы _инкапсулируете_ всё ваше блокируещее API и весь остальной код будете писать в асинхронном, неблокирующем стиле.
@HeapyHop Если у вас всё упирается в базу, то от корутин пользы не будет. Но это прошлый век. Сейчас популярны микросервисы и уже редко увидишь, что всё в базу упирается


Руслан
04.07.2017
15:16:59
Ну в смысле что конечный микросервис будет ходить в базу, асинхронного JDBC у нас нет, и вот общении между микросервисами и прием запросов от пользователя будет асинхронными, но в базу то мы упремся (в том смысле что там нету хорошего асинхронного драйвера к популярным ORM/мапперам).

Ivan
04.07.2017
15:17:05

Mustang
04.07.2017
15:18:42
Сохрани дерево. Скачай пдф

Roman
04.07.2017
15:18:45
Никакой подковерной магии нет! Вы бы это могли всё написать сами, но только получится говнокод. А так этот говнокод за вас сделает компилятор и вам не надо на него смотреть и глаза будут целы

Boris
04.07.2017
15:19:06
хорошая вещь корутины, но интуитивно совешенно непонятная, я вот отлично знаю как они работают, но вот такой простой метафоры, которая бы мне позволила думать о них как о последовательном коде нет. То что вроде они работают так же как последовательный код, только асинхронно в действительности только сбивает. Идеально было бы конечно иметь очень небольшой код, в котором корутины используются просто и понятно, это наверное было бы идеальная иллюстрация, только не синтетические примеры, как это бывает обычно в докладах, а вполне конкретные. Вот есть у нас приложение, вот тут вот у нас обработчик хттп запроса, вот тут мы делаем это асинхронно и от этого такой вот профит.. или тоже самое для андроида, что наверное попроще придумать


Руслан
04.07.2017
15:19:20
хорошая вещь корутины, но интуитивно совешенно непонятная, я вот отлично знаю как они работают, но вот такой простой метафоры, которая бы мне позволила думать о них как о последовательном коде нет. То что вроде они работают так же как последовательный код, только асинхронно в действительности только сбивает. Идеально было бы конечно иметь очень небольшой код, в котором корутины используются просто и понятно, это наверное было бы идеальная иллюстрация, только не синтетические примеры, как это бывает обычно в докладах, а вполне конкретные. Вот есть у нас приложение, вот тут вот у нас обработчик хттп запроса, вот тут мы делаем это асинхронно и от этого такой вот профит.. или тоже самое для андроида, что наверное попроще придумать
хорошая вещь корутины, но интуитивно совешенно непонятная, я вот отлично знаю как они работают, но вот такой простой метафоры, которая бы мне позволила думать о них как о последовательном коде нет. То что вроде они работают так же как последовательный код, только асинхронно в действительности только сбивает. Идеально было бы конечно иметь очень небольшой код, в котором корутины используются просто и понятно, это наверное было бы идеальная иллюстрация, только не синтетические примеры, как это бывает обычно в докладах, а вполне конкретные. Вот есть у нас приложение, вот тут вот у нас обработчик хттп запроса, вот тут мы делаем это асинхронно и от этого такой вот профит.. или тоже самое для андроида, что наверное попроще придумать
Не знаю насколько это качественный код, но тут я хожу в три места с помощью AsyncHttpClient(apache), который обернут в suspend функцию. В корутине runBlocking я делаю три параллельных запроса и ожидаю ответа с таймаутом, агрегирую результат и отдаю. Проблема в том, что окружающий мир - блокирующий, но хотя бы в маленьком месте я заюзал корутины)

Google

Boris
04.07.2017
15:22:32
да, я видел его, хороший пример

? animufag ?
04.07.2017
15:24:51


Boris
04.07.2017
15:25:12
но немного редкий для того, чтобы его применить для свого кода, обычно если это микросервисы, то там всё сложнее, но вцелом конечно для микросервисов легко себе представить их использование, а вот если я пытаюсь представить как я буду заменять флоу инициализации текстуры в гл-е, то не понимаю как я буду писать корутины, чтобы они перебрасывались из одного контекта выполнения в другой

Руслан
04.07.2017
15:25:45

Igor
04.07.2017
16:03:35
Примерно это же код на CompletableFuture
Если нет “бизнес логики” (а тут ее почти нет), то код получается почти одинаковым.
https://i.gyazo.com/a6d38955d9e096e87dfd362c16123c7f.png
(P.S. awaitOrNull это моя 3-х строчная фукция, которая делает anyOf с промисом на таймаут)

Alexander
04.07.2017
16:10:22

Михаил
04.07.2017
16:11:08
:D

? animufag ?
04.07.2017
16:11:55
как легко допустить ошибки без корутин

Roman
04.07.2017
16:15:53
Говорила мне мама — не используейте futures.... (и вам того же советую)

jacoder
04.07.2017
16:17:34

Igor
04.07.2017
16:17:40

Roman
04.07.2017
16:18:16

Igor
04.07.2017
16:24:10

Roman
04.07.2017
16:24:33
Да и вообще на futures/Rx нормально ложиться только _очень_ простая логика. Когда у тебя последовательный pipeline, следующий результат зависит строго только от предыдущего (не нужные промежуточные) и никаких лишних ветвлений или циклов в логике нет.

? animufag ?
04.07.2017
16:26:59

Igor
04.07.2017
16:27:04
Вот, Руслан _объективно_ про резюмировал. Остальное это мантры и попытки продать свою технологию, которая "лечит все на свете”.
Если тебе ок все чейнить, и так же обрабатывать ошибки то тогда тебе корутины совсем не нужны, они про то чтобы отказаться явной передачи колбеков и упростить жизнь разработчика не обремененного ФП

Roman
04.07.2017
16:27:15
@angmarr А как еще с фьчерсами сделать параллельно три запроса, дождаться ответа и как-то их объединить? При чем тут архитектура. Если перед вами всатала такая задача, то вам как-то надо её выразить в коде. Можно конечно ради этой задачи сделать Framework и Архитектуру, которая позволит такие задачи решать элегантно, но если эта задача встала один раз, то зачем?

Google

Roman
04.07.2017
16:29:19
+1. Еще надо добавить, что если ты готов для каждой нетривиальной задачи писать свой комбинатор ;)
(for the record — я RX очень люблю — это супер вещь для решения тех задач, для которых он был создан)

? animufag ?
04.07.2017
16:41:30
ну у rx в андроид есть некоторые штуки, помимо того что он решает проблемы с конкаренси.
1. то что приятно выражать свой асинхронный апи в типах rx. особенно со вторым, мол это событие произойдёт максимум один раз, вот это несколько. хотя чувствуется, что это всё могло бы быть написано сразу в джаве/в котлине все эти мапы, синглы, мейби.
2. то что есть потенциальный подписчик со своим жизненным циклом и потенциальный обсервабл. и подписать можешь совершенно из третьего места – получается такой (в худшем случае) эвентбас.если использовать корутины, то придётся его переизобретать


Igor
04.07.2017
16:53:04
Похоже что 1. вытекает из 2, если у вас по “архитектуре” все возвращается только одни раз, то и observable и не нужен, а нужны промисы.
Конкретно Observable на самом деле нужен редко и заменяется какой-нибудь EventBus/broadcasts
RX с его Observable + Single (Completable вообще не нужен в Kotlin) выглядит как солянка из reactive-streams + promises
Single/Completable изначально не были частью RX и по факту вносят скорее дискомфорт (toCompleble и тд) тем что не имеют общих интерфейсов.
В android я вообще пользуюсь только rx.Single и то потому что нет нормальных промисов из коробки (типа CompletableFuture).
А вот и статейка в тему с̶р̶а̶ч̶а̶ ̶к̶о̶р̶у̶т̶и̶н̶ы̶ ̶v̶s̶ ̶п̶р̶о̶м̶и̶с̶ы̶
https://medium.com/@vjames19/kotlin-futures-a-better-completablefuture-api-for-kotlin-using-extension-functions-bb50b989ea26

Yuri
04.07.2017
18:04:51
но в этом примере мы все равно заблокируемся на методе getCount? какой профит? в параллельном выполнении?

Admin
ERROR: S client not available

Igor
04.07.2017
18:10:51

Жабра
04.07.2017
18:29:56
Кто-нибудь хочет стать моим ментором? :))
Зачем программисту нужен ментор и где его найти: https://goo.gl/v4aqow
Спойлер: для тех случаев, когда Google не может помочь.
Чаще всего нужна помощь не в какой-то определенной библиотеке, а в построении ООП-модели.

Михаил
04.07.2017
18:31:05

Igor
04.07.2017
18:36:47

Umren
04.07.2017
18:38:13

Михаил
04.07.2017
20:26:01
а как в корутинах хэндлить ошибки без трай-кетч блоков?
есть что-то типа аналога onError из rxjava?

Ilya
04.07.2017
20:28:27
Вопрос непонятен. Стандартный механизм работы с ошибками в языке – исключения, и корутины следуют этому. Зачем ещё что-то сверху наворачивать?

Михаил
04.07.2017
20:29:46
ну может есть функция из коробки, которая предоставляет возможность передать колбэк, который вызовется на ошибку

Руслан
04.07.2017
20:34:13
Так причем тут корутины? :) Пиши на Rx если нравится onError

Google

Egor
04.07.2017
20:37:04
как можно сделать статическую ссылку на контект в андроиде?

Михаил
04.07.2017
20:39:20

Egor
04.07.2017
20:39:38
а точнее? я чет подзабыл и не получается теперь =(

Михаил
04.07.2017
20:40:01

Igor
04.07.2017
20:47:03

? animufag ?
04.07.2017
20:47:42
Кстати вот например внутри launch бросаю эксепшен, об этом можно как-нибудь извне узнать?

Михаил
04.07.2017
20:48:32

? animufag ?
04.07.2017
20:48:48
Не
Пробовал
Ну сейчас уже с телефона пишу, а так это единственное что пробовал
Ну как бы идея понятно внутри лаунча асинхронный код лаунч запускается успешно, и синхронный код едет дальше
У job может статус ставится специальный

Ilya
04.07.2017
21:03:57
Если установлен CoroutineExceptionHandler, тогда туда свалится, иначе в currentThread.uncaughtExceptionHandler

Михаил
04.07.2017
21:23:03
что-то в такой духе не получится написать?
launch(UI) {
run(CommonPool) {
updateErrorMessages()
}.ifError {
handleError(it)
}
notifyChange()
}

Ilya
04.07.2017
21:23:57
а чем это лучше completable future и зачем тут coroutines?

Михаил
04.07.2017
21:28:20
completable future нету на андроиде можно сказать)

Ilya
04.07.2017
21:41:19
беда…
Что-то такое хотите?
fun Job.onException(f: (Throwable) -> Unit) = invokeOnCompletion { if (it != null) f(it) }

Alexander
04.07.2017
21:46:13