Adding WaitAvailable to EFCore extensions
This commit is contained in:
@@ -56,7 +56,7 @@ namespace AMWD.Common.AspNetCore.BasicAuthentication
|
|||||||
if (context.Result != null)
|
if (context.Result != null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (context.HttpContext.Request.Headers.ContainsKey("Authorization"))
|
if (!context.HttpContext.Request.Headers.ContainsKey("Authorization"))
|
||||||
{
|
{
|
||||||
SetAuthenticateRequest(context);
|
SetAuthenticateRequest(context);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -28,18 +29,24 @@ namespace Microsoft.EntityFrameworkCore
|
|||||||
if (database == null)
|
if (database == null)
|
||||||
throw new ArgumentNullException(nameof(database));
|
throw new ArgumentNullException(nameof(database));
|
||||||
|
|
||||||
var options = new DatabaseMigrationOptions();
|
|
||||||
optionsAction?.Invoke(options);
|
|
||||||
|
|
||||||
if (database.GetProviderType() == DatabaseProvider.InMemory)
|
if (database.GetProviderType() == DatabaseProvider.InMemory)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
var options = new DatabaseMigrationOptions();
|
||||||
|
optionsAction?.Invoke(options);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(options.MigrationsTableName))
|
if (string.IsNullOrWhiteSpace(options.MigrationsTableName))
|
||||||
throw new ArgumentNullException(nameof(options.MigrationsTableName), $"The property {nameof(options.MigrationsTableName)} of the {nameof(options)} parameter is required.");
|
throw new ArgumentNullException(nameof(options.MigrationsTableName), $"The property {nameof(options.MigrationsTableName)} of the {nameof(options)} parameter is required.");
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(options.Path))
|
if (string.IsNullOrWhiteSpace(options.Path))
|
||||||
throw new ArgumentNullException(nameof(options.Path), $"The property {nameof(options.Path)} of the {nameof(options)} parameter is required.");
|
throw new ArgumentNullException(nameof(options.Path), $"The property {nameof(options.Path)} of the {nameof(options)} parameter is required.");
|
||||||
|
|
||||||
|
await database.WaitAvailableAsync(opts =>
|
||||||
|
{
|
||||||
|
opts.WaitDelay = options.WaitDelay;
|
||||||
|
opts.Logger = options.Logger;
|
||||||
|
}, cancellationToken);
|
||||||
|
|
||||||
var connection = database.GetDbConnection();
|
var connection = database.GetDbConnection();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -52,7 +59,58 @@ namespace Microsoft.EntityFrameworkCore
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
connection.Close();
|
await connection.CloseAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Waits until the database connection is available.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="database">The database connection.</param>
|
||||||
|
/// <param name="optionsAction">An action to set additional options.</param>
|
||||||
|
/// <param name="cancellationToken">A cancellation token.</param>
|
||||||
|
/// <returns>An awaitable task to wait until the database is available.</returns>
|
||||||
|
public static async Task WaitAvailableAsync(this DatabaseFacade database, Action<DatabaseMigrationOptions> optionsAction = null, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (database == null)
|
||||||
|
throw new ArgumentNullException(nameof(database));
|
||||||
|
|
||||||
|
if (database.GetProviderType() == DatabaseProvider.InMemory)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var options = new DatabaseMigrationOptions();
|
||||||
|
optionsAction?.Invoke(options);
|
||||||
|
|
||||||
|
options.Logger?.LogInformation("Waiting for a database connection");
|
||||||
|
var connection = database.GetDbConnection();
|
||||||
|
while (!cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await connection.OpenAsync(cancellationToken);
|
||||||
|
options.Logger?.LogInformation("Database connection available");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// keep things quiet
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Task.Delay(options.WaitDelay, cancellationToken);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// keep things quiet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
await connection.CloseAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Reflection;
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Microsoft.EntityFrameworkCore
|
namespace Microsoft.EntityFrameworkCore
|
||||||
@@ -27,5 +28,10 @@ namespace Microsoft.EntityFrameworkCore
|
|||||||
/// Gets or sets the source assembly for embedded files.
|
/// Gets or sets the source assembly for embedded files.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Assembly SourceAssembly { get; set; }
|
public Assembly SourceAssembly { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a delay to wait before a connect retry.
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan WaitDelay { get; set; } = TimeSpan.FromSeconds(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
CHANGELOG.md
10
CHANGELOG.md
@@ -4,9 +4,17 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [Unreleased](https://git.am-wd.de/AM.WD/common/compare/v1.4.0...master) - 0000-00-00
|
## [Unreleased](https://git.am-wd.de/AM.WD/common/compare/v1.4.1...master) - 0000-00-00
|
||||||
|
_nothing changed yet_
|
||||||
|
|
||||||
|
|
||||||
|
## [v1.4.1](https://git.am-wd.de/AM.WD/common/compare/v1.4.0...v1.4.1) - 2022-03-23
|
||||||
### Added
|
### Added
|
||||||
- `IntegrityHashTagHelper` can be used with `asp-integrity="true|false"` and `asp-integrity-strength="256|384|512"`
|
- `IntegrityHashTagHelper` can be used with `asp-integrity="true|false"` and `asp-integrity-strength="256|384|512"`
|
||||||
|
- `WaitAvailableAsync` can be used to wait for a database connection to be available.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- `ApplyMigrationsAsync` uses `WaitAvailableAsync` internally.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- `InMemory` database provider does not fail on "migration" (none possible)
|
- `InMemory` database provider does not fail on "migration" (none possible)
|
||||||
|
|||||||
Reference in New Issue
Block a user