Skip to content

Commit

Permalink
Changed usage of mutex with update method of mutable state flow to at…
Browse files Browse the repository at this point in the history
…omically update values of it. (#1028)
  • Loading branch information
riggaroo committed Nov 21, 2022
2 parents 321cd95 + a5f61e4 commit 6757721
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ import com.example.jetnews.utils.addOrRemove
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.flow.update

/**
* Implementation of InterestRepository that returns a hardcoded list of
Expand Down Expand Up @@ -78,9 +77,6 @@ class FakeInterestsRepository : InterestsRepository {
private val selectedPeople = MutableStateFlow(setOf<String>())
private val selectedPublications = MutableStateFlow(setOf<String>())

// Used to make suspend functions that read and update state safe to call from any thread
private val mutex = Mutex()

override suspend fun getTopics(): Result<List<InterestSection>> {
return Result.Success(topics)
}
Expand All @@ -94,26 +90,20 @@ class FakeInterestsRepository : InterestsRepository {
}

override suspend fun toggleTopicSelection(topic: TopicSelection) {
mutex.withLock {
val set = selectedTopics.value.toMutableSet()
set.addOrRemove(topic)
selectedTopics.value = set
selectedTopics.update {
it.addOrRemove(topic)
}
}

override suspend fun togglePersonSelected(person: String) {
mutex.withLock {
val set = selectedPeople.value.toMutableSet()
set.addOrRemove(person)
selectedPeople.value = set
selectedPeople.update {
it.addOrRemove(person)
}
}

override suspend fun togglePublicationSelected(publication: String) {
mutex.withLock {
val set = selectedPublications.value.toMutableSet()
set.addOrRemove(publication)
selectedPublications.value = set
selectedPublications.update {
it.addOrRemove(publication)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.withContext

/**
Expand Down Expand Up @@ -55,8 +56,6 @@ class BlockingFakePostsRepository : PostsRepository {
override fun observeFavorites(): Flow<Set<String>> = favorites

override suspend fun toggleFavorite(postId: String) {
val set = favorites.value.toMutableSet()
set.addOrRemove(postId)
favorites.value = set
favorites.update { it.addOrRemove(postId) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,22 @@ import com.example.jetnews.model.Post
import com.example.jetnews.model.PostsFeed
import com.example.jetnews.utils.addOrRemove
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.withContext

/**
* Implementation of PostsRepository that returns a hardcoded list of
* posts with resources after some delay in a background thread.
*/
@OptIn(ExperimentalCoroutinesApi::class)
class FakePostsRepository : PostsRepository {

// for now, store these in memory
private val favorites = MutableStateFlow<Set<String>>(setOf())

// Used to make suspend functions that read and update state safe to call from any thread
private val mutex = Mutex()

override suspend fun getPost(postId: String?): Result<Post> {
return withContext(Dispatchers.IO) {
Expand All @@ -68,10 +64,8 @@ class FakePostsRepository : PostsRepository {
override fun observeFavorites(): Flow<Set<String>> = favorites

override suspend fun toggleFavorite(postId: String) {
mutex.withLock {
val set = favorites.value.toMutableSet()
set.addOrRemove(postId)
favorites.value = set.toSet()
favorites.update {
it.addOrRemove(postId)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import com.example.jetnews.utils.ErrorMessage
import java.util.UUID
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
Expand Down Expand Up @@ -127,7 +126,7 @@ class HomeViewModel(

// UI state exposed to the UI
val uiState = viewModelState
.map { it.toUiState() }
.map(HomeViewModelState::toUiState)
.stateIn(
viewModelScope,
SharingStarted.Eagerly,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@

package com.example.jetnews.utils

internal fun <E> MutableSet<E>.addOrRemove(element: E) {
internal fun <E> Set<E>.addOrRemove(element: E): Set<E> {
this as MutableSet
if (!add(element)) {
remove(element)
}
return this.toSet()
}

0 comments on commit 6757721

Please sign in to comment.