Skip to content

Commit

Permalink
Perf: unset EnableContentResponseOnWrite dotnet#22999
Browse files Browse the repository at this point in the history
  • Loading branch information
umitkavala committed Nov 13, 2020
1 parent b608a57 commit fdb07fc
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,15 @@ public virtual CosmosDbContextOptionsBuilder MaxTcpConnectionsPerEndpoint(int co
public virtual CosmosDbContextOptionsBuilder MaxRequestsPerTcpConnection(int requestLimit)
=> WithOption(e => e.WithMaxRequestsPerTcpConnection(Check.NotNull(requestLimit, nameof(requestLimit))));

/// <summary>
/// Sets the boolean to only return the headers and status code in the Cosmos DB response for write item operation
/// like Create, Upsert, Patch and Replace. Setting the option to false will cause the response to have a null resource.
/// This reduces networking and CPU load by not sending the resource back over the network and serializing it on the client.
/// </summary>
/// <param name="enabled"><see langword="false" /> to have null resource</param>
public virtual CosmosDbContextOptionsBuilder ContentResponseOnWriteEnabled(bool enabled = false)
=> WithOption(e => e.ContentResponseOnWriteEnabled(Check.NotNull(enabled, nameof(enabled))));

/// <summary>
/// Sets an option by cloning the extension used to store the settings. This ensures the builder
/// does not modify options that are already in use elsewhere.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class CosmosOptionsExtension : IDbContextOptionsExtension
private int? _gatewayModeMaxConnectionLimit;
private int? _maxTcpConnectionsPerEndpoint;
private int? _maxRequestsPerTcpConnection;
private bool? _enableContentResponseOnWrite;
private DbContextOptionsExtensionInfo _info;

/// <summary>
Expand Down Expand Up @@ -74,6 +75,7 @@ protected CosmosOptionsExtension([NotNull] CosmosOptionsExtension copyFrom)
_gatewayModeMaxConnectionLimit = copyFrom._gatewayModeMaxConnectionLimit;
_maxTcpConnectionsPerEndpoint = copyFrom._maxTcpConnectionsPerEndpoint;
_maxRequestsPerTcpConnection = copyFrom._maxRequestsPerTcpConnection;
_enableContentResponseOnWrite = copyFrom._enableContentResponseOnWrite;
}

