Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.7" />
<PackageVersion Include="Microsoft.Data.SqlClient" Version="7.0.0" />
<PackageVersion Include="NuGetizer" Version="1.4.7" />
<PackageVersion Include="Cronos" Version="0.11.1" />
</ItemGroup>
</Project>
42 changes: 42 additions & 0 deletions src/SqlBulkSyncFunction/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,34 @@ public static class Queues
/// </summary>
public const string SyncJobProgressQueue = "syncjobprogress";
}
/// <summary>
/// NCRONTAB expressions and configuration keys for <see cref="Functions.ProcessGlobalChangeTrackingSchedule"/> timer triggers.
/// </summary>
public static class Schedules
{
/// <summary>
/// Configuration / environment key for the <c>Custom</c> schedule (same as the timer binding placeholder without % delimiters).
/// </summary>
public const string CustomScheduleConfigurationKey = "ProcessGlobalChangeTrackingSchedule";

/// <summary>
/// Timer trigger binding for the custom schedule: <c>%ProcessGlobalChangeTrackingSchedule%</c>.
/// </summary>
public const string CustomScheduleTimerTrigger = "%" + CustomScheduleConfigurationKey + "%";

/// <summary>NCRONTAB for <c>Midnight</c> (<c>0 0 0 * * *</c>).</summary>
public const string MidnightCron = "0 0 0 * * *";

/// <summary>NCRONTAB for <c>Noon</c> (<c>0 0 12 * * *</c>).</summary>
public const string NoonCron = "0 0 12 * * *";

/// <summary>NCRONTAB for <c>EveryFiveMinutes</c> (<c>5 */5 * * * *</c>).</summary>
public const string EveryFiveMinutesCron = "5 */5 * * * *";

/// <summary>NCRONTAB for <c>EveryHour</c> (<c>10 0 * * * *</c>).</summary>
public const string EveryHourCron = "10 0 * * * *";
}

public static class Containers
{
/// <summary>
Expand All @@ -30,5 +58,19 @@ public static class Containers
public const string SyncJob = "syncjob";

public const string SyncSchedule = "syncschedule";

/// <summary>
/// Blob container for per-job monitoring aggregates (written by the aggregation timer).
/// </summary>
public const string Monitor = "monitor";
}

/// <summary>
/// Content types for Azure Blob uploads.
/// </summary>
public static class BlobContentTypes
{
/// <summary>JSON documents (UTF-8).</summary>
public const string Json = "application/json; charset=utf-8";
}
}
24 changes: 24 additions & 0 deletions src/SqlBulkSyncFunction/Functions/AggregateSyncMonitoring.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using SqlBulkSyncFunction.Services;

namespace SqlBulkSyncFunction.Functions;

/// <summary>
/// Timer that drains schedule and progress queues in order and refreshes per-job aggregate blobs under the monitor container.
/// </summary>
public sealed class AggregateSyncMonitoring(SyncMonitoringAggregationService aggregationService)
{
/// <summary>
/// Runs every minute on the minute (UTC).
/// </summary>
[Function(nameof(AggregateSyncMonitoring))]
public Task Run(
#pragma warning disable IDE0060 // Remove unused parameter
[TimerTrigger("0 */1 * * * *")] TimerInfo timerInfo,
#pragma warning restore IDE0060 // Remove unused parameter
CancellationToken cancellationToken
)
=> aggregationService.ProcessAllQueuesAsync(cancellationToken);
}
Loading
Loading