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