https://kotlinlang.org logo
Title
m

Marc Knaup

10/10/2020, 6:58 PM
Is using
AtomicRef
and
Deferred
a good approach to ensure that concurrent calls to
update()
never cause more than one
updateAsync()
execution in parallel? For example let’s say
updateAsync()
execution takes 10 seconds and there are 4 calls to
update()
with 2 seconds in between.
updateAsync()
would only be called once and they all share the same result, right?
d

Dominaezzz

10/10/2020, 7:35 PM
The code you have might call
updateAsync()
multiple times. (Unless it's just an illustration then nvm). The function pass to
updateAndGet
should be pure.
Instead of
AtomicRef
, I think you should use a
Semaphore
.
m

Marc Knaup

10/10/2020, 7:49 PM
What do you mean by pure?
d

Dominaezzz

10/10/2020, 7:50 PM
Without side effect. As the lambda could be executed multiple times.
m

Marc Knaup

10/10/2020, 7:51 PM
Oh, really. Damn. It launches a coroutine 😅
d

Dominaezzz

10/10/2020, 7:52 PM
Haha yeah. You could have 8 `updateAsync()`s running concurrently without it's result being consumed.
m

Marc Knaup

10/10/2020, 7:52 PM
I guess I have to fall back to a
Mutex
then?
Mutex
basically seems to be a
Semaphore
with
permits = 1
, doesn’t it?
d

Dominaezzz

10/10/2020, 7:54 PM
It is but
Semaphore
was quite recently optimised and currently performs better than
Mutex
. (I checked this a month ago, not sure if
Mutex
has been updated since).
m

Marc Knaup

10/10/2020, 7:55 PM
Interesting. Thanks for the heads ups 🙂
c

Casey Brooks

10/12/2020, 2:26 PM
What’s the intention here? Is it that if
updateAsync
is running that it won’t try to update again? Or that new updates cancel/replace the previous one? There are a handful of things you can do with Channels or Flows that can solve both those cases pretty elegantly
m

Marc Knaup

10/12/2020, 2:41 PM
New update requests should join the current pending update. I’ve already rewritten it as a Flow 🙂
d

Dominaezzz

10/12/2020, 2:58 PM
If you've got time or can be bothered. Can you share the rewrite? I can't imagine how this can be rewritten with a
Flow
.
m

Marc Knaup

10/12/2020, 3:00 PM
It’s merged with other functionality by now, esp. caching. So the behavior has changed slightly which makes it work with Flows 🙂
It now comes close to something like
flow { while(true) { emit(update()); delay(refreshInterval) } }.stateIn(…)
d

Dominaezzz

10/12/2020, 3:15 PM
Ah,
stateIn
off course, that makes a lot of sense.