You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

task.go 2.8 kB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package task
  2. import (
  3. "code.gitea.io/gitea/models"
  4. "code.gitea.io/gitea/modules/log"
  5. "code.gitea.io/gitea/modules/redis/redis_key"
  6. "code.gitea.io/gitea/modules/redis/redis_lock"
  7. "code.gitea.io/gitea/modules/util"
  8. "code.gitea.io/gitea/services/reward"
  9. "code.gitea.io/gitea/services/reward/limiter"
  10. "fmt"
  11. "time"
  12. )
  13. func Accomplish(userId int64, taskType string, sourceId string) {
  14. go accomplish(userId, taskType, sourceId)
  15. }
  16. func accomplish(userId int64, taskType string, sourceId string) error {
  17. defer func() {
  18. if err := recover(); err != nil {
  19. combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2))
  20. log.Error("PANIC:%v", combinedErr)
  21. }
  22. }()
  23. //lock
  24. var taskLock = redis_lock.NewDistributeLock(redis_key.TaskAccomplishLock(sourceId, taskType))
  25. isOk, err := taskLock.Lock(3 * time.Second)
  26. if err != nil {
  27. log.Error("get taskLock error. %v", err)
  28. return err
  29. }
  30. if !isOk {
  31. log.Info("duplicated task request,userId=%d taskType=%s sourceId=%s", userId, taskType, sourceId)
  32. return nil
  33. }
  34. defer taskLock.UnLock()
  35. //is handled before?
  36. isHandled, err := isHandled(taskType, sourceId)
  37. if err != nil {
  38. log.Error("Get isHandled error,%v", err)
  39. return err
  40. }
  41. if isHandled {
  42. log.Info("task has been handled,userId=%d taskType=%s sourceId=%s", userId, taskType, sourceId)
  43. return nil
  44. }
  45. //get task config
  46. config, err := GetTaskConfig(taskType)
  47. if err != nil {
  48. log.Error("GetTaskConfig error,%v", err)
  49. return err
  50. }
  51. if config == nil {
  52. log.Info("task config not exist,userId=%d taskType=%s sourceId=%s", userId, taskType, sourceId)
  53. return nil
  54. }
  55. //is limited?
  56. if isLimited(userId, config) {
  57. log.Info("task accomplish maximum times are reached,userId=%d taskType=%s sourceId=%s", userId, taskType, sourceId)
  58. return nil
  59. }
  60. //add log
  61. logId := util.UUID()
  62. _, err = models.InsertTaskAccomplishLog(&models.TaskAccomplishLog{
  63. LogId: logId,
  64. ConfigId: config.ID,
  65. TaskCode: config.TaskCode,
  66. UserId: userId,
  67. SourceId: sourceId,
  68. })
  69. if err != nil {
  70. return err
  71. }
  72. //reward
  73. reward.Send(models.RewardOperateContext{
  74. SourceType: models.SourceTypeAccomplishTask,
  75. SourceId: logId,
  76. Reward: models.Reward{
  77. Amount: config.AwardAmount,
  78. Type: config.AwardType,
  79. },
  80. TargetUserId: userId,
  81. RequestId: logId,
  82. OperateType: models.OperateTypeIncrease,
  83. })
  84. return nil
  85. }
  86. func isHandled(taskType string, sourceId string) (bool, error) {
  87. _, err := models.GetTaskAccomplishLogBySourceIdAndTaskCode(sourceId, taskType)
  88. if err != nil {
  89. if models.IsErrRecordNotExist(err) {
  90. return false, nil
  91. }
  92. return false, err
  93. }
  94. return true, nil
  95. }
  96. func isLimited(userId int64, config *models.TaskConfig) bool {
  97. if err := limiter.CheckLimit(config.TaskCode, models.LimitTypeTask, userId, 1); err != nil {
  98. return true
  99. }
  100. return false
  101. }