Skip to content
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

Intermittent/concurrency error on serialization in aspnetcore odata 7.5.4 #2390

Closed
houbi56 opened this issue Jan 5, 2021 · 5 comments
Closed

Comments

@houbi56
Copy link

houbi56 commented Jan 5, 2021

Getting intermittent serialization errors in 7.5.4 under load, worked without issues in 7.5.2

We use a class IgnoreDefaultEntityPropertiesSerializer : ODataResourceSerializer that on CreateStructuralProperty returns null if
the value of the created ODataproperty is of primitive type and has a default value.
Prop is created by calling base.CreateStructuralProperty(structuralProperty, resourceContext);

The error happens when multiple (16) concurrent calls are made from a webpage, typically 10-20% of the time one of the calls will fail with the error:
System.InvalidOperationException: The EDM instance of type '[xxx Nullable=True]' is missing the property 'yyy'..

--
System.InvalidOperationException: The EDM instance of type '[xxx Nullable=True]' is missing the property 'yyy'.
at Microsoft.AspNet.OData.ResourceContext.GetPropertyValue(String propertyName)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.CreateStructuralProperty(IEdmStructuralProperty structuralProperty, ResourceContext resourceContext)
at [ournamespace].Server.Configuration.Serialization.IgnoreDefaultEntityPropertiesSerializer.CreateStructuralProperty(IEdmStructuralProperty structuralProperty, ResourceContext resourceContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.CreateStructuralPropertyBag(SelectExpandNode selectExpandNode, ResourceContext resourceContext)


@houbi56 houbi56 closed this as completed Jan 5, 2021
@houbi56 houbi56 reopened this Jan 5, 2021
@xuzhg
Copy link
Member

xuzhg commented Jan 12, 2021

@houbi56 Could you please share us a simple repro to dig more?

@houbi56
Copy link
Author

houbi56 commented Jan 13, 2021

@houbi56
Copy link
Author

houbi56 commented Jan 14, 2021

See github repo for repro
I get the exception below when performing 20 concurrent calls. Seems that $select as of 7.5.4 is no longer thread-safe?

var c = new HttpClient();
var url = "http://localhost:5000/odata/ODataEntity?$select=Id,SomeOtherProperty";
Parallel.ForEach(Enumerable.Range(1, 20), async (i) =>
{
    var r = await c.GetAsync(url);
});

--

System.InvalidOperationException: The EDM instance of type '[OData_754_Error.ODataEntity Nullable=True]' is missing the property 'SomeProperty'.
at Microsoft.AspNet.OData.ResourceContext.GetPropertyValue(String propertyName)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.CreateStructuralProperty(IEdmStructuralProperty structuralProperty, ResourceContext resourceContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.CreateStructuralPropertyBag(SelectExpandNode selectExpandNode, ResourceContext resourceContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.CreateResource(SelectExpandNode selectExpandNode, ResourceContext resourceContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.WriteResourceAsync(Object graph, ODataWriter writer, ODataSerializerContext writeContext, IEdmTypeReference expectedType)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteResourceSetAsync(IEnumerable enumerable, IEdmTypeReference resourceSetType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteObjectAsync(Object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
at Microsoft.AspNet.OData.Formatter.ODataOutputFormatterHelper.WriteToStreamAsync(Type type, Object value, IEdmModel model, ODataVersion version, Uri baseAddress, MediaTypeHeaderValue contentType, IWebApiUrlHelper internaUrlHelper, IWebApiRequestMessage internalRequest, IWebApiHeaders internalRequestHeaders, Func2 getODataMessageWrapper, Func2 getEdmTypeSerializer, Func2 getODataPayloadSerializer, Func1 getODataSerializerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsyncEnumerable(ActionContext context, ObjectResult result, Object asyncEnumerable, Func`2 reader)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
......

@houbi56 houbi56 changed the title Intermittent error on serialization in aspnetcore odata 7.5.4 Intermittent/concurrency error on serialization in aspnetcore odata 7.5.4 Jan 14, 2021
@houbi56
Copy link
Author

houbi56 commented Jan 14, 2021

Did some more digging.
This PR breaks it #2362.
Fields are used in an actionfilter which (according to MS Docs) is not threadsafe. @RamjotSingh @xuzhg

EnableQueryAttribute

    private ODataQueryOptions CreateAndValidateQueryOptions(HttpRequest request, ODataQueryContext queryContext)
    {
        if (_queryValidationRunBeforeActionExecution)
        {
            //**Below is not thread safe and returns data belonging to different http request** 
            return _processedQueryOptions;
        }

        ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, request);

        ValidateQuery(request, queryOptions);

        return queryOptions;
    }

@houbi56
Copy link
Author

houbi56 commented Jan 20, 2021

Confirm fixed in #2397

@houbi56 houbi56 closed this as completed Jan 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants