Skip to content

Commit

Permalink
Gfs/cli timeout (#349)
Browse files Browse the repository at this point in the history
* Add overall processing time out for GetTags and Analyze commands

* Separate state for timed out skipped

* Update FileRecord.cs
  • Loading branch information
gfs committed May 5, 2021
1 parent b20e0a0 commit fd26fed
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 33 deletions.
6 changes: 6 additions & 0 deletions AppInspector.CLI/CLICmdOptions.cs
Expand Up @@ -43,6 +43,9 @@ public class CLIGetTagsCommandOptions : CLICommandOptions
[Option("file-timeout", Required = false, HelpText = "If set, maximum amount of time in milliseconds to allow for processing each file.", Default = 0)]
public int FileTimeOut { get; set; } = 0;

[Option("processing-timeout", Required = false, HelpText = "If set, maximum amount of time in milliseconds to allow for processing overall.", Default = 0)]
public int ProcessingTimeOut { get; set; } = 0;

[Option("single-threaded", Required = false, HelpText = "Disables parallel processing.")]
public bool SingleThread { get; set; }

Expand Down Expand Up @@ -80,6 +83,9 @@ public class CLIAnalyzeCmdOptions : CLICommandOptions
[Option("file-timeout", Required = false, HelpText = "If set, maximum amount of time in milliseconds to allow for processing each file.", Default = 0)]
public int FileTimeOut { get; set; } = 0;

[Option("processing-timeout", Required = false, HelpText = "If set, maximum amount of time in milliseconds to allow for processing overall.", Default = 0)]
public int ProcessingTimeOut { get; set; } = 0;

[Option("single-threaded", Required = false, HelpText = "Disables parallel processing.")]
public bool SingleThread { get; set; }

Expand Down
36 changes: 10 additions & 26 deletions AppInspector.CLI/Program.cs
Expand Up @@ -278,7 +278,8 @@ private static int RunGetTagsCommand(CLIGetTagsCommandOptions cliOptions)
Log = cliOptions.Log,
SingleThread = cliOptions.SingleThread,
NoShowProgress = cliOptions.NoShowProgressBar,
FileTimeOut = cliOptions.FileTimeOut
FileTimeOut = cliOptions.FileTimeOut,
ProcessingTimeOut = cliOptions.ProcessingTimeOut
});

GetTagsResult getTagsResult = command.GetResult();
Expand All @@ -290,8 +291,6 @@ private static int RunGetTagsCommand(CLIGetTagsCommandOptions cliOptions)

private static int RunAnalyzeCommand(CLIAnalyzeCmdOptions cliOptions)
{
AnalyzeResult.ExitCode exitCode = AnalyzeResult.ExitCode.CriticalError;

AnalyzeCommand command = new AnalyzeCommand(new AnalyzeOptions()
{
SourcePath = cliOptions.SourcePath ?? "",
Expand All @@ -303,20 +302,18 @@ private static int RunAnalyzeCommand(CLIAnalyzeCmdOptions cliOptions)
Log = cliOptions.Log,
SingleThread = cliOptions.SingleThread,
NoShowProgress = cliOptions.NoShowProgressBar,
FileTimeOut = cliOptions.FileTimeOut
FileTimeOut = cliOptions.FileTimeOut,
ProcessingTimeOut = cliOptions.ProcessingTimeOut
});

AnalyzeResult analyzeResult = command.GetResult();
exitCode = analyzeResult.ResultCode;
ResultsWriter.Write(analyzeResult, cliOptions);

return (int)exitCode;
return (int)analyzeResult.ResultCode;
}

private static int RunTagDiffCommand(CLITagDiffCmdOptions cliOptions)
{
TagDiffResult.ExitCode exitCode = TagDiffResult.ExitCode.CriticalError;

TagDiffCommand command = new TagDiffCommand(new TagDiffOptions()
{
SourcePath1 = cliOptions.SourcePath1 ?? "",
Expand All @@ -330,16 +327,13 @@ private static int RunTagDiffCommand(CLITagDiffCmdOptions cliOptions)
});

TagDiffResult tagDiffResult = command.GetResult();
exitCode = tagDiffResult.ResultCode;
ResultsWriter.Write(tagDiffResult, cliOptions);

return (int)exitCode;
return (int)tagDiffResult.ResultCode;
}