/// <summary>
Expand Down Expand Up @@ -441,6 +443,30 @@ public virtual CosmosOptionsExtension WithMaxRequestsPerTcpConnection(int reques
return clone;
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual bool? EnableContentResponseOnWrite
=> _enableContentResponseOnWrite;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual CosmosOptionsExtension ContentResponseOnWriteEnabled(bool enabled)
{
var clone = Clone();

clone._enableContentResponseOnWrite = enabled;

return clone;
}

/// <summary>
/// A factory for creating the default <see cref="IExecutionStrategy" />, or <see langword="null" /> if none has been
/// configured.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ public class CosmosSingletonOptions : ICosmosSingletonOptions
/// </summary>
public virtual int? MaxRequestsPerTcpConnection { get; private set; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual bool? EnableContentResponseOnWrite { get; private set; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
Expand All @@ -153,6 +161,7 @@ public virtual void Initialize(IDbContextOptions options)
GatewayModeMaxConnectionLimit = cosmosOptions.GatewayModeMaxConnectionLimit;
MaxTcpConnectionsPerEndpoint = cosmosOptions.MaxTcpConnectionsPerEndpoint;
MaxRequestsPerTcpConnection = cosmosOptions.MaxRequestsPerTcpConnection;
EnableContentResponseOnWrite = cosmosOptions.EnableContentResponseOnWrite;
}
}

Expand All @@ -179,7 +188,9 @@ public virtual void Validate(IDbContextOptions options)
|| IdleTcpConnectionTimeout != cosmosOptions.IdleTcpConnectionTimeout
|| GatewayModeMaxConnectionLimit != cosmosOptions.GatewayModeMaxConnectionLimit
|| MaxTcpConnectionsPerEndpoint != cosmosOptions.MaxTcpConnectionsPerEndpoint
|| MaxRequestsPerTcpConnection != cosmosOptions.MaxRequestsPerTcpConnection))
|| MaxRequestsPerTcpConnection != cosmosOptions.MaxRequestsPerTcpConnection
|| EnableContentResponseOnWrite != cosmosOptions.EnableContentResponseOnWrite
))
{
throw new InvalidOperationException(
CoreStrings.SingletonOptionChanged(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,14 @@ public interface ICosmosSingletonOptions : ISingletonOptions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
int? MaxRequestsPerTcpConnection { get; }


/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
bool? EnableContentResponseOnWrite { get; }
}
}
19 changes: 14 additions & 5 deletions src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,8 @@ private async Task<bool> CreateItemOnceAsync(

var entry = parameters.Entry;
var container = Client.GetDatabase(_databaseId).GetContainer(parameters.ContainerId);
var itemRequestOptions = CreateItemRequestOptions(entry);
var enableContentResponseOnWrite = ((ICosmosSingletonOptions)Client.ClientOptions).EnableContentResponseOnWrite;
var itemRequestOptions = CreateItemRequestOptions(entry, enableContentResponseOnWrite);
var partitionKey = CreatePartitionKey(entry);

using var response = await container.CreateItemStreamAsync(stream, partitionKey, itemRequestOptions, cancellationToken)
Expand Down Expand Up @@ -354,7 +355,10 @@ private async Task<bool> ReplaceItemOnceAsync(

var entry = parameters.Entry;
var container = Client.GetDatabase(_databaseId).GetContainer(parameters.ContainerId);
var itemRequestOptions = CreateItemRequestOptions(entry);

var enableContentResponseOnWrite = ((ICosmosSingletonOptions)Client.ClientOptions).EnableContentResponseOnWrite;
var itemRequestOptions = CreateItemRequestOptions(entry, enableContentResponseOnWrite);

var partitionKey = CreatePartitionKey(entry);

using var response = await container.ReplaceItemStreamAsync(
Expand Down Expand Up @@ -416,7 +420,10 @@ public virtual async Task<bool> DeleteItemOnceAsync(
{
var entry = parameters.Entry;
var items = Client.GetDatabase(_databaseId).GetContainer(parameters.ContainerId);
var itemRequestOptions = CreateItemRequestOptions(entry);

var enableContentResponseOnWrite = ((ICosmosSingletonOptions)Client.ClientOptions).EnableContentResponseOnWrite;

var itemRequestOptions = CreateItemRequestOptions(entry, enableContentResponseOnWrite);
var partitionKey = CreatePartitionKey(entry);

using var response = await items.DeleteItemStreamAsync(
Expand All @@ -427,7 +434,7 @@ public virtual async Task<bool> DeleteItemOnceAsync(
return response.StatusCode == HttpStatusCode.NoContent;
}

private static ItemRequestOptions CreateItemRequestOptions(IUpdateEntry entry)
private static ItemRequestOptions CreateItemRequestOptions(IUpdateEntry entry, bool? enableContentResponseOnWrite)
{
var etagProperty = entry.EntityType.GetETagProperty();
if (etagProperty == null)
Expand All @@ -442,7 +449,9 @@ private static ItemRequestOptions CreateItemRequestOptions(IUpdateEntry entry)
etag = converter.ConvertToProvider(etag);
}

return new ItemRequestOptions { IfMatchEtag = (string)etag };


return new ItemRequestOptions { IfMatchEtag = (string)etag, EnableContentResponseOnWrite = enableContentResponseOnWrite };
}

private static PartitionKey CreatePartitionKey(IUpdateEntry entry)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ public SingletonCosmosClientWrapper([NotNull] ICosmosSingletonOptions options)
configuration.MaxRequestsPerTcpConnection = options.MaxRequestsPerTcpConnection.Value;
}

if (options.EnableContentResponseOnWrite != null)
{
configuration.EnableTcpConnectionEndpointRediscovery = options.EnableContentResponseOnWrite.Value;
}

_options = configuration;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,5 +191,20 @@ public void Can_create_options_with_max_requests_per_tcp_connection()

Assert.Equal(requestLimit, extension.MaxRequestsPerTcpConnection);
}

[ConditionalFact]
public void Can_create_options_with_content_response_on_write_enabled()
{
var enabled = true;
var options = new DbContextOptionsBuilder().UseCosmos(
"serviceEndPoint",
"authKeyOrResourceToken",
"databaseName",
o => { o.ContentResponseOnWriteEnabled(enabled); });

var extension = options.Options.FindExtension<CosmosOptionsExtension>();

Assert.Equal(enabled, extension.EnableContentResponseOnWrite);
}
}
}

0 comments on commit fdb07fc

Please sign in to comment.