utils.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package model
  2. import (
  3. "errors"
  4. "github.com/bytedance/gopkg/util/gopool"
  5. "gorm.io/gorm"
  6. "one-api/common"
  7. "sync"
  8. "time"
  9. )
  10. const (
  11. BatchUpdateTypeUserQuota = iota
  12. BatchUpdateTypeTokenQuota
  13. BatchUpdateTypeUsedQuota
  14. BatchUpdateTypeChannelUsedQuota
  15. BatchUpdateTypeRequestCount
  16. BatchUpdateTypeCount // if you add a new type, you need to add a new map and a new lock
  17. )
  18. var batchUpdateStores []map[int]int
  19. var batchUpdateLocks []sync.Mutex
  20. func init() {
  21. for i := 0; i < BatchUpdateTypeCount; i++ {
  22. batchUpdateStores = append(batchUpdateStores, make(map[int]int))
  23. batchUpdateLocks = append(batchUpdateLocks, sync.Mutex{})
  24. }
  25. }
  26. func InitBatchUpdater() {
  27. gopool.Go(func() {
  28. for {
  29. time.Sleep(time.Duration(common.BatchUpdateInterval) * time.Second)
  30. batchUpdate()
  31. }
  32. })
  33. }
  34. func addNewRecord(type_ int, id int, value int) {
  35. batchUpdateLocks[type_].Lock()
  36. defer batchUpdateLocks[type_].Unlock()
  37. if _, ok := batchUpdateStores[type_][id]; !ok {
  38. batchUpdateStores[type_][id] = value
  39. } else {
  40. batchUpdateStores[type_][id] += value
  41. }
  42. }
  43. func batchUpdate() {
  44. common.SysLog("batch update started")
  45. for i := 0; i < BatchUpdateTypeCount; i++ {
  46. batchUpdateLocks[i].Lock()
  47. store := batchUpdateStores[i]
  48. batchUpdateStores[i] = make(map[int]int)
  49. batchUpdateLocks[i].Unlock()
  50. // TODO: maybe we can combine updates with same key?
  51. for key, value := range store {
  52. switch i {
  53. case BatchUpdateTypeUserQuota:
  54. err := increaseUserQuota(key, value)
  55. if err != nil {
  56. common.SysError("failed to batch update user quota: " + err.Error())
  57. }
  58. case BatchUpdateTypeTokenQuota:
  59. err := increaseTokenQuota(key, value)
  60. if err != nil {
  61. common.SysError("failed to batch update token quota: " + err.Error())
  62. }
  63. case BatchUpdateTypeUsedQuota:
  64. updateUserUsedQuota(key, value)
  65. case BatchUpdateTypeRequestCount:
  66. updateUserRequestCount(key, value)
  67. case BatchUpdateTypeChannelUsedQuota:
  68. updateChannelUsedQuota(key, value)
  69. }
  70. }
  71. }
  72. common.SysLog("batch update finished")
  73. }
  74. func RecordExist(err error) (bool, error) {
  75. if err == nil {
  76. return true, nil
  77. }
  78. if errors.Is(err, gorm.ErrRecordNotFound) {
  79. return false, nil
  80. }
  81. return false, err
  82. }
  83. func shouldUpdateRedis(fromDB bool, err error) bool {
  84. return common.RedisEnabled && fromDB && err == nil
  85. }