private static int RunTagTestCommand(CLITagTestCmdOptions cliOptions)
{
TagTestResult.ExitCode exitCode = TagTestResult.ExitCode.CriticalError;

TagTestCommand command = new TagTestCommand(new TagTestOptions()
{
SourcePath = cliOptions.SourcePath,
Expand All @@ -351,16 +345,13 @@ private static int RunTagTestCommand(CLITagTestCmdOptions cliOptions)
});

TagTestResult tagTestCommand = command.GetResult();
exitCode = tagTestCommand.ResultCode;
ResultsWriter.Write(tagTestCommand, cliOptions);

return (int)exitCode;
return (int)tagTestCommand.ResultCode;
}

private static int RunExportTagsCommand(CLIExportTagsCmdOptions cliOptions)
{
ExportTagsResult.ExitCode exitCode = ExportTagsResult.ExitCode.CriticalError;

ExportTagsCommand command = new ExportTagsCommand(new ExportTagsOptions()
{
IgnoreDefaultRules = cliOptions.IgnoreDefaultRules,
Expand All @@ -370,16 +361,13 @@ private static int RunExportTagsCommand(CLIExportTagsCmdOptions cliOptions)
});

ExportTagsResult exportTagsResult = command.GetResult();
exitCode = exportTagsResult.ResultCode;
ResultsWriter.Write(exportTagsResult, cliOptions);

return (int)exitCode;
return (int)exportTagsResult.ResultCode;
}

private static int RunVerifyRulesCommand(CLIVerifyRulesCmdOptions cliOptions)
{
VerifyRulesResult.ExitCode exitCode = VerifyRulesResult.ExitCode.CriticalError;

VerifyRulesCommand command = new VerifyRulesCommand(new VerifyRulesOptions()
{
VerifyDefaultRules = cliOptions.VerifyDefaultRules,
Expand All @@ -390,16 +378,13 @@ private static int RunVerifyRulesCommand(CLIVerifyRulesCmdOptions cliOptions)
});

VerifyRulesResult exportTagsResult = command.GetResult();
exitCode = exportTagsResult.ResultCode;
ResultsWriter.Write(exportTagsResult, cliOptions);

return (int)exitCode;
return (int)exportTagsResult.ResultCode;
}

private static int RunPackRulesCommand(CLIPackRulesCmdOptions cliOptions)
{
PackRulesResult.ExitCode exitCode = PackRulesResult.ExitCode.CriticalError;

PackRulesCommand command = new PackRulesCommand(new PackRulesOptions()
{
RepackDefaultRules = cliOptions.RepackDefaultRules,
Expand All @@ -409,10 +394,9 @@ private static int RunPackRulesCommand(CLIPackRulesCmdOptions cliOptions)
});

PackRulesResult exportTagsResult = command.GetResult();
exitCode = exportTagsResult.ResultCode;
ResultsWriter.Write(exportTagsResult, cliOptions);

return (int)exitCode;
return (int)exportTagsResult.ResultCode;
}

#endregion RunCmdsWriteResults
Expand Down
42 changes: 39 additions & 3 deletions AppInspector/Commands/AnalyzeCommand.cs
Expand Up @@ -30,6 +30,7 @@ public class AnalyzeOptions : CommandOptions
public bool TreatEverythingAsCode { get; set; } = false;
public bool NoShowProgress { get; set; } = true;
public int FileTimeOut { get; set; } = 0;
public int ProcessingTimeOut { get; set; } = 0;
}

/// <summary>
Expand All @@ -42,7 +43,8 @@ public enum ExitCode
Success = 0,
NoMatches = 1,
CriticalError = Utils.ExitCode.CriticalError, //ensure common value for final exit log mention
Canceled = 3
Canceled = 3,
TimedOut = 4
}

[JsonProperty(Order = 2, PropertyName = "resultCode")]
Expand Down Expand Up @@ -447,6 +449,8 @@ public AnalyzeResult GetResult()
AppVersion = Utils.GetVersionString()
};

var timedOut = false;

if (!_options.NoShowProgress)
{
var done = false;
Expand Down Expand Up @@ -504,7 +508,7 @@ public AnalyzeResult GetResult()
sw.Start();
_ = Task.Factory.StartNew(() =>
{
PopulateRecords(new CancellationToken(), _options, fileQueue);
DoProcessing(fileQueue);
done = true;
});

Expand All @@ -525,7 +529,7 @@ public AnalyzeResult GetResult()
}
else
{
PopulateRecords(new CancellationToken(), _options, GetFileEntries(_options));
DoProcessing(GetFileEntries(_options));
}

//wrapup result status
Expand All @@ -547,7 +551,39 @@ public AnalyzeResult GetResult()
analyzeResult.ResultCode = AnalyzeResult.ExitCode.Success;
}

