Hello everyone. What is the better approach to do ...
# getting-started
f
Hello everyone. What is the better approach to do concurrent read/write to a MutableList or whatever?
• Mutex, once the operations is performed via coroutine • Semaphore • Atomicfu
c
It depends on what you want to do… If you only need a single access,
Mutex
is fine.
l
Ideally, restructure so that you don’t have to. 🙂 Shared mutable state is where all the problems come from.
3
e
it really depends on what kind of concurrent operations you have. if you have iterators that need to remain valid while other operations are happening then perhaps you need to take full copies like CopyOnWriteArrayList, or some other strategy which isn't possible with any of the above, for example
1
f
I have a object which read/write data to a bluetooth peripheral. And I want implement a queue of read/write requests. That queue is filled by suspend functions and another coroutine get the data to perform the operations.
c
Then you probably want a
Channel
instead of a list?
☝️ 3
f
Nice. With a
Channel
, can I change the order of the requests? For example: In the channel I have two requests [ A, B ] , but my repository received another request C with a higher priority. So, the channel must be [C, A, B].
c
How many priorities do you have? If it's just "high priority" and "low priority", you can just have a channel each.
l
(I’m using that exact model for a project now, though the channels are kafka topics.)
f
For now, I have three level of priority
c
Yeah, if you have 2 or 3 priorities, having a channel for each is a very simple efficient way to do it. With 4 and more it becomes a bit too messy for my liking.
e
if you have more priorities, you may need something like PriorityBlockingQueue. there's no pure Kotlin implementation that I've seen though
👀 1
f
NIce. I think is a good approach. With
Channel
, can I verify if a request exist before add a new one or replace a request already added??
c
I verify if a request exist before add a new one or replace a request already added
Why do you want to do this?
l
Generally speaking, you can’t do that with a queue. You can only add/remove at the ends.
f
Sometimes the bluetooth peripheral take a long time to answer. So I want change the requests of the queue to be transparent to the user
Generally speaking, you can’t do that with a queue. You can only add/remove at the ends.
yeahh
c
Sometimes the bluetooth peripheral take a long time to answer. So I want change the requests of the queue to be transparent to the user
You already have the priority system, right? So that's already done automatically.
You could have an actor that reads from the channels, decides whether to drop the requests, and writes the requests in another channel.
e
if you want to rewrite elements of the "queue", that forces you to guard against concurrent consumers, at which point you don't have parallel work
1
☝️ 1
l
If you want to modify an item being processed, don’t modify it in place. Make the processing enqueuing a new item that is a modified version of the old one.
f
I will try implement three channels of priority. For now, I wont remove a request added previously.
thank you for all ideas
p
Perhaps invalidating the request by setting some
expired
property on it 🤷‍♂️
f
The channels of priority works fine. But I am not getting to invalidate/drop a new request if one equal was produced but do not consumed yet.
l
A queue won’t do duplication-catching for you. If that’s something you need, you’ll need to maintain your own list. And it will get complicated. (I’m doing that now, on the sending side.)