|
- package task
-
- import (
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/redis/redis_key"
- "code.gitea.io/gitea/modules/redis/redis_lock"
- "code.gitea.io/gitea/services/reward"
- "errors"
- "time"
- )
-
- func Accomplish(userId int64, taskType models.TaskType, sourceId string) {
- go accomplish(userId, taskType, sourceId)
- }
-
- func accomplish(userId int64, taskType models.TaskType, sourceId string) error {
- //lock
- var taskLock = redis_lock.NewDistributeLock(redis_key.TaskAccomplishLock(userId, sourceId, taskType))
- if !taskLock.Lock(3 * time.Second) {
- log.Info("duplicated task request,userId=%d taskType=%s sourceId=%s", userId, taskType, sourceId)
- return nil
- }
- defer taskLock.UnLock()
-
- //is handled before?
- isHandled, err := isHandled(taskType, sourceId)
- if err != nil {
- log.Error("Get isHandled error,%v", err)
- return err
- }
- if isHandled {
- log.Info("task has been handled,userId=%d taskType=%s sourceId=%s", userId, taskType, sourceId)
- return nil
- }
-
- //get task config
- config, err := GetTaskConfig(taskType)
- if err != nil {
- log.Error("GetTaskConfig error,%v", err)
- return err
- }
- if config == nil {
- log.Info("task config not exist,userId=%d taskType=%s sourceId=%s", userId, taskType, sourceId)
- return nil
- }
-
- //is limited?
- isLimited, err := IsLimited(userId, config)
- if err != nil {
- log.Error("get limited error,%v", err)
- return err
- }
- if isLimited {
- log.Info("task accomplish maximum times are reached,userId=%d taskType=%s sourceId=%s", userId, taskType, sourceId)
- return nil
- }
-
- //add log
- models.InsertTaskAccomplishLog(&models.TaskAccomplishLog{
- ConfigId: config.ID,
- TaskCode: config.TaskCode,
- UserId: userId,
- SourceId: sourceId,
- })
-
- //reward
- reward.Send(reward.RewardOperateContext{
- SourceType: models.SourceTypeAccomplishTask,
- SourceId: sourceId,
- Reward: reward.Reward{
- Amount: config.AwardAmount,
- Type: config.AwardType,
- },
- TargetUserId: userId,
- })
-
- return nil
- }
-
- func isHandled(taskType models.TaskType, sourceId string) (bool, error) {
- _, err := models.GetTaskAccomplishLogBySourceIdAndTaskCode(sourceId, taskType.String())
- if err != nil {
- if models.IsErrRecordNotExist(err) {
- return false, nil
- }
- return false, err
- }
- return true, nil
-
- }
-
- func IsLimited(userId int64, config *models.TaskConfig) (bool, error) {
- limiter := GetLimiter(config.RefreshRate)
- if limiter == nil {
- return false, errors.New("task config incorrect")
- }
- n, err := models.CountOnceTask(config.ID, userId, limiter.GetCurrentPeriod())
- if err != nil {
- return false, err
- }
- return n >= config.Times, nil
-
- }
|