yuzd / Hangfire.HttpJob

httpjob for Hangfire,restful api for Hangfire,job调度与业务分离
https://github.com/yuzd/Hangfire.HttpJob/wiki
MIT License
626 stars 185 forks source link

请帮忙解释下这两个属性的作用是啥? #99

Closed ghwillbe closed 3 years ago

ghwillbe commented 3 years ago

JobStorageConfig Class

  1. public int? ExpireAtDays { get; set; }
  2. public TimeSpan? ExpireAt { get; set; }

我在测试过程发现,在创建JobAgent实例时,注入的service没有重新实例化(DbContext有tracking的数据), 我想是不是和这两个参数有关系,还请帮忙解答下,谢谢~

yuzd commented 3 years ago

jobagent默认是单例,可以看wiki介绍。 这两个参数是设置storage存储的过期时间的。

ghwillbe commented 3 years ago

恩,我知道jobagent是默认单例。 正常来说,一段http请求结束,context会dispose掉,因为这个线程没有人使用。 但httpjob的请求不会,每一次启动jobagent,context tracking的数据也会叠加。不知道是否我的问题还是httpjob需要哪里设置: 我贴一下我代码的结构:

public class SyncEmployeeDataAgent : JobAgent
    {
        private readonly ILogger _logger;
        private readonly ISyncEmployeeDataJob _syncEmpDataJob;
        public SyncEmployeeDataAgent(
            ILogger<SyncEmployeeDataAgent> logger,
            ISyncEmployeeDataJob syncEmpDataJob
        )
        {
            this._logger = logger;
            this._syncEmpDataJob = syncEmpDataJob;
        }

        public override async Task OnStart(JobContext jobContext)
        {
            await Task.Run(() =>
            {
                this._syncEmpDataJob.SyncEmployeeData();
            });
        }
    }
public class SyncEmployeeDataJob : ISyncEmployeeDataJob {
        private readonly IConfiguration _configuration;
        private readonly ILogger _logger;
        private readonly ICommonService _commonSrv;
        public SyncEmployeeDataJob (IConfiguration configuration, ILogger<SyncEmployeeDataJob> logger,
            ICommonService commonSrv) {
            this._configuration = configuration;
            this._logger = logger;
            this._commonSrv = commonSrv;
        }

        public void SyncEmployeeData () {
            //do something 
           // this.commonSrv.Save(entity)
        }
}

unitofwork有实现IDispose,请求结束会dispose context.

public class CommonService : BaseService, ICommonService {
        private readonly IEmployeeRepository _employeeRepository;
        public CommonService (
            IEmployeeRepository employeeRepository,
            IUnitOfWorkRepository unitOfWork) : base (unitOfWork) {
            this._employeeRepository = employeeRepository;
        }

       public void Save(entity){
           // savechange...
           this._untiOfWork.commit();
       }
}
yuzd commented 3 years ago

你是说的是 IUnitOfWorkRepository 这个 执行会叠加吗?

你可以试试看SyncEmployeeDataAgent 上面打上一个标签【TransientJob】 来排查下是否是单例造成的

JobAgent 的 OnStart 其实已经在单独的线程执行了 不需要另外开Task

方便加我qq 1877682825

ghwillbe commented 3 years ago

image
可以看到图片吗,这里我才刚刚进入到jobagent, 就显示已经有数据在tracking了,tracking的数据就是我上一次请求的数据。

yuzd commented 3 years ago

你按照我上面说的排查下,我怀疑是单例的原因造成的,如果是的话 改成多例就可以了,或者你注入进来容器,然后容器在去拿你的实例,这样即使单例也能行

ghwillbe commented 3 years ago

确认是单例的原因,谢谢。

我使用单例的原因是,我不想重复启动任务。
用容器去拿实例是一个办法,另外,如果是transient的话,是否可以加上不允许重复启动任务的功能?

yuzd commented 3 years ago

如果你想用单例的话 可以试着在 SyncEmployeeDataAgent 的构造方法里面注入 容器,然后根据容器去拿实例 这样就能保证job是单例的但是job里面用到对象是多例的。

ghwillbe commented 3 years ago

我目前也正准备这样做,谢谢啊鱼总。