mirror of https://github.com/abpframework/abp.git
11 changed files with 232 additions and 8 deletions
@ -0,0 +1,34 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.BackgroundWorkers; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace Volo.Abp.IdentityServer.Tokens |
|||
{ |
|||
public class TokenCleanupBackgroundWorker : AsyncPeriodicBackgroundWorkerBase |
|||
{ |
|||
protected TokenCleanupOptions Options { get; } |
|||
|
|||
public TokenCleanupBackgroundWorker( |
|||
AbpTimer timer, |
|||
IServiceScopeFactory serviceScopeFactory, |
|||
IOptions<TokenCleanupOptions> options) |
|||
: base( |
|||
timer, |
|||
serviceScopeFactory) |
|||
{ |
|||
Options = options.Value; |
|||
timer.Period = Options.CleanupPeriod; |
|||
} |
|||
|
|||
protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext) |
|||
{ |
|||
await workerContext |
|||
.ServiceProvider |
|||
.GetRequiredService<TokenCleanupService>() |
|||
.CleanAsync() |
|||
.ConfigureAwait(false); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using Volo.Abp.BackgroundWorkers; |
|||
|
|||
namespace Volo.Abp.IdentityServer.Tokens |
|||
{ |
|||
public class TokenCleanupOptions |
|||
{ |
|||
/// <summary>
|
|||
/// Default: 3,600,000 ms.
|
|||
/// </summary>
|
|||
public int CleanupPeriod { get; set; } = 3_600_000; |
|||
|
|||
/// <summary>
|
|||
/// Default value: 100.
|
|||
/// </summary>
|
|||
public int CleanupBatchSize { get; set; } = 100; |
|||
|
|||
/// <summary>
|
|||
/// The number of loop if there are
|
|||
/// more than <see cref="CleanupBatchSize"/> tokens in the database.
|
|||
/// So, if <see cref="CleanupLoopCount"/> is 10 and <see cref="CleanupBatchSize"/> is 100,
|
|||
/// then the cleanup worker will clean 1,000 items in one <see cref="CleanupPeriod"/> at max.
|
|||
///
|
|||
/// Default value: 10.
|
|||
/// </summary>
|
|||
public int CleanupLoopCount { get; set; } = 10; |
|||
|
|||
/// <summary>
|
|||
/// Default value: true.
|
|||
/// If <see cref="AbpBackgroundWorkerOptions.IsEnabled"/> is false,
|
|||
/// this property is ignored and the cleanup worker doesn't work for this application instance.
|
|||
/// </summary>
|
|||
public bool EnableCleanup { get; set; } = true; |
|||
} |
|||
} |
|||
@ -0,0 +1,88 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.IdentityServer.Devices; |
|||
using Volo.Abp.IdentityServer.Grants; |
|||
using Volo.Abp.Timing; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace Volo.Abp.IdentityServer.Tokens |
|||
{ |
|||
public class TokenCleanupService : ITransientDependency |
|||
{ |
|||
protected IPersistentGrantRepository PersistentGrantRepository { get; } |
|||
protected IDeviceFlowCodesRepository DeviceFlowCodesRepository { get; } |
|||
protected IClock Clock { get; } |
|||
protected TokenCleanupOptions Options { get; } |
|||
|
|||
public TokenCleanupService( |
|||
IPersistentGrantRepository persistentGrantRepository, |
|||
IDeviceFlowCodesRepository deviceFlowCodesRepository, |
|||
IClock clock, |
|||
IOptions<TokenCleanupOptions> options) |
|||
{ |
|||
PersistentGrantRepository = persistentGrantRepository; |
|||
DeviceFlowCodesRepository = deviceFlowCodesRepository; |
|||
Clock = clock; |
|||
Options = options.Value; |
|||
} |
|||
|
|||
public virtual async Task CleanAsync() |
|||
{ |
|||
await RemoveGrantsAsync() |
|||
.ConfigureAwait(false); |
|||
|
|||
await RemoveDeviceCodesAsync() |
|||
.ConfigureAwait(false); |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
protected virtual async Task RemoveGrantsAsync() |
|||
{ |
|||
for (int i = 0; i < Options.CleanupLoopCount; i++) |
|||
{ |
|||
var persistentGrants = await PersistentGrantRepository |
|||
.GetListByExpirationAsync(Clock.Now, Options.CleanupBatchSize) |
|||
.ConfigureAwait(false); |
|||
|
|||
//TODO: Can be optimized if the repository implements the batch deletion
|
|||
foreach (var persistentGrant in persistentGrants) |
|||
{ |
|||
await PersistentGrantRepository |
|||
.DeleteAsync(persistentGrant) |
|||
.ConfigureAwait(false); |
|||
} |
|||
|
|||
//No need to continue to query if it gets more than max items.
|
|||
if (persistentGrants.Count < Options.CleanupBatchSize) |
|||
{ |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
protected virtual async Task RemoveDeviceCodesAsync() |
|||
{ |
|||
for (int i = 0; i < Options.CleanupLoopCount; i++) |
|||
{ |
|||
var deviceFlowCodeses = await DeviceFlowCodesRepository |
|||
.GetListByExpirationAsync(Clock.Now, Options.CleanupBatchSize) |
|||
.ConfigureAwait(false); |
|||
|
|||
//TODO: Can be optimized if the repository implements the batch deletion
|
|||
foreach (var deviceFlowCodes in deviceFlowCodeses) |
|||
{ |
|||
await DeviceFlowCodesRepository |
|||
.DeleteAsync(deviceFlowCodes) |
|||
.ConfigureAwait(false); |
|||
} |
|||
|
|||
//No need to continue to query if it gets more than max items.
|
|||
if (deviceFlowCodeses.Count < Options.CleanupBatchSize) |
|||
{ |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue