结果扫描与完整搜索不共用锁
This commit is contained in:
parent
0be061086d
commit
a9025be505
@ -3,6 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>FastGithub</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub.Scanner
|
||||
namespace FastGithub
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义中间件的接口
|
||||
/// </summary>
|
||||
interface IGithubScanMiddleware
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
public interface IMiddleware<TContext>
|
||||
{
|
||||
/// <summary>
|
||||
/// 执行中间件
|
||||
@ -14,6 +15,6 @@ namespace FastGithub.Scanner
|
||||
/// <param name="context">上下文</param>
|
||||
/// <param name="next">下一个中间件</param>
|
||||
/// <returns></returns>
|
||||
Task InvokeAsync(GithubContext context, Func<Task> next);
|
||||
Task InvokeAsync(TContext context, Func<Task> next);
|
||||
}
|
||||
}
|
||||
54
FastGithub.Core/IPipelineBuilder.cs
Normal file
54
FastGithub.Core/IPipelineBuilder.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义中间件管道创建者的接口
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext">中间件上下文</typeparam>
|
||||
public interface IPipelineBuilder<TContext>
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取服务提供者
|
||||
/// </summary>
|
||||
IServiceProvider AppServices { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <typeparam name="TMiddleware"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
IPipelineBuilder<TContext> Use<TMiddleware>() where TMiddleware : class, IMiddleware<TContext>;
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="middleware"></param>
|
||||
/// <returns></returns>
|
||||
IPipelineBuilder<TContext> Use(Func<TContext, Func<Task>, Task> middleware);
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <param name="middleware">中间件</param>
|
||||
/// <returns></returns>
|
||||
IPipelineBuilder<TContext> Use(Func<InvokeDelegate<TContext>, InvokeDelegate<TContext>> middleware);
|
||||
|
||||
/// <summary>
|
||||
/// 创建所有中间件执行处理者
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
InvokeDelegate<TContext> Build();
|
||||
|
||||
/// <summary>
|
||||
/// 使用默认配制创建新的PipelineBuilder
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IPipelineBuilder<TContext> New();
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,12 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub.Scanner
|
||||
namespace FastGithub
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示所有中间件执行委托
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext">中间件上下文类型</typeparam>
|
||||
/// <param name="context">中间件上下文</param>
|
||||
/// <returns></returns>
|
||||
delegate Task GithubScanDelegate(GithubContext context);
|
||||
public delegate Task InvokeDelegate<TContext>(TContext context);
|
||||
}
|
||||
103
FastGithub.Core/PipelineBuilder.cs
Normal file
103
FastGithub.Core/PipelineBuilder.cs
Normal file
@ -0,0 +1,103 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示中间件创建者
|
||||
/// </summary>
|
||||
public class PipelineBuilder<TContext> : IPipelineBuilder<TContext>
|
||||
{
|
||||
private readonly InvokeDelegate<TContext> completedHandler;
|
||||
private readonly List<Func<InvokeDelegate<TContext>, InvokeDelegate<TContext>>> middlewares = new List<Func<InvokeDelegate<TContext>, InvokeDelegate<TContext>>>();
|
||||
|
||||
/// <summary>
|
||||
/// 获取服务提供者
|
||||
/// </summary>
|
||||
public IServiceProvider AppServices { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 中间件创建者
|
||||
/// </summary>
|
||||
/// <param name="appServices"></param>
|
||||
public PipelineBuilder(IServiceProvider appServices)
|
||||
: this(appServices, context => Task.CompletedTask)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 中间件创建者
|
||||
/// </summary>
|
||||
/// <param name="appServices"></param>
|
||||
/// <param name="completedHandler">完成执行内容处理者</param>
|
||||
public PipelineBuilder(IServiceProvider appServices, InvokeDelegate<TContext> completedHandler)
|
||||
{
|
||||
this.AppServices = appServices;
|
||||
this.completedHandler = completedHandler;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <typeparam name="TMiddleware"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public IPipelineBuilder<TContext> Use<TMiddleware>() where TMiddleware : class, IMiddleware<TContext>
|
||||
{
|
||||
var middleware = this.AppServices.GetRequiredService<TMiddleware>();
|
||||
return this.Use(middleware.InvokeAsync);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="middleware"></param>
|
||||
/// <returns></returns>
|
||||
public IPipelineBuilder<TContext> Use(Func<TContext, Func<Task>, Task> middleware)
|
||||
{
|
||||
return this.Use(next => context => middleware(context, () => next(context)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <param name="middleware"></param>
|
||||
/// <returns></returns>
|
||||
public IPipelineBuilder<TContext> Use(Func<InvokeDelegate<TContext>, InvokeDelegate<TContext>> middleware)
|
||||
{
|
||||
this.middlewares.Add(middleware);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 创建所有中间件执行处理者
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public InvokeDelegate<TContext> Build()
|
||||
{
|
||||
var handler = this.completedHandler;
|
||||
for (var i = this.middlewares.Count - 1; i >= 0; i--)
|
||||
{
|
||||
handler = this.middlewares[i](handler);
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 使用默认配制创建新的PipelineBuilder
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IPipelineBuilder<TContext> New()
|
||||
{
|
||||
return new PipelineBuilder<TContext>(this.AppServices, this.completedHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
71
FastGithub.Core/PipelineBuilderExtensions.cs
Normal file
71
FastGithub.Core/PipelineBuilderExtensions.cs
Normal file
@ -0,0 +1,71 @@
|
||||
using System;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
/// <summary>
|
||||
/// 中间件创建者扩展
|
||||
/// </summary>
|
||||
public static class PipelineBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 中断执行中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="handler">处理者</param>
|
||||
/// <returns></returns>
|
||||
public static IPipelineBuilder<TContext> Run<TContext>(this IPipelineBuilder<TContext> builder, InvokeDelegate<TContext> handler)
|
||||
{
|
||||
return builder.Use(_ => handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 条件中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="handler"></param>
|
||||
/// <returns></returns>
|
||||
public static IPipelineBuilder<TContext> When<TContext>(this IPipelineBuilder<TContext> builder, Func<TContext, bool> predicate, InvokeDelegate<TContext> handler)
|
||||
{
|
||||
return builder.Use(next => async context =>
|
||||
{
|
||||
if (predicate.Invoke(context) == true)
|
||||
{
|
||||
await handler.Invoke(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
await next(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 条件中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="configureAction"></param>
|
||||
/// <returns></returns>
|
||||
public static IPipelineBuilder<TContext> When<TContext>(this IPipelineBuilder<TContext> builder, Func<TContext, bool> predicate, Action<IPipelineBuilder<TContext>> configureAction)
|
||||
{
|
||||
return builder.Use(next => async context =>
|
||||
{
|
||||
if (predicate.Invoke(context) == true)
|
||||
{
|
||||
var branchBuilder = builder.New();
|
||||
configureAction(branchBuilder);
|
||||
await branchBuilder.Build().Invoke(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
await next(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示中间件创建者
|
||||
/// </summary>
|
||||
sealed class GithubScanBuilder : IGithubScanBuilder
|
||||
{
|
||||
private readonly GithubScanDelegate completedHandler;
|
||||
private readonly List<Func<GithubScanDelegate, GithubScanDelegate>> middlewares = new();
|
||||
|
||||
/// <summary>
|
||||
/// 获取服务提供者
|
||||
/// </summary>
|
||||
public IServiceProvider AppServices { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 中间件创建者
|
||||
/// </summary>
|
||||
/// <param name="appServices"></param>
|
||||
public GithubScanBuilder(IServiceProvider appServices)
|
||||
: this(appServices, context => Task.CompletedTask)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 中间件创建者
|
||||
/// </summary>
|
||||
/// <param name="appServices"></param>
|
||||
/// <param name="completedHandler">完成执行内容处理者</param>
|
||||
public GithubScanBuilder(IServiceProvider appServices, GithubScanDelegate completedHandler)
|
||||
{
|
||||
this.AppServices = appServices;
|
||||
this.completedHandler = completedHandler;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <param name="middleware"></param>
|
||||
/// <returns></returns>
|
||||
public IGithubScanBuilder Use(Func<GithubScanDelegate, GithubScanDelegate> middleware)
|
||||
{
|
||||
this.middlewares.Add(middleware);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 创建所有中间件执行处理者
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public GithubScanDelegate Build()
|
||||
{
|
||||
var handler = this.completedHandler;
|
||||
for (var i = this.middlewares.Count - 1; i >= 0; i--)
|
||||
{
|
||||
handler = this.middlewares[i](handler);
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
/// <summary>
|
||||
/// 中间件创建者扩展
|
||||
/// </summary>
|
||||
static class GithubScanBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TMiddleware"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IGithubScanBuilder Use<TMiddleware>(this IGithubScanBuilder builder) where TMiddleware : class, IGithubScanMiddleware
|
||||
{
|
||||
return builder.AppServices.GetService(typeof(TMiddleware)) is TMiddleware middleware
|
||||
? builder.Use(middleware.InvokeAsync)
|
||||
: throw new InvalidOperationException($"无法获取服务{typeof(TMiddleware)}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="middleware"></param>
|
||||
/// <returns></returns>
|
||||
public static IGithubScanBuilder Use(this IGithubScanBuilder builder, Func<GithubContext, Func<Task>, Task> middleware)
|
||||
{
|
||||
return builder.Use(next => context => middleware(context, () => next(context)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using FastGithub.Scanner.Middlewares;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Linq;
|
||||
@ -12,18 +13,34 @@ namespace FastGithub.Scanner
|
||||
sealed class GithubScanService : IGithubScanService
|
||||
{
|
||||
private readonly GithubMetaService metaService;
|
||||
private readonly GithubScanDelegate scanDelegate;
|
||||
private readonly ILogger<GithubScanService> logger;
|
||||
private readonly GithubContextHashSet results = new();
|
||||
|
||||
private readonly InvokeDelegate<GithubContext> fullScanDelegate;
|
||||
private readonly InvokeDelegate<GithubContext> resultScanDelegate;
|
||||
|
||||
public GithubScanService(
|
||||
GithubMetaService metaService,
|
||||
GithubScanDelegate scanDelegate,
|
||||
ILogger<GithubScanService> logger)
|
||||
ILogger<GithubScanService> logger,
|
||||
IPipelineBuilder<GithubContext> pipelineBuilder)
|
||||
{
|
||||
this.metaService = metaService;
|
||||
this.scanDelegate = scanDelegate;
|
||||
this.logger = logger;
|
||||
|
||||
this.fullScanDelegate = pipelineBuilder
|
||||
.New()
|
||||
.Use<ConcurrentMiddleware>()
|
||||
.Use<PortScanMiddleware>()
|
||||
.Use<HttpsScanMiddleware>()
|
||||
.Use<ScanOkLogMiddleware>()
|
||||
.Build();
|
||||
|
||||
this.resultScanDelegate = pipelineBuilder
|
||||
.New()
|
||||
.Use<PortScanMiddleware>()
|
||||
.Use<HttpsScanMiddleware>()
|
||||
.Use<ScanOkLogMiddleware>()
|
||||
.Build();
|
||||
}
|
||||
|
||||
public async Task ScanAllAsync(CancellationToken cancellationToken = default)
|
||||
@ -40,7 +57,7 @@ namespace FastGithub.Scanner
|
||||
|
||||
async Task ScanAsync(GithubContext context)
|
||||
{
|
||||
await this.scanDelegate(context);
|
||||
await this.fullScanDelegate(context);
|
||||
if (context.HttpElapsed != null)
|
||||
{
|
||||
lock (this.results.SyncRoot)
|
||||
@ -63,7 +80,7 @@ namespace FastGithub.Scanner
|
||||
foreach (var context in contexts)
|
||||
{
|
||||
context.HttpElapsed = null;
|
||||
await this.scanDelegate(context);
|
||||
await this.resultScanDelegate(context);
|
||||
}
|
||||
|
||||
this.logger.LogInformation("结果扫描结束");
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义中间件管道创建者的接口
|
||||
/// </summary>
|
||||
interface IGithubScanBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取服务提供者
|
||||
/// </summary>
|
||||
IServiceProvider AppServices { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <param name="middleware">中间件</param>
|
||||
/// <returns></returns>
|
||||
IGithubScanBuilder Use(Func<GithubScanDelegate, GithubScanDelegate> middleware);
|
||||
|
||||
/// <summary>
|
||||
/// 创建所有中间件执行处理者
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
GithubScanDelegate Build();
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
namespace FastGithub.Scanner.Middlewares
|
||||
{
|
||||
[Service(ServiceLifetime.Singleton)]
|
||||
sealed class ConcurrentMiddleware : IGithubScanMiddleware
|
||||
sealed class ConcurrentMiddleware : IMiddleware<GithubContext>
|
||||
{
|
||||
private readonly SemaphoreSlim semaphoreSlim = new(Environment.ProcessorCount * 4);
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ using System.Threading.Tasks;
|
||||
namespace FastGithub.Scanner.Middlewares
|
||||
{
|
||||
[Service(ServiceLifetime.Singleton)]
|
||||
sealed class HttpsScanMiddleware : IGithubScanMiddleware
|
||||
sealed class HttpsScanMiddleware : IMiddleware<GithubContext>
|
||||
{
|
||||
private readonly IOptionsMonitor<GithubOptions> options;
|
||||
private readonly ILogger<HttpsScanMiddleware> logger;
|
||||
|
||||
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
||||
namespace FastGithub.Scanner.Middlewares
|
||||
{
|
||||
[Service(ServiceLifetime.Singleton)]
|
||||
sealed class PortScanMiddleware : IGithubScanMiddleware
|
||||
sealed class PortScanMiddleware : IMiddleware<GithubContext>
|
||||
{
|
||||
private const int PORT = 443;
|
||||
private readonly IOptionsMonitor<GithubOptions> options;
|
||||
|
||||
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
namespace FastGithub.Scanner.Middlewares
|
||||
{
|
||||
[Service(ServiceLifetime.Singleton)]
|
||||
sealed class ScanOkLogMiddleware : IGithubScanMiddleware
|
||||
sealed class ScanOkLogMiddleware : IMiddleware<GithubContext>
|
||||
{
|
||||
private readonly ILogger<ScanOkLogMiddleware> logger;
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
using FastGithub.Scanner;
|
||||
using FastGithub.Scanner.Middlewares;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Threading.Tasks;
|
||||
@ -22,18 +21,13 @@ namespace FastGithub
|
||||
var assembly = typeof(ScannerServiceCollectionExtensions).Assembly;
|
||||
return services
|
||||
.AddHttpClient()
|
||||
.AddSingleton(serviceProvider =>
|
||||
{
|
||||
return new GithubScanBuilder(serviceProvider, ctx => Task.CompletedTask)
|
||||
.Use<ConcurrentMiddleware>()
|
||||
.Use<PortScanMiddleware>()
|
||||
.Use<HttpsScanMiddleware>()
|
||||
.Use<ScanOkLogMiddleware>()
|
||||
.Build();
|
||||
})
|
||||
.AddServiceAndOptions(assembly, configuration)
|
||||
.AddHostedService<GithubFullScanHostedService>()
|
||||
.AddHostedService<GithubResultScanHostedService>()
|
||||
.AddSingleton<IPipelineBuilder<GithubContext>>(appService =>
|
||||
{
|
||||
return new PipelineBuilder<GithubContext>(appService, ctx => Task.CompletedTask);
|
||||
})
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user