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

Fix getMemberOrNull and getGuildMembers caching only user data #964

Merged
merged 2 commits into from
Aug 11, 2024

Conversation

Galarzaa90
Copy link
Contributor

As reported in Discord, these calls are storing the results to the user cache, so subsequent calls would not find them from cache.

When using cacheWithCachingRestFallback, this results in REST calls being made every single time to get members, unless they got cached from a gateway event.

@lukellmann
Copy link
Member

You want to store both UserData and MemberData, see GuildEventHandler. I think it needs some extra logic (storeAndReturn and storeOnEach won't suffice if I'm not wrong).

@Galarzaa90
Copy link
Contributor Author

Galarzaa90 commented Aug 11, 2024

You want to store both UserData and MemberData, see GuildEventHandler. I think it needs some extra logic (storeAndReturn and storeOnEach won't suffice if I'm not wrong).

For getMemberOrNull this could work:

override suspend fun getMemberOrNull(guildId: Snowflake, userId: Snowflake): Member? {
    return storeAndReturn(supplier.getMemberOrNull(guildId, userId)) {
        cache.put(it.data)
        it.memberData
    }
}

or without storeAndReturns, so it doesn't look "hacky":

override suspend fun getMemberOrNull(guildId: Snowflake, userId: Snowflake): Member? {
    return supplier.getMemberOrNull(guildId, userId)?.also { 
        cache.put(it.data)
        cache.put(it.memberData)
    }
}

For getGuildMembers, that won't work because cache.put is a suspend function and the transform on storeOnEach is crossinline.

Should additional utility functions be added for these single uses?

Alternative for getGuildMembers:

override fun getGuildMembers(guildId: Snowflake, limit: Int?): Flow<Member> {
    return supplier.getGuildMembers(guildId, limit).onEach { 
        cache.put(it.data)
        cache.put(it.memberData)
    }
}

@lukellmann
Copy link
Member

or without storeAndReturns, so it doesn't look "hacky":

override suspend fun getMemberOrNull(guildId: Snowflake, userId: Snowflake): Member? {
    return supplier.getMemberOrNull(guildId, userId)?.also { 
        cache.put(it.data)
        cache.put(it.memberData)
    }
}

Yes, I'd prefer something like this.

For getGuildMembers, that won't work because cache.put is a suspend function and the transform on storeOnEach is crossinline.

Should additional utility functions be added for these single uses?

Alternative for getGuildMembers:

override fun getGuildMembers(guildId: Snowflake, limit: Int?): Flow<Member> {
    return supplier.getGuildMembers(guildId, limit).onEach { 
        cache.put(it.data)
        cache.put(it.memberData)
    }
}

I think we don't need an extra function and make it complicated, keeping it simple with something like your alternative should be fine.

Note that in both cases using an expression body function and a named lambda parameter instead of it might be slightly more readable IMHO.

@Galarzaa90
Copy link
Contributor Author

Changes applied

Copy link
Member

@lukellmann lukellmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks :)

@lukellmann lukellmann merged commit 2be545a into kordlib:main Aug 11, 2024
3 checks passed
@lukellmann lukellmann changed the title Fix getMemberOrNull and getGuildMembers caching user data instead of member data Fix getMemberOrNull and getGuildMembers caching only user data Aug 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants