Skip to content

Commit b058432

Browse files
authored
Merge branch 'master' into master
2 parents c1937d1 + b257f8e commit b058432

13 files changed

+297
-267
lines changed

Directory.Build.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<ClientOfficialVersion>3.32.0</ClientOfficialVersion>
44
<ClientPreviewVersion>3.32.0</ClientPreviewVersion>
55
<ClientPreviewSuffixVersion>preview</ClientPreviewSuffixVersion>
6-
<DirectVersion>3.30.1</DirectVersion>
6+
<DirectVersion>3.30.2</DirectVersion>
77
<EncryptionOfficialVersion>2.0.1</EncryptionOfficialVersion>
88
<EncryptionPreviewVersion>2.0.1</EncryptionPreviewVersion>
99
<EncryptionPreviewSuffixVersion>preview</EncryptionPreviewSuffixVersion>

Microsoft.Azure.Cosmos.Samples/Tools/CTL/CTLConfig.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace CosmosCTL
1111
using CommandLine.Text;
1212
using Microsoft.Azure.Cosmos;
1313
using Newtonsoft.Json;
14+
using static CosmosCTL.ReservoirProvider;
1415

1516
public class CTLConfig
1617
{
@@ -76,7 +77,7 @@ public string DiagnosticsThresholdDuration
7677
}
7778

7879
[Option("ctl_content_response_on_write", Required = false, HelpText = "Should return content response on writes")]
79-
public bool IsContentResponseOnWriteEnabled { get; set; } = true;
80+
public bool? IsContentResponseOnWriteEnabled { get; set; } = true;
8081

8182
[Option("ctl_output_event_traces", Required = false, HelpText = "Outputs TraceSource to console")]
8283
public bool OutputEventTraces { get; set; } = false;
@@ -102,6 +103,12 @@ public string DiagnosticsThresholdDuration
102103
[Option("ctl_telemetry_schedule_in_sec", Required = false, HelpText = "telemetry task schedule time in sec")]
103104
public string TelemetryScheduleInSeconds { get; set; }
104105

106+
[Option("ctl_reservoir_type", Required = false, HelpText = "Defines the reservoir type. Valid values are: Uniform, SlidingWindow and ExponentialDecay. The default value is SlidingWindow.")]
107+
public ReservoirTypes ReservoirType { get; set; } = ReservoirTypes.SlidingWindow;
108+
109+
[Option("ctl_reservoir_sample_size", Required = false, HelpText = "The reservoir sample size.")]
110+
public int ReservoirSampleSize { get; set; } = 1028;
111+
105112
internal TimeSpan RunningTimeDurationAsTimespan { get; private set; } = TimeSpan.FromHours(10);
106113
internal TimeSpan DiagnosticsThresholdDurationAsTimespan { get; private set; } = TimeSpan.FromSeconds(60);
107114

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
//------------------------------------------------------------
4+
5+
namespace CosmosCTL
6+
{
7+
using System;
8+
using App.Metrics.ReservoirSampling;
9+
10+
/// <summary>
11+
/// Returns the <see cref="IReservoir"/> based on the CTL configuration.
12+
/// </summary>
13+
public class ReservoirProvider
14+
{
15+
/// <summary>
16+
/// Create and returns a new instance of the <see cref="IReservoir"/> based on the CTL configuration.
17+
/// </summary>
18+
/// <param name="ctlConfig">An instance of <see cref="CTLConfig"/> containing the CTL config params.</param>
19+
/// <returns>An implementation of <see cref="IReservoir"/>.</returns>
20+
public static IReservoir GetReservoir(CTLConfig ctlConfig)
21+
{
22+
return ctlConfig.ReservoirType switch
23+
{
24+
ReservoirTypes.Uniform => new App.Metrics.ReservoirSampling.Uniform.DefaultAlgorithmRReservoir(
25+
sampleSize: ctlConfig.ReservoirSampleSize),
26+
27+
ReservoirTypes.SlidingWindow => new App.Metrics.ReservoirSampling.SlidingWindow.DefaultSlidingWindowReservoir(
28+
sampleSize: ctlConfig.ReservoirSampleSize),
29+
30+
ReservoirTypes.ExponentialDecay => new App.Metrics.ReservoirSampling.ExponentialDecay.DefaultForwardDecayingReservoir(
31+
sampleSize: ctlConfig.ReservoirSampleSize,
32+
alpha: 0.015),
33+
34+
_ => throw new ArgumentException(
35+
message: "Invalid ReservoirType Specified."),
36+
};
37+
}
38+
39+
/// <summary>
40+
/// An enum containing different reservoir types.
41+
/// </summary>
42+
public enum ReservoirTypes
43+
{
44+
Uniform,
45+
SlidingWindow,
46+
ExponentialDecay
47+
}
48+
}
49+
}

