Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: cache contacts size (WPB-14523) #3259

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ fun interface CurrentClientIdProvider {
suspend operator fun invoke(): Either<CoreFailure, ClientId>
}

fun interface ContactsSizeProvider {
suspend operator fun invoke(): Either<CoreFailure, Int>
}

internal fun interface SelfTeamIdProvider {
suspend operator fun invoke(): Either<CoreFailure, TeamId?>
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ interface UserRepository {
suspend fun migrateUserToTeam(teamName: String): Either<CoreFailure, CreateUserTeam>
suspend fun updateTeamId(userId: UserId, teamId: TeamId): Either<StorageFailure, Unit>
suspend fun isClientMlsCapable(userId: UserId, clientId: ClientId): Either<StorageFailure, Boolean>
suspend fun getContactsCount(): Either<StorageFailure, Int>
}

@Suppress("LongParameterList", "TooManyFunctions")
Expand Down Expand Up @@ -319,8 +320,8 @@ internal class UserDataSource internal constructor(
userProfile = userProfileDTO,
connectionState = ConnectionEntity.State.ACCEPTED,
userTypeEntity =
if (userProfileDTO.service != null) UserTypeEntity.SERVICE
else userTypeEntityMapper.teamRoleCodeToUserType(mapTeamMemberDTO[userProfileDTO.id.value]?.permissions?.own)
if (userProfileDTO.service != null) UserTypeEntity.SERVICE
else userTypeEntityMapper.teamRoleCodeToUserType(mapTeamMemberDTO[userProfileDTO.id.value]?.permissions?.own)
)
}
val otherUsers = listUserProfileDTO
Expand Down Expand Up @@ -602,6 +603,10 @@ internal class UserDataSource internal constructor(
clientDAO.isMLSCapable(userId.toDao(), clientId.value)
}

override suspend fun getContactsCount(): Either<StorageFailure, Int> = wrapStorageRequest {
userDAO.getContactsCount()
}

companion object {

internal const val BATCH_SIZE = 500
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ import com.wire.kalium.logic.data.event.EventDataSource
import com.wire.kalium.logic.data.event.EventRepository
import com.wire.kalium.logic.data.featureConfig.FeatureConfigDataSource
import com.wire.kalium.logic.data.featureConfig.FeatureConfigRepository
import com.wire.kalium.logic.data.id.ContactsSizeProvider
import com.wire.kalium.logic.data.id.CurrentClientIdProvider
import com.wire.kalium.logic.data.id.FederatedIdMapper
import com.wire.kalium.logic.data.id.GroupID
Expand Down Expand Up @@ -498,6 +499,7 @@ class UserSessionScope internal constructor(
)

private var _clientId: ClientId? = null
private var _contactsSize: Int? = null

@OptIn(DelicateKaliumApi::class) // Use the uncached client ID in order to create the cache itself.
private suspend fun clientId(): Either<CoreFailure, ClientId> =
Expand All @@ -507,6 +509,13 @@ class UserSessionScope internal constructor(
}
}

private suspend fun contactsSize(): Either<CoreFailure, Int> =
if (_contactsSize != null) Either.Right(_contactsSize!!) else {
userRepository.getContactsCount().onSuccess {
_contactsSize = it
}
}

private val userScopedLogger: KaliumLogger = kaliumLogger.withUserDeviceData {
KaliumLogger.UserClientData(userId.toLogString(), _clientId?.value?.obfuscateId() ?: "")
}
Expand All @@ -527,6 +536,8 @@ class UserSessionScope internal constructor(
)

val clientIdProvider = CurrentClientIdProvider { clientId() }
val contactsSizeProvider = ContactsSizeProvider { contactsSize() }

private val mlsSelfConversationIdProvider: MLSSelfConversationIdProvider by lazy {
MLSSelfConversationIdProviderImpl(
conversationRepository
Expand Down Expand Up @@ -1204,19 +1215,25 @@ class UserSessionScope internal constructor(
callRepository
)

internal val keyPackageManager: KeyPackageManager = KeyPackageManagerImpl(featureSupport,
internal val keyPackageManager: KeyPackageManager = KeyPackageManagerImpl(
featureSupport,
incrementalSyncRepository,
lazy { clientRepository },
lazy { client.refillKeyPackages },
lazy { client.mlsKeyPackageCountUseCase },
lazy { users.timestampKeyRepository })
internal val keyingMaterialsManager: KeyingMaterialsManager = KeyingMaterialsManagerImpl(featureSupport,
lazy { users.timestampKeyRepository }
)

internal val keyingMaterialsManager: KeyingMaterialsManager = KeyingMaterialsManagerImpl(
featureSupport,
incrementalSyncRepository,
lazy { clientRepository },
lazy { conversations.updateMLSGroupsKeyingMaterials },
lazy { users.timestampKeyRepository })
lazy { users.timestampKeyRepository }
)

val mlsClientManager: MLSClientManager = MLSClientManagerImpl(clientIdProvider,
val mlsClientManager: MLSClientManager = MLSClientManagerImpl(
clientIdProvider,
isAllowedToRegisterMLSClient,
incrementalSyncRepository,
lazy { slowSyncRepository },
Expand All @@ -1225,7 +1242,8 @@ class UserSessionScope internal constructor(
RegisterMLSClientUseCaseImpl(
mlsClientProvider, clientRepository, keyPackageRepository, keyPackageLimitsProvider, userConfigRepository
)
})
}
)

internal val mlsMigrationWorker
get() =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ CREATE TABLE User (
);
CREATE INDEX user_team_index ON User(team);
CREATE INDEX user_service_id ON User(bot_service);
CREATE INDEX idx_user_connection_status_accepted ON User (connection_status) WHERE connection_status = 'ACCEPTED';

deleteUser:
DELETE FROM User WHERE qualified_id = ?;
Expand Down Expand Up @@ -280,3 +281,7 @@ UPDATE User SET team = ? WHERE qualified_id = ?;
selectNameByMessageId:
SELECT name FROM User
WHERE qualified_id = (SELECT Message.sender_user_id FROM Message WHERE Message.id = :messageId AND Message.conversation_id = :conversationId);

getContactsCount:
SELECT COUNT(*)
FROM User WHERE connection_status == 'ACCEPTED';
1 change: 1 addition & 0 deletions persistence/src/commonMain/db_user/migrations/99.sqm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE INDEX idx_user_connection_status_accepted ON User (connection_status) WHERE connection_status = 'ACCEPTED';
Original file line number Diff line number Diff line change
Expand Up @@ -317,4 +317,5 @@ interface UserDAO {
suspend fun getUsersMinimizedByQualifiedIDs(qualifiedIDs: List<QualifiedIDEntity>): List<UserEntityMinimized>
suspend fun getNameAndHandle(userId: UserIDEntity): NameAndHandleEntity?
suspend fun updateTeamId(userId: UserIDEntity, teamId: String)
suspend fun getContactsCount(): Int?
}
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,12 @@ class UserDAOImpl internal constructor(
}

override suspend fun updateTeamId(userId: UserIDEntity, teamId: String) {
userQueries.updateTeamId(teamId, userId)
withContext(queriesContext) {
userQueries.updateTeamId(teamId, userId)
}
}

override suspend fun getContactsCount(): Int? = withContext(queriesContext) {
userQueries.getContactsCount().executeAsOneOrNull()?.toInt()
}
}
Loading