-
Notifications
You must be signed in to change notification settings - Fork 138
Thread-safe GetModelAsync #306
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
Conversation
This ONLY synchronizes multiple simultaneous calls to model building pipeline, WebApiConfig still could return before a long running GetModelAsync completes.
src/Microsoft.Restier.Core/Api.cs
Outdated
| var builder = context.GetApiService<IModelBuilder>(); | ||
| if (builder == null) | ||
| { | ||
| return null; |
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.
Maybe we should throw if there is no model builder? It is more meaningful than a later null-reference exception.
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.
Ok, thanks.
The message I put into Resources is "IEdmModel cannot be generated since API service IModelBuilder is not registered."
Let me know better description.
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.
That sounds good:-) Thanks.
|
So basically this PR is to make any call to |
| source.SetResult(model); | ||
| return model; | ||
| } | ||
| catch (AggregateException e) |
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.
Are we going to do anything special for an AggregateException in the future? If not, we may consider merge the two catch-clauses.
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.
If we catch AggregatedException as normal Exception, and SetException to the task, the task will wrap it again and so ends with an AggreatedException, which has an inner AggregatedException, which has the actual exceptions as its InnerExceptions.
Perhaps I don't get your idea clearly, since GetModelAsync works on ApiConfiguration, so calling it with any model instance will be synchronized. So, if a query needs EdmModel to complete, an RegisterNorthwind could have returned before the route is completely registered. So if the model generation is really costly, RESTier routing will likely get messed up. |
Throw on IModelBuilder missing.
|
@rayao Yeah, I understand your concern about requests coming before the route has been completely registered. But in this case, since the route has not been registered yet. The service could safely return 404 for those requests. And what I was thinking about was that you can't process any OData request without getting the model instance (parse URI or serialization/deserialization). Now the model instance is registered staticly into |
|
I've no other questions, please feel free to merge it. |
@lewischeng-ms This is only true for synchronous long running GetModelAsync call (like all of our existing samples, although they return task but they're synchronous in nature). A truly async GetModelAsync call won't have the chance to registered a route before WebApiConfig pipeline ends, and that results in RESTier routing not established, no further requests could be processed.
Yeah I initially thought that, but since the route selection pipeline is synchronous, we can't await. |
This ONLY synchronizes multiple simultaneous calls to model building pipeline, WebApiConfig still could return before a long running GetModelAsync completes.
Partially resolve #304