November Happy Hour will be moved to Thursday December 5th.

GUID option for ScheduledPlugIn

Vote:
 

As of 8.5.0, there doesn't seem to be any way to set a GUID for scheduled jobs, similarly to how GUIDs can be set for e.g. content type definitions. Episerver matches a scheduled job's code with the job's data in the DB just by using the job's class name and namespace. If you change either, all the job's settings and history is lost! This actually happened to us with a critical integration job after some simple code refactoring and it was not a very nice surprise.

So I propose a GUID setting for ScheduledPlugIn:

[ScheduledPlugIn(DisplayName = "My scheduled job", GUID = "7A3B7C7F-BE79-45E4-BCC1-C18A2930572F")]

Episerver could use use the GUID for mapping the scheduled job's code and DB data, so you could freely rename/move the class.

#121865
May 19, 2015 9:34
Vote:
 

Hi,

If your scheduledjob inherits from EPiServer.BaseLibrary.Scheduling.JobBase, then you are able to set ScheduledJobId guid property. EPiServer check if your job extends JobBase and use this Id.

Did you tried this?

    [ScheduledPlugIn(DisplayName = "My scheduled job")]
    public class TestScheduledJob: JobBase
    {
        public TestScheduledJob()
        {
            this.ScheduledJobId = new Guid("7A3B7C7F-BE79-45E4-BCC1-C18A2930572F");
        }

        public override string Execute()
        {
            return string.Empty;
        }
    }
#122016
May 25, 2015 20:43
Vote:
 

Hi Grzegorz,

I have tried that and unfortunately it doesn't work. The reason is that setting ScheduledJobId for JobBase does not actually set the ID property for the ScheduledJob object. And the ID property is used when either updating or creating a new scheduled job in ScheduledJobRepository:

/// <summary>
/// Saves job information or creates a new job
/// 
/// </summary>
public virtual void Save(ScheduledJob job)
{
  if (string.IsNullOrEmpty(job.Name))
	throw new DataAbstractionException("Cannot save a job without name");
  DataSet dataSet1 = ScheduledJobRepository.DataAccess.Service().List();
  DataTable dataTable = dataSet1.Tables[0];
  DataRow row;
  if (job.ID != Guid.Empty)
  {
	row = dataTable.Select("pkID='" + job.ID.ToString() + "'")[0];
  }
  else
  {
	row = dataTable.NewRow();
	row["pkID"] = (object) Guid.NewGuid().ToString();
  }
}

In the code a newly or renamed/moved scheduled job will have ID == Guid.Empty, even though you set ScheduledJobId in ScheduledJobBase.

#122034
May 26, 2015 9:22
Vote:
 

Hi,

You are right about uage if ScheduledJobId. It's not used.

Maybe to solve your problem you could register your own version of ScheduledJobRepository with Save method overriden. Inside you will ensure that correct Id and Type was used to store the job.

public class ExtendedScheduledJobRepository : ScheduledJobRepository
    {
        internal static Injected<ServiceAccessor<SchedulerDB>> DataAccess { get; set; }

        public override void Save(ScheduledJob job)
        {
            var type = Assembly.Load(job.AssemblyName).GetType(job.TypeName, true);
            if (type.IsSubclassOf(typeof (JobBase)))
            {
                var jobBase = (JobBase) Activator.CreateInstance(type);
                var dbJob = base.Get(jobBase.ScheduledJobId);
                if (dbJob == null || dbJob.AssemblyName != job.AssemblyName  ||
                    dbJob.MethodName != job.MethodName || dbJob.TypeName != job.TypeName)
                {
                    job.ID = jobBase.ScheduledJobId;
                    var dataSet = DataAccess.Service().List();
                    var dataTable = dataSet.Tables[0];
                    var row = dataTable.NewRow();
                    row["pkID"] = (object) Guid.NewGuid().ToString();
                    row["MethodName"] = (object) job.MethodName;
                    row["fStatic"] = (object) Converter.ToIntZero((object) (bool) (job.IsStaticMethod ? 1 : 0));
                    row["TypeName"] = (object) job.TypeName;
                    row["AssemblyName"] = (object) job.AssemblyName;

                    DataAccess.Service().Save(dataSet.GetChanges());
                }
            }

            base.Save(job);
        }
    }
}

 

#122070
May 26, 2015 12:48
Vote:
 

Thanks, I suppose that could be used as a workaround until the ScheduledPlugIn attribute gets a GUID property or some other out of the box solution becomes available.

#122088
May 26, 2015 15:25
This thread is locked and should be used for reference only.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.