if (timedOut)
{
analyzeResult.ResultCode = AnalyzeResult.ExitCode.TimedOut;
}

return analyzeResult;

void DoProcessing(IEnumerable<FileEntry> fileEntries)
{
if (_options.ProcessingTimeOut > 0)
{
using var cts = new CancellationTokenSource();
var t = Task.Run(() => PopulateRecords(cts.Token, _options, fileEntries), cts.Token);
if (!t.Wait(new TimeSpan(0, 0, 0, 0, _options.ProcessingTimeOut)))
{
timedOut = true;
WriteOnce.Error($"Processing timed out.");
cts.Cancel();
if (_metaDataHelper is not null)
{
// Populate skips for all the entries we didn't process
foreach (var entry in fileEntries.Where(x => !_metaDataHelper.Files.Any(y => x.FullPath == y.FileName)))
{
_metaDataHelper.Files.Add(new FileRecord() { AccessTime = entry.AccessTime, CreateTime = entry.CreateTime, ModifyTime = entry.ModifyTime, FileName = entry.FullPath, Status = ScanState.TimeOutSkipped });
}
}
}
}
else
{
PopulateRecords(new CancellationToken(), _options, fileEntries);
}
}
}
}
}
42 changes: 39 additions & 3 deletions AppInspector/Commands/GetTagsCommand.cs
Expand Up @@ -30,6 +30,7 @@ public class GetTagsCommandOptions : CommandOptions
public bool TreatEverythingAsCode { get; set; } = false;
public bool NoShowProgress { get; set; } = true;
public int FileTimeOut { get; set; } = 0;
public int ProcessingTimeOut { get; set; }
}

/// <summary>
Expand All @@ -42,7 +43,8 @@ public enum ExitCode
Success = 0,
NoMatches = 1,
CriticalError = Utils.ExitCode.CriticalError, //ensure common value for final exit log mention
Canceled = 3
Canceled = 3,
TimedOut = 4
}

[JsonProperty(Order = 2, PropertyName = "resultCode")]
Expand Down Expand Up @@ -444,6 +446,8 @@ public GetTagsResult GetResult()
AppVersion = Utils.GetVersionString()
};

var timedOut = false;

if (!_options.NoShowProgress)
{
var done = false;
Expand Down Expand Up @@ -501,7 +505,7 @@ public GetTagsResult GetResult()
sw.Start();
_ = Task.Factory.StartNew(() =>
{
PopulateRecords(new CancellationToken(), _options, fileQueue);
DoProcessing(fileQueue);
done = true;
});

Expand All @@ -521,7 +525,7 @@ public GetTagsResult GetResult()
}
else
{
PopulateRecords(new CancellationToken(), _options, GetFileEntries(_options));
DoProcessing(GetFileEntries(_options));
}

//wrapup result status
Expand All @@ -543,7 +547,39 @@ public GetTagsResult GetResult()
getTagsResult.ResultCode = GetTagsResult.ExitCode.Success;
}

if (timedOut)
{
getTagsResult.ResultCode = GetTagsResult.ExitCode.TimedOut;
}

return getTagsResult;

void DoProcessing(IEnumerable<FileEntry> fileEntries)
{
if (_options.ProcessingTimeOut > 0)
{
using var cts = new CancellationTokenSource();
var t = Task.Run(() => PopulateRecords(cts.Token, _options, fileEntries), cts.Token);
if (!t.Wait(new TimeSpan(0, 0, 0, 0, _options.ProcessingTimeOut)))
{
timedOut = true;
WriteOnce.Error($"Processing timed out.");
cts.Cancel();
if (_metaDataHelper is not null)
{
// Populate skips for all the entries we didn't process
foreach (var entry in fileEntries.Where(x => !_metaDataHelper.Files.Any(y => x.FullPath == y.FileName)))
{
_metaDataHelper.Files.Add(new FileRecord() { AccessTime = entry.AccessTime, CreateTime = entry.CreateTime, ModifyTime = entry.ModifyTime, FileName = entry.FullPath, Status = ScanState.TimeOutSkipped });
}
}
}
}
else
{
PopulateRecords(new CancellationToken(), _options, fileEntries);
}
}
}
}
}
3 changes: 2 additions & 1 deletion AppInspector/FileRecord.cs
Expand Up @@ -19,6 +19,7 @@ public enum ScanState
Skipped,
TimedOut,
Analyzed,
Affected
Affected,
TimeOutSkipped
}
}

0 comments on commit fd26fed

Please sign in to comment.