This commit is contained in:
2020-05-16 23:02:16 +00:00
parent 933b5ce459
commit 4ea7f3ff9a
6 changed files with 80 additions and 20 deletions

View File

@@ -70,9 +70,10 @@ namespace AyaNova.Api.Controllers
}
/////////////////////////////////
/////////////////////////////////////////////////////////////
//BULK OPS
//
//
/// <summary>
/// Bulk add tags to list of object id's specified
@@ -102,7 +103,6 @@ namespace AyaNova.Api.Controllers
JObject o = JObject.FromObject(new
{
idList = idList,
op = "add-tag",
tag = tag
});
@@ -110,6 +110,7 @@ namespace AyaNova.Api.Controllers
j.Name = JobName;
j.ObjectType = ayaType;
j.JobType = JobType.BulkCoreBizObjectOperation;
j.SubType = JobSubType.TagAdd;
j.Exclusive = false;
j.JobInfo = o.ToString();
await JobsBiz.AddJobAsync(j, ct);
@@ -142,7 +143,6 @@ namespace AyaNova.Api.Controllers
var JobName = $"Bulk operation: Add tag \"{tag}\" on any {ayaType}";
JObject o = JObject.FromObject(new
{
op = "add-any-tag",
tag = tag
});
@@ -150,6 +150,7 @@ namespace AyaNova.Api.Controllers
j.Name = JobName;
j.ObjectType = ayaType;
j.JobType = JobType.BulkCoreBizObjectOperation;
j.SubType = JobSubType.TagAddAny;
j.Exclusive = false;
j.JobInfo = o.ToString();
await JobsBiz.AddJobAsync(j, ct);
@@ -184,8 +185,7 @@ namespace AyaNova.Api.Controllers
var JobName = $"Bulk operation: Remove tag \"{tag}\" from {ayaType} ({idList.Count} specified)";
JObject o = JObject.FromObject(new
{
idList = idList,
op = "remove-tag",
idList = idList,
tag = tag
});
@@ -193,6 +193,7 @@ namespace AyaNova.Api.Controllers
j.Name = JobName;
j.ObjectType = ayaType;
j.JobType = JobType.BulkCoreBizObjectOperation;
j.SubType = JobSubType.TagRemove;
j.Exclusive = false;
j.JobInfo = o.ToString();
await JobsBiz.AddJobAsync(j, ct);
@@ -226,13 +227,13 @@ namespace AyaNova.Api.Controllers
var JobName = $"Bulk operation: Remove tag \"{tag}\" from any {ayaType}";
JObject o = JObject.FromObject(new
{
op = "remove-any-tag",
tag = tag
});
OpsJob j = new OpsJob();
j.Name = JobName;
j.ObjectType = ayaType;
j.SubType = JobSubType.TagRemoveAny;
j.JobType = JobType.BulkCoreBizObjectOperation;
j.Exclusive = false;
j.JobInfo = o.ToString();
@@ -273,7 +274,6 @@ namespace AyaNova.Api.Controllers
JObject o = JObject.FromObject(new
{
idList = idList,
op = "replace-tag",
fromTag = fromTag,
toTag = toTag
});
@@ -282,6 +282,7 @@ namespace AyaNova.Api.Controllers
j.ObjectType = ayaType;
j.Name = JobName;
j.JobType = JobType.BulkCoreBizObjectOperation;
j.SubType = JobSubType.TagReplace;
j.Exclusive = false;
j.JobInfo = o.ToString();
await JobsBiz.AddJobAsync(j, ct);
@@ -319,7 +320,6 @@ namespace AyaNova.Api.Controllers
var JobName = $"Bulk operation: Replace tag \"{fromTag}\" with tag \"{toTag}\" on any {ayaType}";
JObject o = JObject.FromObject(new
{
op = "replace-any-tag",
fromTag = fromTag,
toTag = toTag
});
@@ -328,6 +328,7 @@ namespace AyaNova.Api.Controllers
j.Name = JobName;
j.ObjectType = ayaType;
j.JobType = JobType.BulkCoreBizObjectOperation;
j.SubType = JobSubType.TagReplaceAny;
j.Exclusive = false;
j.JobInfo = o.ToString();
await JobsBiz.AddJobAsync(j, ct);

View File

@@ -9,11 +9,25 @@ namespace AyaNova.Biz
{
NotSet = 0,
TestWidgetJob = 1,//test job for unit testing
CoreJobSweeper = 2,
CoreJobSweeper = 2,
SeedTestData = 4,
BulkCoreBizObjectOperation = 5
}
/// <summary>
/// SubTypes for jobs that have further distinctions
/// </summary>
public enum JobSubType : int
{
NotSet = 0,
TagAdd = 1,
TagAddAny = 2,
TagRemove = 4,
TagRemoveAny = 5,
TagReplace = 6,
TagReplaceAny = 7
}
}//eons

View File

@@ -396,8 +396,11 @@ namespace AyaNova.Biz
/// <returns></returns>
internal static async Task ProcessJobAsync(OpsJob job, AyContext ct)
{
var JobDescription = $"{job.Name} {job.JobType.ToString()}";
if (job.SubType!=JobSubType.NotSet)
JobDescription += $":{job.SubType}";
log.LogDebug($"ProcessJobAsync -> Processing job {job.Name} (type {job.JobType.ToString()})");
log.LogDebug($"ProcessJobAsync -> Processing job {JobDescription}");
IJobObject o = null;
switch (job.JobType)
@@ -408,7 +411,9 @@ namespace AyaNova.Biz
case JobType.SeedTestData:
o = (IJobObject)BizObjectFactory.GetBizObject(AyaType.TrialSeeder, ct);
break;
case JobType.BulkCoreBizObjectOperation:
case JobType.BulkCoreBizObjectOperation:
//bulk op, hand off to biz object to deal with
//note, convention is that there is an idList in job.jobinfo json if preselected else it's all objects of type
o = (IJobObject)BizObjectFactory.GetBizObject(job.ObjectType, ct);
break;
default:
@@ -416,7 +421,7 @@ namespace AyaNova.Biz
}
await o.HandleJobAsync(job);
log.LogDebug($"ProcessJobAsync -> Job completed {job.Name} (type {job.JobType.ToString()})");
log.LogDebug($"ProcessJobAsync -> Job completed {JobDescription}");
}

