-
Notifications
You must be signed in to change notification settings - Fork 475
Fix memory leak in ModelContainer - #1101 #1506
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
2d91e89
1db4faa
c24bf7d
8f0bc23
efb145c
958b56a
b410832
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
using Microsoft.AspNet.OData.Common; | ||
using Microsoft.AspNet.OData.Formatter; | ||
using Microsoft.AspNet.OData.Query; | ||
using Microsoft.AspNet.OData.Query.Expressions; | ||
using Microsoft.AspNet.OData.Routing; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.OData.Edm; | ||
|
@@ -20,6 +21,7 @@ namespace Microsoft.AspNet.OData | |
public class ODataQueryContext | ||
{ | ||
private DefaultQuerySettings _defaultQuerySettings; | ||
private string modelId = null; | ||
|
||
/// <summary> | ||
/// Constructs an instance of <see cref="ODataQueryContext"/> with <see cref="IEdmModel" />, element CLR type, | ||
|
@@ -72,18 +74,30 @@ public ODataQueryContext(IEdmModel model, IEdmType elementType, ODataPath path) | |
{ | ||
throw Error.ArgumentNull("model"); | ||
} | ||
|
||
if (elementType == null) | ||
{ | ||
throw Error.ArgumentNull("elementType"); | ||
} | ||
|
||
Model = model; | ||
ElementType = elementType; | ||
Model = model; | ||
Path = path; | ||
NavigationSource = GetNavigationSource(Model, ElementType, path); | ||
GetPathContext(); | ||
} | ||
|
||
/// <summary> | ||
/// Destructor called to clean up reference in ModelContainer | ||
/// </summary> | ||
~ODataQueryContext() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we use the IDisposable pattern instead of destructor? |
||
{ | ||
if (this.modelId != null) | ||
{ | ||
ModelContainer.RemoveModelId(ModelId); | ||
} | ||
} | ||
|
||
internal ODataQueryContext(IEdmModel model, Type elementClrType) | ||
: this(model, elementClrType, path: null) | ||
{ | ||
|
@@ -152,6 +166,19 @@ public DefaultQuerySettings DefaultQuerySettings | |
|
||
internal string TargetName { get; private set; } | ||
|
||
internal string ModelId | ||
{ | ||
get | ||
{ | ||
if (this.modelId == null) | ||
{ | ||
this.modelId = ModelContainer.GetModelID(this.Model); | ||
} | ||
|
||
return this.modelId; | ||
} | ||
} | ||
|
||
private static IEdmNavigationSource GetNavigationSource(IEdmModel model, IEdmType elementType, ODataPath odataPath) | ||
{ | ||
Contract.Assert(model != null); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ | |
using Microsoft.AspNet.OData.Common; | ||
using Microsoft.AspNet.OData.Extensions; | ||
using Microsoft.AspNet.OData.Formatter; | ||
using Microsoft.AspNet.OData.Interfaces; | ||
using Microsoft.AspNet.OData.Query; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Mvc; | ||
|
@@ -247,5 +248,41 @@ public virtual IEdmModel GetModel( | |
Contract.Assert(model != null); | ||
return model; | ||
} | ||
|
||
/// <summary> | ||
/// Register the QueryContext with the Request so that it doesn't get garbage collected early | ||
/// </summary> | ||
/// <param name="request">The HTTPRequestMessage to register with</param> | ||
/// <param name="queryContext">The ODataQueryContext to be registered</param> | ||
private static void RegisterContext(IWebApiRequestMessage request, ODataQueryContext queryContext) | ||
{ | ||
HttpRequestScope httpRequestScope = request.RequestContainer.GetService(typeof(HttpRequestScope)) as HttpRequestScope; | ||
HttpRequest httpRequest = httpRequestScope == null ? null : httpRequestScope.HttpRequest; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: extra space |
||
|
||
if (httpRequest != null) | ||
{ | ||
HttpContext context = httpRequest.HttpContext; | ||
ODataQueryContextCacheFeature queryCache = context.Features.Get<ODataQueryContextCacheFeature>(); | ||
if (queryCache == null) | ||
{ | ||
lock (context.Features) | ||
{ | ||
queryCache = context.Features.Get<ODataQueryContextCacheFeature>(); | ||
if (queryCache == null) | ||
{ | ||
queryCache = new ODataQueryContextCacheFeature(); | ||
context.Features.Set<ODataQueryContextCacheFeature>(queryCache); | ||
} | ||
} | ||
} | ||
|
||
queryCache.Add(queryContext); | ||
} | ||
} | ||
|
||
private class ODataQueryContextCacheFeature : List<ODataQueryContext> | ||
{ | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -483,6 +483,8 @@ public class Microsoft.AspNet.OData.ODataQueryContext { | |
Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; } | ||
ODataPath Path { public get; } | ||
System.IServiceProvider RequestContainer { public get; } | ||
|
||
protected virtual void Finalize () | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. need to change the Core version publicApi.bsl |
||
} | ||
|
||
public class Microsoft.AspNet.OData.ODataSwaggerConverter { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Core version, to use "ODataFeature" to add the Per-request information.
In Classic version, to use "ODataProperties" to add the Per-request information.