Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Commit

Permalink
Requeue ado notification on ff (#3358)
Browse files Browse the repository at this point in the history
* Requeue ado notification on ff

* Fix test
  • Loading branch information
tevoinea authored and AdamL-Microsoft committed Jul 28, 2023
1 parent 9f8a8a0 commit 638ff8c
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 13 deletions.
13 changes: 8 additions & 5 deletions src/ApiService/ApiService/Functions/QueueFileChanges.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,17 @@ public class QueueFileChanges {
// requeuing ourselves because azure functions doesn't support retry policies
// for queue based functions.

await FileAdded(fileChangeEvent, isLastRetryAttempt: false);
var result = await FileAdded(fileChangeEvent, isLastRetryAttempt: false);
if (!result.IsOk && result.ErrorV.Code == ErrorCode.ADO_WORKITEM_PROCESSING_DISABLED) {
await RequeueMessage(msg, TimeSpan.FromDays(1));
}
} catch (Exception e) {
_log.LogError(e, "File Added failed");
await RequeueMessage(msg);
}
}

private async Async.Task FileAdded(JsonDocument fileChangeEvent, bool isLastRetryAttempt) {
private async Async.Task<OneFuzzResultVoid> FileAdded(JsonDocument fileChangeEvent, bool isLastRetryAttempt) {
var data = fileChangeEvent.RootElement.GetProperty("data");
var url = data.GetProperty("url").GetString()!;
var parts = url.Split("/").Skip(3).ToList();
Expand All @@ -77,10 +80,10 @@ public class QueueFileChanges {
var path = string.Join('/', parts.Skip(1));

_log.LogInformation("file added : {Container} - {Path}", container, path);
await _notificationOperations.NewFiles(Container.Parse(container), path, isLastRetryAttempt);
return await _notificationOperations.NewFiles(Container.Parse(container), path, isLastRetryAttempt);
}

private async Async.Task RequeueMessage(string msg) {
private async Async.Task RequeueMessage(string msg, TimeSpan? visibilityTimeout = null) {
var json = JsonNode.Parse(msg);

// Messages that are 'manually' requeued by us as opposed to being requeued by the azure functions runtime
Expand All @@ -103,7 +106,7 @@ public class QueueFileChanges {
queueName,
json,
StorageType.Config,
CalculateExponentialBackoff(newCustomDequeueCount))
visibilityTimeout ?? CalculateExponentialBackoff(newCustomDequeueCount))
.IgnoreResult();
}

Expand Down
1 change: 1 addition & 0 deletions src/ApiService/ApiService/OneFuzzTypes/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public enum ErrorCode {
ADO_VALIDATION_UNEXPECTED_HTTP_EXCEPTION = 490,
ADO_VALIDATION_UNEXPECTED_ERROR = 491,
ADO_VALIDATION_MISSING_PAT_SCOPES = 492,
ADO_WORKITEM_PROCESSING_DISABLED = 494,
// NB: if you update this enum, also update enums.py
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class NotificationOperationsTestHooks {
var fileName = query["fileName"];
var isLastRetryAttempt = UriExtension.GetBool("isLastRetryAttempt", query, true);

await _notificationOps.NewFiles(Container.Parse(container), fileName, isLastRetryAttempt);
_ = await _notificationOps.NewFiles(Container.Parse(container), fileName, isLastRetryAttempt);
var resp = req.CreateResponse(HttpStatusCode.OK);
return resp;
}
Expand Down
25 changes: 18 additions & 7 deletions src/ApiService/ApiService/onefuzzlib/NotificationOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Microsoft.OneFuzz.Service;

public interface INotificationOperations : IOrm<Notification> {
Async.Task NewFiles(Container container, string filename, bool isLastRetryAttempt);
Async.Task<OneFuzzResultVoid> NewFiles(Container container, string filename, bool isLastRetryAttempt);
IAsyncEnumerable<Notification> GetNotifications(Container container);
IAsyncEnumerable<(Task, IEnumerable<Container>)> GetQueueTasks();
Async.Task<OneFuzzResult<Notification>> Create(Container container, NotificationTemplate config, bool replaceExisting);
Expand All @@ -21,24 +21,29 @@ public NotificationOperations(ILogger<NotificationOperations> log, IOnefuzzConte
: base(log, context) {

}
public async Async.Task NewFiles(Container container, string filename, bool isLastRetryAttempt) {
public async Async.Task<OneFuzzResultVoid> NewFiles(Container container, string filename, bool isLastRetryAttempt) {
var result = OneFuzzResultVoid.Ok;

// We don't want to store file added events for the events container because that causes an infinite loop
if (container == WellKnownContainers.Events) {
return;
return result;
}

var notifications = GetNotifications(container);
var hasNotifications = await notifications.AnyAsync();
var reportOrRegression = await _context.Reports.GetReportOrRegression(container, filename, expectReports: hasNotifications);
if (hasNotifications && await _context.FeatureManagerSnapshot.IsEnabledAsync(FeatureFlagConstants.EnableWorkItemCreation)) {
if (hasNotifications) {
var done = new List<NotificationTemplate>();
await foreach (var notification in notifications) {
if (done.Contains(notification.Config)) {
continue;
}

done.Add(notification.Config);
_ = await TriggerNotification(container, notification, reportOrRegression, isLastRetryAttempt);
var notificationResult = await TriggerNotification(container, notification, reportOrRegression, isLastRetryAttempt);
if (result.IsOk && !notificationResult.IsOk) {
result = notificationResult;
}
}
}

Expand Down Expand Up @@ -77,6 +82,8 @@ public NotificationOperations(ILogger<NotificationOperations> log, IOnefuzzConte
} else {
await _context.Events.SendEvent(new EventFileAdded(container, filename));
}

return result;
}

public async System.Threading.Tasks.Task<OneFuzzResultVoid> TriggerNotification(Container container,
Expand All @@ -87,8 +94,12 @@ public NotificationOperations(ILogger<NotificationOperations> log, IOnefuzzConte
notification.NotificationId);
break;
case AdoTemplate adoTemplate when reportOrRegression is not null:
return await _context.Ado.NotifyAdo(adoTemplate, container, reportOrRegression, isLastRetryAttempt,
notification.NotificationId);
if (await _context.FeatureManagerSnapshot.IsEnabledAsync(FeatureFlagConstants.EnableWorkItemCreation)) {
return await _context.Ado.NotifyAdo(adoTemplate, container, reportOrRegression, isLastRetryAttempt,
notification.NotificationId);
} else {
return OneFuzzResultVoid.Error(ErrorCode.ADO_WORKITEM_PROCESSING_DISABLED, "Work item processing is currently disabled");
}
case GithubIssuesTemplate githubIssuesTemplate when reportOrRegression is not null:
await _context.GithubIssues.GithubIssue(githubIssuesTemplate, container, reportOrRegression,
notification.NotificationId);
Expand Down

0 comments on commit 638ff8c

Please sign in to comment.