This commit is contained in:
@@ -20,7 +20,7 @@ Done!
|
|||||||
License agreement page for subscription vs perpetual
|
License agreement page for subscription vs perpetual
|
||||||
("Quickly, quickly, there's no time" must use a new format as this is a subscription "SERVICE" not a software product so maybe look at quickbooks license or service agreement I guess it would be called)
|
("Quickly, quickly, there's no time" must use a new format as this is a subscription "SERVICE" not a software product so maybe look at quickbooks license or service agreement I guess it would be called)
|
||||||
Must be clear customer is responsible for their data and must remain within reasonable usage levels or we will cancel the service
|
Must be clear customer is responsible for their data and must remain within reasonable usage levels or we will cancel the service
|
||||||
|
TODO: must change the "View license agreement" link in About form to "View service agreement" and use Service agreement text to describe it
|
||||||
|
|
||||||
- Launch a trialing server, can start small and work up but keep all users on it so to save money and not any of our own corporate infrastructure servers
|
- Launch a trialing server, can start small and work up but keep all users on it so to save money and not any of our own corporate infrastructure servers
|
||||||
"All free trial subscriptions are located in New York data center. Paid subscriptions can be in any of the following data centers of your choice ...blah blah blah."
|
"All free trial subscriptions are located in New York data center. Paid subscriptions can be in any of the following data centers of your choice ...blah blah blah."
|
||||||
|
|||||||
@@ -99,7 +99,20 @@ namespace AyaNova.Api.Controllers
|
|||||||
return Ok(ApiOkResponse.Response(await JobsBiz.GetJobStatusAsync(gid)));
|
return Ok(ApiOkResponse.Response(await JobsBiz.GetJobStatusAsync(gid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get current job status and progress for a job
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="gid"></param>
|
||||||
|
/// <returns>A single job's current status and progress</returns>
|
||||||
|
[HttpGet("progress/{gid}")]
|
||||||
|
public async Task<IActionResult> GetJobProgress([FromRoute] Guid gid)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
return BadRequest(new ApiErrorResponse(ModelState));
|
||||||
|
return Ok(ApiOkResponse.Response(await JobsBiz.GetJobProgressAsync(gid)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -240,6 +253,23 @@ namespace AyaNova.Api.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Request cancellation of Job. Not all jobs can be cancelled.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="gid"></param>
|
||||||
|
/// <returns>Accepted</returns>
|
||||||
|
[HttpPost("request-cancel/{gid}")]
|
||||||
|
public async Task<IActionResult> RequestCancelJob([FromRoute] Guid gid)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
return BadRequest(new ApiErrorResponse(ModelState));
|
||||||
|
|
||||||
|
await JobsBiz.RequestCancelAsync(gid);
|
||||||
|
return Accepted();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------
|
//------------
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -596,10 +596,29 @@ namespace AyaNova.Biz
|
|||||||
else
|
else
|
||||||
idList = await ct.Customer.AsNoTracking().Select(z => z.Id).ToListAsync();
|
idList = await ct.Customer.AsNoTracking().Select(z => z.Id).ToListAsync();
|
||||||
bool SaveIt = false;
|
bool SaveIt = false;
|
||||||
|
|
||||||
|
//case 4192
|
||||||
|
TimeSpan ProgressAndCancelCheckSpan = new TimeSpan(0, 0, ServerBootConfig.JOB_PROGRESS_UPDATE_AND_CANCEL_CHECK_SECONDS);
|
||||||
|
DateTime LastProgressCheck = DateTime.UtcNow.Subtract(new TimeSpan(1, 1, 1, 1, 1));
|
||||||
|
var TotalRecords = idList.LongCount();
|
||||||
|
long CurrentRecord = -1;
|
||||||
|
|
||||||
|
|
||||||
foreach (long id in idList)
|
foreach (long id in idList)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
//Update progress / cancel requested?
|
||||||
|
CurrentRecord++;
|
||||||
|
if (DateUtil.IsAfterDuration(LastProgressCheck, ProgressAndCancelCheckSpan))
|
||||||
|
{
|
||||||
|
await JobsBiz.UpdateJobProgressAsync(job.GId, $"{CurrentRecord}/{TotalRecords}");
|
||||||
|
if (await JobsBiz.GetJobStatusAsync(job.GId) == JobStatus.CancelRequested)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SaveIt = false;
|
SaveIt = false;
|
||||||
ClearErrors();
|
ClearErrors();
|
||||||
Customer o = null;
|
Customer o = null;
|
||||||
@@ -635,7 +654,7 @@ namespace AyaNova.Biz
|
|||||||
FailedObjectCount++;
|
FailedObjectCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TEMPORARY MEASURE AWAITING BETTER SOLUTION AND CANCELLABLE EXTENSION JOBS
|
//TEMPORARY MEASURE AWAITING BETTER SOLUTION AND CANCELLABLE EXTENSION JOBS
|
||||||
//delay so we're not tying up all the resources in a tight loop
|
//delay so we're not tying up all the resources in a tight loop
|
||||||
await Task.Delay(AyaNova.Util.ServerBootConfig.JOB_OBJECT_HANDLE_BATCH_JOB_LOOP_DELAY);
|
await Task.Delay(AyaNova.Util.ServerBootConfig.JOB_OBJECT_HANDLE_BATCH_JOB_LOOP_DELAY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ namespace AyaNova.Biz
|
|||||||
Sleeping = 1,
|
Sleeping = 1,
|
||||||
Running = 2,
|
Running = 2,
|
||||||
Completed = 3,
|
Completed = 3,
|
||||||
Failed = 4
|
Failed = 4,
|
||||||
|
CancelRequested = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,16 @@ namespace AyaNova.Biz
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Request the cancellation of a job, not all jobs honour this
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="jobId"></param>
|
||||||
|
internal static async Task RequestCancelAsync(Guid jobId)
|
||||||
|
{
|
||||||
|
await UpdateJobStatusAsync(jobId, JobStatus.CancelRequested);
|
||||||
|
await LogJobAsync(jobId, "LT:Cancel");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove the job and it's logs
|
/// Remove the job and it's logs
|
||||||
@@ -152,6 +162,37 @@ namespace AyaNova.Biz
|
|||||||
return o.JobStatus;
|
return o.JobStatus;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update the progress of a job
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="jobId"></param>
|
||||||
|
/// <param name="progress"></param>
|
||||||
|
internal static async Task UpdateJobProgressAsync(Guid jobId, string progress)
|
||||||
|
{
|
||||||
|
using (AyContext ct = ServiceProviderProvider.DBContext)
|
||||||
|
{
|
||||||
|
var oFromDb = await ct.OpsJob.SingleOrDefaultAsync(z => z.GId == jobId);
|
||||||
|
if (oFromDb == null) return;
|
||||||
|
oFromDb.Progress = progress;
|
||||||
|
await ct.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the progress and status of a job
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="jobId"></param>
|
||||||
|
internal static async Task<JobProgress> GetJobProgressAsync(Guid jobId)
|
||||||
|
{
|
||||||
|
using (AyContext ct = ServiceProviderProvider.DBContext)
|
||||||
|
{
|
||||||
|
var o = await ct.OpsJob.AsNoTracking().SingleOrDefaultAsync(z => z.GId == jobId);
|
||||||
|
if (o == null) return new JobProgress() { JobStatus = JobStatus.Absent, Progress = string.Empty };
|
||||||
|
return new JobProgress() { JobStatus = o.JobStatus, Progress = o.Progress };
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion Job ops
|
#endregion Job ops
|
||||||
|
|
||||||
#region PROCESSOR
|
#region PROCESSOR
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ namespace AyaNova.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string JobInfo { get; set; }//json as string of any required extra info for job
|
public string JobInfo { get; set; }//json as string of any required extra info for job
|
||||||
|
|
||||||
|
public string Progress {get;set;}//any type of text digestible by client showing progress of job, typically just a string i.e. "133/344"
|
||||||
|
|
||||||
public OpsJob()
|
public OpsJob()
|
||||||
{
|
{
|
||||||
@@ -53,6 +54,7 @@ namespace AyaNova.Models
|
|||||||
AType = AyaType.NoType;
|
AType = AyaType.NoType;
|
||||||
JobStatus = JobStatus.Sleeping;
|
JobStatus = JobStatus.Sleeping;
|
||||||
JobInfo = null;
|
JobInfo = null;
|
||||||
|
Progress=string.Empty;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
server/AyaNova/models/dto/JobProgress.cs
Normal file
26
server/AyaNova/models/dto/JobProgress.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using AyaNova.Biz;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace AyaNova.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Job Progress
|
||||||
|
/// </summary>
|
||||||
|
public class JobProgress
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Progress string
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>string</returns>
|
||||||
|
public string Progress { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Status of the job
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Job status</returns>
|
||||||
|
public JobStatus JobStatus { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,9 +20,9 @@ namespace AyaNova.Util
|
|||||||
/////////// CHANGE THIS ON NEW SCHEMA UPDATE ////////////////////
|
/////////// CHANGE THIS ON NEW SCHEMA UPDATE ////////////////////
|
||||||
|
|
||||||
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImportingAsync WHEN NEW TABLES ADDED!!!!
|
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImportingAsync WHEN NEW TABLES ADDED!!!!
|
||||||
private const int DESIRED_SCHEMA_LEVEL = 7;
|
private const int DESIRED_SCHEMA_LEVEL = 8;
|
||||||
|
|
||||||
internal const long EXPECTED_COLUMN_COUNT = 1377;
|
internal const long EXPECTED_COLUMN_COUNT = 1378;
|
||||||
internal const long EXPECTED_INDEX_COUNT = 161;
|
internal const long EXPECTED_INDEX_COUNT = 161;
|
||||||
internal const long EXPECTED_CHECK_CONSTRAINTS = 561;
|
internal const long EXPECTED_CHECK_CONSTRAINTS = 561;
|
||||||
internal const long EXPECTED_FOREIGN_KEY_CONSTRAINTS = 204;
|
internal const long EXPECTED_FOREIGN_KEY_CONSTRAINTS = 204;
|
||||||
@@ -1571,6 +1571,21 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 8.0.13 additions for job feedback
|
||||||
|
//
|
||||||
|
if (currentSchema < 8)
|
||||||
|
{
|
||||||
|
LogUpdateMessage(log);
|
||||||
|
|
||||||
|
await ExecQueryAsync("ALTER TABLE aopsjob ADD column progress TEXT");
|
||||||
|
|
||||||
|
await SetSchemaLevelAsync(++currentSchema);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//#########################################
|
//#########################################
|
||||||
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
|
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
@@ -15,7 +16,7 @@ namespace AyaNova.Util
|
|||||||
//STATIC HARD CODED COMPILE TIME DEFAULTS NOT SET THROUGH CONFIG
|
//STATIC HARD CODED COMPILE TIME DEFAULTS NOT SET THROUGH CONFIG
|
||||||
internal const int FAILED_AUTH_DELAY = 3000;//ms
|
internal const int FAILED_AUTH_DELAY = 3000;//ms
|
||||||
internal const int JOB_OBJECT_HANDLE_BATCH_JOB_LOOP_DELAY = 200;//ms this delay is a temporary measure to ensure super big time consuming batch jobs don't use all server CPU resources
|
internal const int JOB_OBJECT_HANDLE_BATCH_JOB_LOOP_DELAY = 200;//ms this delay is a temporary measure to ensure super big time consuming batch jobs don't use all server CPU resources
|
||||||
|
internal const int JOB_PROGRESS_UPDATE_AND_CANCEL_CHECK_SECONDS = 15;//seconds between progress updates and checks for cancellation of long running jobs
|
||||||
|
|
||||||
//UPLOAD LIMITS 1048576 = 1MiB for testing 10737420000 10737418240 10,737,418,240
|
//UPLOAD LIMITS 1048576 = 1MiB for testing 10737420000 10737418240 10,737,418,240
|
||||||
internal const long MAX_ATTACHMENT_UPLOAD_BYTES = 10737420000;//slight bit of overage as 10737418241=10GiB
|
internal const long MAX_ATTACHMENT_UPLOAD_BYTES = 10737420000;//slight bit of overage as 10737418241=10GiB
|
||||||
|
|||||||
Reference in New Issue
Block a user