View File

@@ -4,6 +4,8 @@ using EnumsNET;
using AyaNova.Util;
using AyaNova.Api.ControllerHelpers;
using AyaNova.Models;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
namespace AyaNova.Biz
{
@@ -42,7 +44,7 @@ namespace AyaNova.Biz
if (HasErrors)
return null;
else
{
{
newObject.Tags = TagBiz.NormalizeTags(newObject.Tags);
newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields);
await ct.Widget.AddAsync(newObject);
@@ -173,7 +175,7 @@ namespace AyaNova.Biz
//RESTART SERIAL
//
internal async Task<bool> RestartSerial(long newSerial)
{
{
using (var command = ct.Database.GetDbConnection().CreateCommand())
{
command.CommandText = $"alter table awidget alter column serial restart with {newSerial}";
@@ -286,6 +288,9 @@ namespace AyaNova.Biz
//basically any error condition during job processing should throw up an exception if it can't be handled
switch (job.JobType)
{
case JobType.BulkCoreBizObjectOperation:
await ProcessBulkJobAsync(job);
break;
case JobType.TestWidgetJob:
await ProcessTestJobAsync(job);
break;
@@ -304,18 +309,50 @@ namespace AyaNova.Biz
var sleepTime = 30 * 1000;
//Simulate a long running job here
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Running, ct);
await JobsBiz.LogJobAsync(job.GId, $"WidgetBiz::ProcessTestJob started, sleeping for {sleepTime} seconds...", ct);
await JobsBiz.LogJobAsync(job.GId, $"Widget ProcessTestJob started, sleeping for {sleepTime} seconds...", ct);
//Uncomment this to test if the job prevents other routes from running
//result is NO it doesn't prevent other requests, so we are a-ok for now
await Task.Delay(sleepTime);
await JobsBiz.LogJobAsync(job.GId, "WidgetBiz::ProcessTestJob done sleeping setting job to finished", ct);
await JobsBiz.LogJobAsync(job.GId, "Widget ProcessTestJob done sleeping setting job to finished", ct);
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Completed, ct);
}
//Other job handlers here...
private async Task ProcessBulkJobAsync(OpsJob job)
{
//Simulate a long running job here
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Running, ct);
await JobsBiz.LogJobAsync(job.GId, $"Widget BulkJob {job.SubType} started...", ct);
List<long> idList = new List<long>();
JObject jobData = JObject.Parse(job.JobInfo);
if (jobData.ContainsKey("idList"))
{
idList = jobData["idList"].Value<List<long>>();
}
else{
//we need to fetch a list of them all because ALL items was selected
}
var seedLevel = (Seeder.SeedLevel)jobData["seedLevel"].Value<int>();
var timeZoneOffset = jobData["timeZoneOffset"].Value<decimal>();
//either process an id list or fetch all objects and process
//call out processor for each item in turn
switch (job.SubType)
{
case JobSubType.TagAdd:
}
await JobsBiz.LogJobAsync(job.GId, $"Widget BulkJob {job.SubType} completed", ct);
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Completed, ct);
}
/////////////////////////////////////////////////////////////////////

View File

@@ -17,7 +17,7 @@ namespace AyaNova.Models
public DateTime Created { get; set; }
public uint Concurrency { get; set; }
[Required]
public string Name { get; set; }
@@ -27,10 +27,12 @@ namespace AyaNova.Models
public DateTime StartAfter { get; set; }
[Required]
public JobType JobType { get; set; }
public JobSubType SubType { get; set; }
public long ObjectId { get; set; }
public AyaType ObjectType { get; set; }
[Required]
public JobStatus JobStatus { get; set; }
/// <summary>
/// Json string of any required extra info for job
/// </summary>
@@ -45,6 +47,7 @@ namespace AyaNova.Models
Exclusive = false;
StartAfter = Created;
JobType = JobType.NotSet;
SubType = JobSubType.NotSet;
ObjectId = 0;
ObjectType = AyaType.NoType;
JobStatus = JobStatus.Sleeping;

View File

@@ -22,7 +22,7 @@ namespace AyaNova.Util
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
private const int DESIRED_SCHEMA_LEVEL = 11;
internal const long EXPECTED_COLUMN_COUNT = 305;
internal const long EXPECTED_COLUMN_COUNT = 306;
internal const long EXPECTED_INDEX_COUNT = 134;
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
@@ -270,7 +270,7 @@ namespace AyaNova.Util
LogUpdateMessage(log);
await ExecQueryAsync("CREATE TABLE aopsjob (gid uuid PRIMARY KEY, name text not null, created timestamp not null, exclusive bool not null, " +
"startafter timestamp not null, jobtype integer not null, objectid bigint null, objecttype integer null, jobstatus integer not null, jobinfo text null)");
"startafter timestamp not null, jobtype integer not null, subtype integer null, objectid bigint null, objecttype integer null, jobstatus integer not null, jobinfo text null)");
await ExecQueryAsync("CREATE TABLE aopsjoblog (gid uuid PRIMARY KEY, jobid uuid not null REFERENCES aopsjob (gid), created timestamp not null, statustext text not null)");
await SetSchemaLevelAsync(++currentSchema);