Luke Rohde
11/08/2019, 5:08 PMjeff
11/08/2019, 5:58 PMflow { expensiveNetworkOperation() }
and I want to collect that flow repeatedly. What's the best way to prevent duplicating the expensiveNetworkOperation() call?bholota
11/09/2019, 10:45 PMursus
11/09/2019, 10:58 PMsujin
11/10/2019, 10:06 AMjanvladimirmostert
11/10/2019, 5:25 PMCompletableFuture.await()
, how much overhead does await()
add in the scenario where the CompletableFuture
is not yet done?
public suspend fun <T> CompletionStage<T>.await(): T {
// fast path when CompletableFuture is already done (does not suspend)
if (this is Future<*> && isDone()) {
...
}
// slow path -- suspend
return suspendCancellableCoroutine { cont: CancellableContinuation<T> ->
val consumer = ContinuationConsumer(cont)
whenComplete(consumer)
cont.invokeOnCancellation {
// mayInterruptIfRunning is not used
(this as? CompletableFuture<T>)?.cancel(false)
consumer.cont = null // shall clear reference to continuation to aid GC
}
}
}
Is the overhead just extra class instances being created or is there more happening?ursus
11/10/2019, 7:09 PMelaborate tissue
11/11/2019, 2:47 AMMark
11/11/2019, 6:40 AMtrathschlag
11/11/2019, 9:53 AMlazy
? I'm not looking for async
. All I want is execution in the current coroutine, if the value was not yet computed.ghedeon
11/11/2019, 4:17 PMCoroutineScope scope = ViewModelKt.getViewModelScope(this);
BuildersKt.launch(scope, scope.getCoroutineContext(), CoroutineStart.DEFAULT,
(_scope, continuation) -> signUp.invoke(params, continuation)
);
Animesh Sahu
11/12/2019, 4:10 PMelaborate tissue
11/12/2019, 5:18 PMursus
11/12/2019, 6:03 PMursus
11/12/2019, 6:28 PMaerb
11/12/2019, 7:12 PMisActive
or having a CancellationException thrown?ursus
11/12/2019, 7:12 PMjulioyg
11/13/2019, 10:45 AMcollect
is executed.
I'm trying:
launch(UI) {
flow.collect {
// i was hoping this was executed in UI
}
should that be running in the UI Dispatcher?mzgreen
11/13/2019, 11:07 AMCoroutineScope(Dispatchers.Main + job)
the order of contexts doesn’t matter and it’s the same if I call CoroutineScope(job + Dispatchers.Main)
, right?Alexjok
11/13/2019, 12:08 PMflowOf(1,2,3).collect { value -> println(value) }
It doesn't compile cause: Type mismatch: Required: FlowCollector<Int> found (Nothing) -> Unit
What i doing wrong?Justin
11/14/2019, 5:50 AMAnimesh Sahu
11/15/2019, 4:53 AMfun main() {
Foo()
}
class Foo {
val bar = Bar()
}
class Bar() {
// perform some long running tasks with some part dependent on foo
}
Case 1:
fun main = runBlocking { //this: CoroutineScope
Foo(this)
}
class Foo(scope: CoroutineScope): CoroutineScope by scope {
val bar = Bar(this)
}
class Bar(val foo: Foo): CoroutineScope by foo {
}
Case 2:
fun main = runBlocking { //this: CoroutineScope
Foo(this)
}
class Foo(scope: CoroutineScope): CoroutineScope {
override val coroutineContext = scope.coroutineContext
val bar = Bar(this)
}
class Bar(val foo: Foo): CoroutineScope {
override val coroutineContext = foo.coroutineContext
}
Case 3:
fun main() {
//just dont start coroutine here
Foo()
}
class Foo: CoroutineScope {
override val coroutineContext = Dispatchers.Default
val bar = Bar(this)
}
class Bar(foo: Foo): CoroutineScope {
override val coroutineContext = Dispatchers.Default
}
Or if there is a better way to create a coroutine driven application?Animesh Sahu
11/15/2019, 5:10 AMfun main() = runBlocking<Unit> {
launch(Dispatchers.Default) {
println("Default : I'm working in thread ${Thread.currentThread().name}")
}
launch(<http://Dispatchers.IO|Dispatchers.IO>) {
println("IO : I'm working in thread ${Thread.currentThread().name}")
}
}
Output:
Default : I'm working in thread DefaultDispatcher-worker-1
IO : I'm working in thread DefaultDispatcher-worker-3
louiscad
11/15/2019, 3:47 PM<http://Dispatchers.IO|Dispatchers.IO>
and using readText()
or readBytes()
, but this still blocks a thread while we are waiting for storage and not the CPU.breandan
11/15/2019, 7:09 PMMark
11/16/2019, 7:03 AMprivate lateinit var deferredFactory: Deferred<MyFactory>
suspend fun getMyFactory(): MyFactory = withContext(Dispatchers.Main) {
if (::deferredFactory.isInitialized) {
return@withContext deferredFactory.await()
}
val deferred = CompletableDeferred<MyFactory>().apply {
deferredFactory = this
}
createFactory().also {
deferred.complete(it)
}
}
private suspend fun createFactory() = withContext(Dispatchers.Default) {
// slow stuff
}
=== UPDATE ===
After all the comments, this is what we came up with:
private val deferredFactory = GlobalScope.async(start = CoroutineStart.LAZY) {
createFactory()
}
suspend fun getFactoryOrNull() =
try {
deferredFactory.await()
} catch (e: Exception) {
//loge("unable to create factory", e)
null
}
uli
11/16/2019, 2:37 PMSrSouza
11/16/2019, 4:34 PMHexa
11/17/2019, 10:16 AMval one = GlobalScope.async(start = CoroutineStart.LAZY) { A() }
val two = GlobalScope.async(start = CoroutineStart.LAZY) { B() }
one.start()
Thread.sleep(1000)
two.start()
is there a better way to wait for one
to start first before starting two
without using Thread.sleep in between?Animesh Sahu
11/18/2019, 3:34 PMAnimesh Sahu
11/18/2019, 3:34 PMgildor
11/18/2019, 3:38 PMAnimesh Sahu
11/18/2019, 3:45 PMprivate val value= AtomicReference<T>()
if (!value.compareAndSet(null, value)) {...}
vs
private var value: T? = null
if (this.value != null) {...}
zak.taccardi
11/18/2019, 5:23 PMAtomicBoolean
is thread safe by itself, but use it in an object that isn’t thread safe and your Boolean
is no longer thread safeSrSouza
11/18/2019, 9:40 PMzak.taccardi
11/18/2019, 10:35 PM