RefreshUserGroupCache writes the database-authoritative group into an existing user hash without changing the user's authentication version.
(userId int)
| 215 | // RefreshUserGroupCache writes the database-authoritative group into an |
| 216 | // existing user hash without changing the user's authentication version. |
| 217 | func RefreshUserGroupCache(userId int) error { |
| 218 | if !common.RedisEnabled { |
| 219 | return nil |
| 220 | } |
| 221 | if userId <= 0 { |
| 222 | return fmt.Errorf("invalid user id") |
| 223 | } |
| 224 | var authoritative User |
| 225 | if err := DB.Select("id", "auth_version", commonGroupCol).Where("id = ?", userId).First(&authoritative).Error; err != nil { |
| 226 | return err |
| 227 | } |
| 228 | // Group transitions intentionally keep the same authentication version. A |
| 229 | // refresh that read the previous group can therefore arrive after a newer |
| 230 | // refresh and still pass the auth-version fence. Re-read after every write |
| 231 | // and repair the cache when the authoritative group changed in between. |
| 232 | for range 3 { |
| 233 | if err := updateUserCacheFieldAtVersion(userId, "Group", authoritative.Group, authoritative.AuthVersion); err != nil { |
| 234 | return err |
| 235 | } |
| 236 | |
| 237 | var verified User |
| 238 | if err := DB.Select("id", "auth_version", commonGroupCol).Where("id = ?", userId).First(&verified).Error; err != nil { |
| 239 | return err |
| 240 | } |
| 241 | if verified.AuthVersion == authoritative.AuthVersion && verified.Group == authoritative.Group { |
| 242 | return nil |
| 243 | } |
| 244 | authoritative = verified |
| 245 | } |
| 246 | |
| 247 | // Preserve the freshest snapshot observed even when the row was too busy to |
| 248 | // stabilize within the bounded retries. Returning an error lets best-effort |
| 249 | // callers emit an operation-specific warning. |
| 250 | if err := updateUserCacheFieldAtVersion(userId, "Group", authoritative.Group, authoritative.AuthVersion); err != nil { |
| 251 | return err |
| 252 | } |
| 253 | return fmt.Errorf("user group changed repeatedly during cache refresh") |
| 254 | } |
| 255 | |
| 256 | func updateUserEmailCache(userId int, email string) error { |
| 257 | return updateUserCacheField(userId, "Email", email) |