Microsoft.Azure.Cosmos.Samples/Tools/CTL/Scenarios/ChangeFeedPullScenario.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public async Task RunAsync(
6464
DurationUnit = TimeUnit.Milliseconds,
6565
RateUnit = TimeUnit.Seconds,
6666
Context = loggingContextIdentifier,
67-
Reservoir = () => new App.Metrics.ReservoirSampling.Uniform.DefaultAlgorithmRReservoir()
67+
Reservoir = () => ReservoirProvider.GetReservoir(config)
6868
};
6969

7070
Container container = cosmosClient.GetContainer(config.Database, config.Collection);

Microsoft.Azure.Cosmos.Samples/Tools/CTL/Scenarios/ReadManyScenario.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public async Task RunAsync(
7676
DurationUnit = TimeUnit.Milliseconds,
7777
RateUnit = TimeUnit.Seconds,
7878
Context = loggingContextIdentifier,
79-
Reservoir = () => new App.Metrics.ReservoirSampling.Uniform.DefaultAlgorithmRReservoir()
79+
Reservoir = () => ReservoirProvider.GetReservoir(config)
8080
};
8181

8282
Container container = cosmosClient.GetContainer(config.Database, config.Collection);

Microsoft.Azure.Cosmos.Samples/Tools/CTL/Scenarios/ReadWriteQueryScenario.cs

