优化分片查询吞吐量
This commit is contained in:
parent
ace2d0cb6c
commit
4ac8601583
|
@ -0,0 +1,133 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShardingCore.Sharding.Enumerators.StreamMergeAsync
|
||||
{
|
||||
internal class OneAtMostElementStreamMergeAsyncEnumerator<T> : IStreamMergeAsyncEnumerator<T>
|
||||
{
|
||||
private List<T>.Enumerator _enumerator;
|
||||
private bool skip;
|
||||
|
||||
public OneAtMostElementStreamMergeAsyncEnumerator(IStreamMergeAsyncEnumerator<T> streamMergeAsyncEnumerator)
|
||||
{
|
||||
var list = new List<T>();
|
||||
if (streamMergeAsyncEnumerator.HasElement())
|
||||
{
|
||||
list.Add(streamMergeAsyncEnumerator.ReallyCurrent);
|
||||
}
|
||||
|
||||
_enumerator = list.GetEnumerator();
|
||||
_enumerator.MoveNext();
|
||||
skip = true;
|
||||
}
|
||||
|
||||
#if !EFCORE2&&!EFCORE3&&!EFCORE5
|
||||
public ValueTask DisposeAsync()
|
||||
{
|
||||
_enumerator.Dispose();
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public ValueTask<bool> MoveNextAsync()
|
||||
{
|
||||
var moveNext = _enumerator.MoveNext();
|
||||
return ValueTask.FromResult<bool>(moveNext);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_enumerator.Dispose();
|
||||
}
|
||||
|
||||
#endif
|
||||
#if EFCORE3 || EFCORE5
|
||||
public ValueTask DisposeAsync()
|
||||
{
|
||||
_enumerator.Dispose();
|
||||
return new ValueTask();
|
||||
}
|
||||
|
||||
public ValueTask<bool> MoveNextAsync()
|
||||
{
|
||||
var moveNext = _enumerator.MoveNext();
|
||||
return new ValueTask<bool>(moveNext);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_enumerator.Dispose();
|
||||
}
|
||||
|
||||
#endif
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (skip)
|
||||
{
|
||||
skip = false;
|
||||
return null != _enumerator.Current;
|
||||
}
|
||||
|
||||
var moveNext = _enumerator.MoveNext();
|
||||
return moveNext;
|
||||
}
|
||||
|
||||
public bool SkipFirst()
|
||||
{
|
||||
if (skip)
|
||||
{
|
||||
skip = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool HasElement()
|
||||
{
|
||||
return null != _enumerator.Current;
|
||||
}
|
||||
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
object IEnumerator.Current => Current;
|
||||
public T Current => GetCurrent();
|
||||
public T ReallyCurrent => GetReallyCurrent();
|
||||
|
||||
public T GetCurrent()
|
||||
{
|
||||
if (skip)
|
||||
return default;
|
||||
return _enumerator.Current;
|
||||
}
|
||||
|
||||
public T GetReallyCurrent()
|
||||
{
|
||||
return _enumerator.Current;
|
||||
}
|
||||
#if EFCORE2
|
||||
public void Dispose()
|
||||
{
|
||||
_enumerator.Dispose();
|
||||
}
|
||||
|
||||
public Task<bool> MoveNext(CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
if (skip)
|
||||
{
|
||||
skip = false;
|
||||
return Task.FromResult(null != _enumerator.Current);
|
||||
}
|
||||
var moveNext = _enumerator.MoveNext();
|
||||
return Task.FromResult(moveNext);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines.Enumer
|
|||
|
||||
protected override IExecutor<IStreamMergeAsyncEnumerator<TEntity>> CreateExecutor0(bool async)
|
||||
{
|
||||
GetStreamMergeContext().ReSetTake(1);
|
||||
GetStreamMergeContext().ReSetTake(2);
|
||||
return new DefaultEnumeratorExecutor<TEntity>(GetStreamMergeContext(), GetStreamMergeCombine(), async);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines.Enumer
|
|||
var streamMergeContext = GetStreamMergeContext();
|
||||
var shardingRouteResult = streamMergeContext.ShardingRouteResult;
|
||||
var sqlRouteUnit = shardingRouteResult.RouteUnits.First();
|
||||
var shardingDbContext = streamMergeContext.CreateDbContext(sqlRouteUnit, ConnectionModeEnum.MEMORY_STRICTLY);
|
||||
var shardingDbContext = streamMergeContext.CreateDbContext(sqlRouteUnit);
|
||||
var newQueryable = (IQueryable<TEntity>)streamMergeContext.GetOriginalQueryable().ReplaceDbContextQueryable(shardingDbContext);
|
||||
var enumeratorParallelExecutor = new SingleQueryEnumeratorExecutor<TEntity>(streamMergeContext);
|
||||
if (async)
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
|
|||
internal abstract class AbstractExecutor<TResult> : IExecutor<TResult>
|
||||
{
|
||||
private readonly StreamMergeContext _streamMergeContext;
|
||||
|
||||
/// <summary>
|
||||
/// not cancelled const mark
|
||||
/// </summary>
|
||||
|
@ -22,10 +23,11 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
|
|||
/// cancelled const mark
|
||||
/// </summary>
|
||||
private const int cancelled = 0;
|
||||
|
||||
/// <summary>
|
||||
/// cancel status
|
||||
/// </summary>
|
||||
private int cancelStatus= notCancelled;
|
||||
private int cancelStatus = notCancelled;
|
||||
|
||||
protected AbstractExecutor(StreamMergeContext streamMergeContext)
|
||||
{
|
||||
|
@ -36,6 +38,7 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
|
|||
{
|
||||
return _streamMergeContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建熔断器来中断符合查询的结果比如firstordefault只需要在顺序查询下查询到第一个
|
||||
/// 如果不是顺序查询则需要所有表的第一个进行内存再次查询
|
||||
|
@ -53,7 +56,9 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
|
|||
return cancelStatus == cancelled;
|
||||
}
|
||||
|
||||
public async Task<LinkedList<TResult>> ExecuteAsync(bool async, DataSourceSqlExecutorUnit dataSourceSqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
public async Task<LinkedList<TResult>> ExecuteAsync(bool async,
|
||||
DataSourceSqlExecutorUnit dataSourceSqlExecutorUnit,
|
||||
CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -65,8 +70,12 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
|
|||
throw;
|
||||
}
|
||||
}
|
||||
private async Task<LinkedList<TResult>> ExecuteAsync0(bool async, DataSourceSqlExecutorUnit dataSourceSqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
|
||||
private async Task<LinkedList<TResult>> ExecuteAsync0(bool async,
|
||||
DataSourceSqlExecutorUnit dataSourceSqlExecutorUnit,
|
||||
CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var streamMergeContext = GetStreamMergeContext();
|
||||
var circuitBreaker = CreateCircuitBreaker();
|
||||
var executorGroups = dataSourceSqlExecutorUnit.SqlExecutorGroups;
|
||||
LinkedList<TResult> result = new LinkedList<TResult>();
|
||||
|
@ -84,13 +93,7 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
|
|||
var dbContexts = routeQueryResults.Select(o => o.DbContext);
|
||||
foreach (var dbContext in dbContexts)
|
||||
{
|
||||
#if !EFCORE2
|
||||
await dbContext.DisposeAsync();
|
||||
|
||||
#endif
|
||||
#if EFCORE2
|
||||
dbContext.Dispose();
|
||||
#endif
|
||||
await streamMergeContext.DbContextDisposeAsync(dbContext);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -105,20 +108,22 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
|
|||
var hasNextLoop = executorGroupsCount > 0;
|
||||
if (hasNextLoop)
|
||||
{
|
||||
if (IsCancelled()|| circuitBreaker.Terminated(result))
|
||||
if (IsCancelled() || circuitBreaker.Terminated(result))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同库同组下面的并行异步执行,需要归并成一个结果
|
||||
/// </summary>
|
||||
/// <param name="sqlExecutorUnits"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task<LinkedList<ShardingMergeResult<TResult>>> GroupExecuteAsync(List<SqlExecutorUnit> sqlExecutorUnits, CancellationToken cancellationToken = new CancellationToken())
|
||||
protected async Task<LinkedList<ShardingMergeResult<TResult>>> GroupExecuteAsync(
|
||||
List<SqlExecutorUnit> sqlExecutorUnits, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
if (sqlExecutorUnits.Count <= 0)
|
||||
{
|
||||
|
@ -128,8 +133,9 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
|
|||
{
|
||||
var result = new LinkedList<ShardingMergeResult<TResult>>();
|
||||
|
||||
var tasks = sqlExecutorUnits.Select(sqlExecutorUnit => ExecuteUnitAsync(sqlExecutorUnit, cancellationToken)).ToArray();
|
||||
|
||||
var tasks = sqlExecutorUnits
|
||||
.Select(sqlExecutorUnit => ExecuteUnitAsync(sqlExecutorUnit, cancellationToken)).ToArray();
|
||||
|
||||
var results = await TaskHelper.WhenAllFastFail(tasks);
|
||||
foreach (var r in results)
|
||||
{
|
||||
|
@ -139,14 +145,17 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
|
|||
return result;
|
||||
}
|
||||
}
|
||||
protected virtual void MergeParallelExecuteResult(LinkedList<TResult> previewResults, IEnumerable<TResult> parallelResults, bool async)
|
||||
|
||||
protected virtual void MergeParallelExecuteResult(LinkedList<TResult> previewResults,
|
||||
IEnumerable<TResult> parallelResults, bool async)
|
||||
{
|
||||
foreach (var parallelResult in parallelResults)
|
||||
{
|
||||
previewResults.AddLast(parallelResult);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Task<ShardingMergeResult<TResult>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit,
|
||||
CancellationToken cancellationToken = new CancellationToken());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,13 +5,16 @@ using System.Text;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.Enumerators;
|
||||
using ShardingCore.Sharding.Enumerators.StreamMergeAsync;
|
||||
using ShardingCore.Sharding.Enumerators.StreamMergeAsync.EFCore2x;
|
||||
using ShardingCore.Sharding.MergeEngines.Abstractions;
|
||||
using ShardingCore.Sharding.MergeEngines.Common;
|
||||
using ShardingCore.Sharding.MergeEngines.Executors.Abstractions;
|
||||
using ShardingCore.Sharding.MergeEngines.Executors.CircuitBreakers;
|
||||
using ShardingCore.Sharding.ShardingExecutors;
|
||||
|
||||
#if EFCORE2
|
||||
using Microsoft.EntityFrameworkCore.Extensions.Internal;
|
||||
|
@ -140,5 +143,62 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators.Abstractions
|
|||
enumator.MoveNext();
|
||||
return enumator;
|
||||
}
|
||||
|
||||
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var shardingMergeResult = await ExecuteUnitAsync0(sqlExecutorUnit, cancellationToken);
|
||||
var dbContext = shardingMergeResult.DbContext;
|
||||
var streamMergeAsyncEnumerator = shardingMergeResult.MergeResult;
|
||||
//连接数严格的会在内存中聚合然后聚合后回收,非连接数严格需要判断是否需要当前执行单元直接回收
|
||||
//first last 等操作没有skip就可以回收,如果没有元素就可以回收
|
||||
//single如果没有元素就可以回收
|
||||
//enumerable如果没有元素就可以回收
|
||||
if (sqlExecutorUnit.ConnectionMode != ConnectionModeEnum.CONNECTION_STRICTLY)
|
||||
{
|
||||
var streamMergeContext = GetStreamMergeContext();
|
||||
if (DisposeInExecuteUnit(streamMergeContext,streamMergeAsyncEnumerator))
|
||||
{
|
||||
var disConnectionStreamMergeAsyncEnumerator = new OneAtMostElementStreamMergeAsyncEnumerator<TResult>(streamMergeAsyncEnumerator);
|
||||
await streamMergeContext.DbContextDisposeAsync(dbContext);
|
||||
return new ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>(null,
|
||||
disConnectionStreamMergeAsyncEnumerator);
|
||||
}
|
||||
}
|
||||
|
||||
return shardingMergeResult;
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否需要在执行单元中直接回收掉链接有助于提高吞吐量
|
||||
/// </summary>
|
||||
/// <param name="streamMergeContext"></param>
|
||||
/// <param name="streamMergeAsyncEnumerator"></param>
|
||||
/// <returns></returns>
|
||||
private bool DisposeInExecuteUnit(StreamMergeContext streamMergeContext,IStreamMergeAsyncEnumerator<TResult> streamMergeAsyncEnumerator)
|
||||
{
|
||||
var queryMethodName = streamMergeContext.MergeQueryCompilerContext.GetQueryMethodName();
|
||||
var hasElement = streamMergeAsyncEnumerator.HasElement();
|
||||
|
||||
switch (queryMethodName)
|
||||
{
|
||||
case nameof(Queryable.First):
|
||||
case nameof(Queryable.FirstOrDefault):
|
||||
case nameof(Queryable.Last):
|
||||
case nameof(Queryable.LastOrDefault):
|
||||
{
|
||||
var skip = streamMergeContext.GetSkip();
|
||||
return skip is null or < 0||!hasElement;
|
||||
}
|
||||
case nameof(Queryable.Single):
|
||||
case nameof(Queryable.SingleOrDefault):
|
||||
case QueryCompilerContext.ENUMERABLE:
|
||||
{
|
||||
return !hasElement;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
protected abstract Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(
|
||||
SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,13 +32,12 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators
|
|||
_async = async;
|
||||
}
|
||||
|
||||
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var streamMergeContext = GetStreamMergeContext();
|
||||
var connectionMode = streamMergeContext.RealConnectionMode(sqlExecutorUnit.ConnectionMode);
|
||||
var sqlSequenceRouteUnit = sqlExecutorUnit.RouteUnit.As<SqlSequenceRouteUnit>();
|
||||
var sequenceResult = sqlSequenceRouteUnit.SequenceResult;
|
||||
var shardingDbContext = streamMergeContext.CreateDbContext(sqlSequenceRouteUnit, connectionMode);
|
||||
var shardingDbContext = streamMergeContext.CreateDbContext(sqlSequenceRouteUnit);
|
||||
var newQueryable = _noPaginationQueryable
|
||||
.Skip(sequenceResult.Skip)
|
||||
.Take(sequenceResult.Take)
|
||||
|
|
|
@ -44,12 +44,10 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators
|
|||
return base.CombineInMemoryStreamMergeAsyncEnumerator(streamsAsyncEnumerators);
|
||||
}
|
||||
|
||||
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var streamMergeContext = GetStreamMergeContext();
|
||||
var connectionMode = streamMergeContext.RealConnectionMode(sqlExecutorUnit.ConnectionMode);
|
||||
|
||||
var shardingDbContext = streamMergeContext.CreateDbContext(sqlExecutorUnit.RouteUnit, connectionMode);
|
||||
var shardingDbContext = streamMergeContext.CreateDbContext(sqlExecutorUnit.RouteUnit);
|
||||
var newQueryable = (IQueryable<TResult>)streamMergeContext.GetReWriteQueryable()
|
||||
.ReplaceDbContextQueryable(shardingDbContext);
|
||||
|
||||
|
|
|
@ -28,11 +28,12 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators
|
|||
_async = async;
|
||||
}
|
||||
|
||||
protected override Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
protected override Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
protected override IStreamMergeCombine GetStreamMergeCombine()
|
||||
{
|
||||
return _streamMergeCombine;
|
||||
|
|
|
@ -36,12 +36,11 @@ internal class LastOrDefaultEnumeratorExecutor<TResult> : AbstractEnumeratorExec
|
|||
return base.CombineInMemoryStreamMergeAsyncEnumerator(streamsAsyncEnumerators);
|
||||
}
|
||||
|
||||
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var streamMergeContext = GetStreamMergeContext();
|
||||
var connectionMode = streamMergeContext.RealConnectionMode(sqlExecutorUnit.ConnectionMode);
|
||||
|
||||
var shardingDbContext = streamMergeContext.CreateDbContext(sqlExecutorUnit.RouteUnit, connectionMode);
|
||||
var shardingDbContext = streamMergeContext.CreateDbContext(sqlExecutorUnit.RouteUnit);
|
||||
var newQueryable = (IQueryable<TResult>)_queryable.ReplaceDbContextQueryable(shardingDbContext);
|
||||
|
||||
var streamMergeAsyncEnumerator = await AsyncParallelEnumerator(newQueryable, _async, cancellationToken);
|
||||
|
|
|
@ -33,12 +33,11 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators
|
|||
_async = async;
|
||||
}
|
||||
|
||||
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var streamMergeContext = GetStreamMergeContext();
|
||||
var connectionMode = streamMergeContext.RealConnectionMode(sqlExecutorUnit.ConnectionMode);
|
||||
|
||||
var shardingDbContext = streamMergeContext.CreateDbContext(sqlExecutorUnit.RouteUnit, connectionMode);
|
||||
var shardingDbContext = streamMergeContext.CreateDbContext(sqlExecutorUnit.RouteUnit);
|
||||
var newQueryable = _reverseOrderQueryable
|
||||
.ReplaceDbContextQueryable(shardingDbContext).As<IQueryable<TResult>>();
|
||||
var streamMergeAsyncEnumerator = await AsyncParallelEnumerator(newQueryable, _async, cancellationToken);
|
||||
|
|
|
@ -32,13 +32,12 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators
|
|||
_noPaginationQueryable = streamMergeContext.GetOriginalQueryable().RemoveSkip().RemoveTake().As<IQueryable<TResult>>();
|
||||
}
|
||||
|
||||
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var streamMergeContext = GetStreamMergeContext();
|
||||
var connectionMode = streamMergeContext.RealConnectionMode(sqlExecutorUnit.ConnectionMode);
|
||||
var sqlSequenceRouteUnit = sqlExecutorUnit.RouteUnit.As<SqlSequenceRouteUnit>();
|
||||
var sequenceResult = sqlSequenceRouteUnit.SequenceResult;
|
||||
var shardingDbContext = streamMergeContext.CreateDbContext(sqlSequenceRouteUnit, connectionMode);
|
||||
var shardingDbContext = streamMergeContext.CreateDbContext(sqlSequenceRouteUnit);
|
||||
var newQueryable = _noPaginationQueryable
|
||||
.Skip(sequenceResult.Skip)
|
||||
.Take(sequenceResult.Take)
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators
|
|||
public SingleQueryEnumeratorExecutor(StreamMergeContext streamMergeContext) : base(streamMergeContext)
|
||||
{
|
||||
}
|
||||
protected override Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
protected override Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
@ -26,11 +26,10 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Methods.Abstractions
|
|||
|
||||
protected override async Task<ShardingMergeResult<RouteQueryResult<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var connectionMode = GetStreamMergeContext().RealConnectionMode(sqlExecutorUnit.ConnectionMode);
|
||||
var dataSourceName = sqlExecutorUnit.RouteUnit.DataSourceName;
|
||||
var routeResult = sqlExecutorUnit.RouteUnit.TableRouteResult;
|
||||
|
||||
var shardingDbContext = GetStreamMergeContext().CreateDbContext(sqlExecutorUnit.RouteUnit, connectionMode);
|
||||
var shardingDbContext = GetStreamMergeContext().CreateDbContext(sqlExecutorUnit.RouteUnit);
|
||||
var newQueryable = GetStreamMergeContext().GetReWriteQueryable()
|
||||
.ReplaceDbContextQueryable(shardingDbContext);
|
||||
|
||||
|
|
|
@ -26,11 +26,10 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Methods.Abstractions
|
|||
|
||||
protected override async Task<ShardingMergeResult<RouteQueryResult<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var connectionMode = GetStreamMergeContext().RealConnectionMode(sqlExecutorUnit.ConnectionMode);
|
||||
var dataSourceName = sqlExecutorUnit.RouteUnit.DataSourceName;
|
||||
var routeResult = sqlExecutorUnit.RouteUnit.TableRouteResult;
|
||||
|
||||
var shardingDbContext = GetStreamMergeContext().CreateDbContext(sqlExecutorUnit.RouteUnit, connectionMode);
|
||||
var shardingDbContext = GetStreamMergeContext().CreateDbContext(sqlExecutorUnit.RouteUnit);
|
||||
var newQueryable = GetStreamMergeContext().GetReWriteQueryable()
|
||||
.ReplaceDbContextQueryable(shardingDbContext);
|
||||
|
||||
|
|
|
@ -171,8 +171,11 @@ namespace ShardingCore.Sharding.ShardingExecutors
|
|||
|
||||
public QueryCompilerExecutor GetQueryCompilerExecutor()
|
||||
{
|
||||
//只获取第一次所以判断是否已经获取过了
|
||||
if (!hasQueryCompilerExecutor.HasValue)
|
||||
{
|
||||
//空结果
|
||||
//todo 后续优化直接无需后续的解析之类的
|
||||
if(_shardingRouteResult.IsEmpty)
|
||||
{
|
||||
hasQueryCompilerExecutor = false;
|
||||
|
|
|
@ -22,8 +22,10 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
|
|||
using ShardingCore.Core.RuntimeContexts;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Sharding.Enumerators;
|
||||
using ShardingCore.Sharding.MergeEngines.Abstractions;
|
||||
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
|
||||
using ShardingCore.Sharding.ShardingExecutors;
|
||||
|
||||
|
||||
namespace ShardingCore.Sharding
|
||||
|
@ -98,7 +100,7 @@ namespace ShardingCore.Sharding
|
|||
_trackerManager = ShardingRuntimeContext.GetTrackerManager();
|
||||
_shardingConfigOptions = ShardingRuntimeContext.GetShardingConfigOptions();
|
||||
QueryEntities = MergeQueryCompilerContext.GetQueryEntities().Keys.ToHashSet();
|
||||
_parallelDbContexts = new ConcurrentDictionary<DbContext, object>();
|
||||
_parallelDbContexts = new ConcurrentDictionary<DbContext, object>(Environment.ProcessorCount,mergeQueryCompilerContext.GetShardingRouteResult().RouteUnits.Count);
|
||||
Orders = parseResult.GetOrderByContext().PropertyOrders.ToArray();
|
||||
Skip = parseResult.GetPaginationContext().Skip;
|
||||
Take = parseResult.GetPaginationContext().Take;
|
||||
|
@ -123,21 +125,13 @@ namespace ShardingCore.Sharding
|
|||
/// 创建对应的dbcontext
|
||||
/// </summary>
|
||||
/// <param name="sqlRouteUnit">数据库路由最小单元</param>
|
||||
/// <param name="connectionMode"></param>
|
||||
/// <returns></returns>
|
||||
public DbContext CreateDbContext(ISqlRouteUnit sqlRouteUnit, ConnectionModeEnum connectionMode)
|
||||
public DbContext CreateDbContext(ISqlRouteUnit sqlRouteUnit)
|
||||
{
|
||||
var routeTail = _routeTailFactory.Create(sqlRouteUnit.TableRouteResult);
|
||||
//如果开启了读写分离或者本次查询是跨表的表示本次查询的dbcontext是不存储的用完后就直接dispose
|
||||
var parallelQuery = IsParallelQuery();
|
||||
var strategy = !parallelQuery
|
||||
? CreateDbContextStrategyEnum.ShareConnection
|
||||
: CreateDbContextStrategyEnum.IndependentConnectionQuery;
|
||||
var dbContext = GetShardingDbContext().GetDbContext(sqlRouteUnit.DataSourceName, strategy, routeTail);
|
||||
if (parallelQuery && RealConnectionMode(connectionMode) == ConnectionModeEnum.MEMORY_STRICTLY)
|
||||
{
|
||||
_parallelDbContexts.TryAdd(dbContext, null);
|
||||
}
|
||||
|
||||
var dbContext = GetShardingDbContext().GetDbContext(sqlRouteUnit.DataSourceName, CreateDbContextStrategyEnum.IndependentConnectionQuery, routeTail);
|
||||
_parallelDbContexts.TryAdd(dbContext, null);
|
||||
|
||||
return dbContext;
|
||||
}
|
||||
|
@ -402,5 +396,32 @@ namespace ShardingCore.Sharding
|
|||
ReSetOrders(propertyOrders);
|
||||
}
|
||||
}
|
||||
#if !EFCORE2
|
||||
|
||||
public async ValueTask<bool> DbContextDisposeAsync(DbContext dbContext)
|
||||
{
|
||||
if (_parallelDbContexts.TryRemove(dbContext, out var _))
|
||||
{
|
||||
await dbContext.DisposeAsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#if EFCORE2
|
||||
|
||||
public Task<bool> DbContextDisposeAsync(DbContext dbContext)
|
||||
{
|
||||
if (_parallelDbContexts.TryRemove(dbContext, out var _))
|
||||
{
|
||||
dbContext.Dispose();
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -34,6 +34,9 @@
|
|||
<Compile Update="..\..\src\ShardingCore\Sharding\ShardingExecutors\CustomerQueryScope.cs">
|
||||
<Link>Sharding\ShardingExecutors\CustomerQueryScope.cs</Link>
|
||||
</Compile>
|
||||
<Compile Update="..\..\src\ShardingCore\Sharding\MergeEngines\Executors\Enumerators\FirstOrDefaultEnumeratorExecutor.cs">
|
||||
<Link>Sharding\MergeEngines\Executors\Enumerators\FirstOrDefaultEnumeratorExecutor.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue