in src/WebJobs.Script.WebHost/Management/FunctionsSyncManager.cs [95:166]
public async Task<TriggersOperationResult> TrySyncTriggersAsync(bool isBackgroundSync = false)
{
var result = new TriggersOperationResult
{
Success = true
};
if (!IsSyncTriggersEnvironment(_webHostEnvironment, _environment))
{
result.Success = false;
result.Error = "Invalid environment for SyncTriggers operation.";
_logger.LogWarning(result.Error);
return result;
}
try
{
await _syncSemaphore.WaitAsync();
var hashBlobClient = await GetHashBlobAsync();
if (isBackgroundSync && hashBlobClient == null && !_environment.IsAnyKubernetesEnvironment())
{
// short circuit before doing any work in background sync
// cases where we need to check/update hash but don't have
// storage access in non-Kubernetes environments.
return result;
}
var payload = await GetSyncTriggersPayload();
if (isBackgroundSync && payload.Count == 0)
{
// We don't do background sync for empty triggers.
// We've seen error cases where a site temporarily gets into a situation
// where it's site content is empty. Doing the empty sync can cause the app
// to go idle when it shouldn't.
_logger.LogDebug("No functions found. Skipping Sync operation.");
return result;
}
bool shouldSyncTriggers = true;
string newHash = null;
if (isBackgroundSync && hashBlobClient != null)
{
newHash = await CheckHashAsync(hashBlobClient, payload.Content);
shouldSyncTriggers = newHash != null;
}
if (shouldSyncTriggers)
{
var (success, error) = await SetTriggersAsync(payload.Content);
if (success && newHash != null)
{
await UpdateHashAsync(hashBlobClient, newHash);
}
result.Success = success;
result.Error = error;
}
}
catch (Exception ex)
{
// best effort - log error and continue
result.Success = false;
result.Error = "SyncTriggers operation failed.";
_logger.LogError(ex, result.Error);
}
finally
{
_syncSemaphore.Release();
}
return result;
}