+7-7
Original file line numberDiff line numberDiff line change
@@ -105,34 +105,34 @@ private async Task ExecuteOperationsAsync(
105105
CounterOptions querySuccessMeter = new CounterOptions { Name = "#Query Successful Operations", Context = loggingContextIdentifier };
106106
CounterOptions queryFailureMeter = new CounterOptions { Name = "#Query Unsuccessful Operations", Context = loggingContextIdentifier };
107107

108-
TimerOptions readLatencyTimer = new TimerOptions
108+
TimerOptions readLatencyTimer = new()
109109
{
110110
Name = "Read latency",
111111
MeasurementUnit = Unit.Requests,
112112
DurationUnit = TimeUnit.Milliseconds,
113113
RateUnit = TimeUnit.Seconds,
114114
Context = loggingContextIdentifier,
115-
Reservoir = () => new App.Metrics.ReservoirSampling.Uniform.DefaultAlgorithmRReservoir()
115+
Reservoir = () => ReservoirProvider.GetReservoir(config)
116116
};
117117

118-
TimerOptions writeLatencyTimer = new TimerOptions
118+
TimerOptions writeLatencyTimer = new ()
119119
{
120120
Name = "Write latency",
121121
MeasurementUnit = Unit.Requests,
122122
DurationUnit = TimeUnit.Milliseconds,
123123
RateUnit = TimeUnit.Seconds,
124124
Context = loggingContextIdentifier,
125-
Reservoir = () => new App.Metrics.ReservoirSampling.Uniform.DefaultAlgorithmRReservoir()
125+
Reservoir = () => ReservoirProvider.GetReservoir(config)
126126
};
127127

128-
TimerOptions queryLatencyTimer = new TimerOptions
128+
TimerOptions queryLatencyTimer = new ()
129129
{
130130
Name = "Query latency",
131131
MeasurementUnit = Unit.Requests,
132132
DurationUnit = TimeUnit.Milliseconds,
133133
RateUnit = TimeUnit.Seconds,
134134
Context = loggingContextIdentifier,
135-
Reservoir = () => new App.Metrics.ReservoirSampling.Uniform.DefaultAlgorithmRReservoir()
135+
Reservoir = () => ReservoirProvider.GetReservoir(config)
136136
};
137137

138138
SemaphoreSlim concurrencyControlSemaphore = new SemaphoreSlim(config.Concurrency);
@@ -178,7 +178,7 @@ private async Task ExecuteOperationsAsync(
178178
operation: i,
179179
partitionKeyAttributeName: config.CollectionPartitionKey,
180180
containers: initializationResult.Containers,
181-
isContentResponseOnWriteEnabled: config.IsContentResponseOnWriteEnabled)),
181+
isContentResponseOnWriteEnabled: config.IsContentResponseOnWriteEnabled.Value)),
182182
onSuccess: () =>
183183
{
184184
concurrencyControlSemaphore.Release();

Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs

+14-16
Original file line numberDiff line numberDiff line change
@@ -755,22 +755,9 @@ private static Documents.PartitionKeyDefinition GetPartitionKeyDefinition(InputP
755755
{
756756
if (!inputParameters.EnableOptimisticDirectExecution) return null;
757757

758-
// case 1: Is query going to a single partition
759-
bool hasPartitionKey = inputParameters.PartitionKey.HasValue
760-
&& inputParameters.PartitionKey != PartitionKey.Null
761-
&& inputParameters.PartitionKey != PartitionKey.None;
762-
763-
// case 2: does query execution plan have a single query range
764-
bool hasQueryRanges = partitionedQueryExecutionInfo != null
765-
&& partitionedQueryExecutionInfo.QueryRanges.Count == 1
766-
&& partitionedQueryExecutionInfo.QueryRanges[0].IsSingleValue;
767-
768-
if (!hasPartitionKey && !hasQueryRanges) return null;
769-
770-
//TODO: does collection have only one physical partition
771-
772-
List<Documents.PartitionKeyRange> targetRanges = new List<Documents.PartitionKeyRange>();
758+
Debug.Assert(containerQueryProperties.ResourceId != null, "CosmosQueryExecutionContextFactory Assert!", "Container ResourceId cannot be null!");
773759

760+
List<Documents.PartitionKeyRange> targetRanges;
774761
if (partitionedQueryExecutionInfo != null)
775762
{
776763
targetRanges = await CosmosQueryExecutionContextFactory.GetTargetPartitionKeyRangesAsync(
@@ -785,15 +772,26 @@ private static Documents.PartitionKeyDefinition GetPartitionKeyDefinition(InputP
785772
else
786773
{
787774
Documents.PartitionKeyDefinition partitionKeyDefinition = GetPartitionKeyDefinition(inputParameters, containerQueryProperties);
788-
if (partitionKeyDefinition != null && containerQueryProperties.ResourceId != null && inputParameters.PartitionKey != null)
775+
if (inputParameters.PartitionKey != null)
789776
{
777+
Debug.Assert(partitionKeyDefinition != null, "CosmosQueryExecutionContextFactory Assert!", "PartitionKeyDefinition cannot be null if partitionKey is defined");
778+
790779
targetRanges = await cosmosQueryContext.QueryClient.GetTargetPartitionKeyRangesByEpkStringAsync(
791780
cosmosQueryContext.ResourceLink,
792781
containerQueryProperties.ResourceId,
793782
inputParameters.PartitionKey.Value.InternalKey.GetEffectivePartitionKeyString(partitionKeyDefinition),
794783
forceRefresh: false,
795784
trace);
796785
}
786+
else
787+
{
788+
targetRanges = await cosmosQueryContext.QueryClient.GetTargetPartitionKeyRangesAsync(
789+
cosmosQueryContext.ResourceLink,
790+
containerQueryProperties.ResourceId,
791+
new List<Documents.Routing.Range<string>> { FeedRangeEpk.FullRange.Range },
792+
forceRefresh: false,
793+
trace);
794+
}
797795
}
798796

799797
if (targetRanges.Count == 1)

Microsoft.Azure.Cosmos/src/Resource/CosmosExceptions/CosmosNullReferenceException.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ internal class CosmosNullReferenceException : NullReferenceException
2525
/// </summary>
2626
internal CosmosNullReferenceException(
2727
NullReferenceException originalException,
28-
ITrace trace)
28+
ITrace trace)
29+
: base(originalException?.Message ?? throw new ArgumentNullException(nameof(originalException)), originalException ?? throw new ArgumentNullException(nameof(originalException)))
2930
{
30-
this.originalException = originalException ?? throw new ArgumentNullException(nameof(originalException));
31+
this.originalException = originalException;
3132

3233
if (trace == null)
3334
{

0 commit comments

Comments
 (0)