I'm a little confused with Resolvers for routes. The problem that Resolvers solve for me is that an object is present in the component at rendering time. If I do it without Resolvers and start fetching objects in a component's constructor via Promise, accessing its nested properties in the template like
{{myObj.foo.bar}}
could lead to an error if the Promise does not resolve early enough, which is very likely when a http request needs to be done. However, the little info about receiving resolved objects from a Resolver tells me to do it like this in the component's constructor
this.route.data.subscribe(val => {...});
Isn't this the same sh*t as before? Ok, I admit, that the backend request has already finished, and I'll receive the subscription in no time. Nevertheless, I access the resolved data asynchronously again. There may be a very high chance that {{myObj.foo.bar}} is accessible at template rendering, but there is no guarantee, isn't it?
I don't know if I see that too critical. It's a gut feeling that using canActivate for the route and setting the resolved object to a Service that, in turn, can be accessed by any component synchronously comes closer to my intention, though.
Looking forward to clarifications
Wrap the whole template or parts where you need to access myObj with *ngIf:
<ng-container *ngIf="myObj?.foo">
{{myObj.foo.bar}}
</ng-container>
Related
In a console application I'm using masstransit to process messages coming from a rabbitMQ queue. Every message deals with a specific customer and contains a customterId (this could be in header or message, tbd).
I'm using standard Microsoft Dependency Injection and I have several services I wish to be scoped to this customer.
I can use IServiceProvider.CreateScope in the masstransit consumer. But I cannot seem to determine the proper way to set a specific "value" to a scope. Something that every scoped service provided can use to determine the customer for which the scope was defined. Something that the scoped service can use to determine the "context"
My feeling is that I am looking to define something like HttpContext (This off course is not available in console application).
Do I have to do this manually by setting properties on a scoped service on which all other (scoped) services have a dependency? That feels not very thread safe to me (what if a service is instantiated in a scope before I can set the customer property?).
I know this is a little open for a question here, yet maybe someone can still provide an answer?
I would provide code, but this more an architectural question and on internal the workings of MSDI.
MassTransit creates a scope for every consumer, so creating another scope is a bad idea. Any scoped dependencies will be resolved through the consumer's constructor automatically by the container.
Background (TLDR: I need parallel queries)
I am building REST service that needs to be able to answer queries very fast.
As such I'm pre-loading a large part of the database into memory and answering using that data instead of making complex database queries for each request. This works great, and the average response time of the API is well below the requirements and a lot faster than direct database queries.
But I have a problem. The service takes about 5 minutes to start and pre-load all of its information. During this time it can not answer queries.
Problem
I want to change this so that during the pre-load phase it makes database queries until the in-memory cache is loaded.
This leads me to a problem. I need to have multiple active queries to my database. Anyone who has tried this in EF Core has problably seen this message.
System.InvalidOperationException: A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
The first sentence on the linked page is
Entity Framework Core does not support multiple parallel operations
being run on the same DbContext instance.
I thought this would be easily solved by wrapping my cache-loading into its own class and the direct query into another, and then having both of these requiring their own instance of the Database Context. Then my service can in turn get these injected and use both of these dependencies in parallel.
This should be what I have:
I have also set up my database context so that it uses transient for all parts.
services.AddDbContext<IDataContext, DataContext>(options =>
options.UseSqlServer(connectionString), ServiceLifetime.Transient, ServiceLifetime.Transient
);
I have also enabled MultipleActiveResultSets=True
All of this however results in the exact same error as listed above.
Again, everything is Transient except the HandlerService which is Singelton as I want this to keep a copy of the cache in memory and not have to load it for every request.
What is it I have failed to understand about the ef-core database context, or DI in general?
I figured out what the problem was. In my case there is as described above, one singleton handler. This handler has one (indirect) context (through DI) for fulfilling requests until the cache is loaded. When multiple parallel queries are sent to the API before the cache is loaded, then this error occurs as each of these request are using the same context. And in my test I was always hitting the parallel requests as part of the startup and hence the singelton service was trying to use the same db context for multiple requests. My solution is to in this one place step outside the "normal" dependency injection and use the IServiceScopeFactory to get a new instance of the dependency used to resolve requests before the cache is loaded. Bohdans answer led me to this conclusion and ultimate solution.
I'm not sure whether it qualifies for a full answer but it's too broad for a comment.
When doing .NET core background services which are obviously singletons too I use IServiceScopeFactory to create services with a limited lifetime.
Here's how I create a context
using (var scope = _scopeFactory.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<DbContext>();
}
My guess is that you could inject it in your hander and use it like this too. So it would allow you to leave context as scoped instead of transient with is default setting btw.
Hope that helps.
I am using Atmosphere Framework 2.0.8.
I have implemented an AtmosphereHandler in my application and have two way communication occurring correctly over WebSockets and Long Polling.
I am trying to add some handling code for when the client disconnects to clean up some resources specific to that client (ie. I have an entry in a table I want to remove).
I have read the following wiki entries:
OnDisconnect Tricks: https://github.com/Atmosphere/atmosphere/wiki/onDisconnect-tricks
Configuring Atmosphere Listener: https://github.com/Atmosphere/atmosphere/wiki/Configuring-Atmosphere-Listener
The thing I am not clear on is where I should add the call to
atmosphereResource.addEventListener( new AtmosphereResourceEventListenerAdapter() {} );
I eventually found some example code in the JavaDoc for the AtmosphereHandler that registers the EventListener in the onRequest() method. http://atmosphere.github.io/atmosphere/apidocs/org/atmosphere/cpr/AtmosphereHandler.html
What I would like to know is if this is the correct way to go about it?
It is my understanding that the AtmosphereResource represents the connection between a client and the server for the life of that connection. The uuid stays consistent for the object on multiple calls through the onRequest() method from the same client. As such, the same AtmosphereResource object will get the EventListener added every time the onRequest method is called.
This seems wrong. Wouldn't this lead to thousands of EventListeners being registered for each AtmosphereResource?
It seems that the EventLister should only be registered once for each AtmosphereResource.
I feel like I am missing something fundamental here. Could someone please explain?
Here's an example using MeteorServlet, so it won't look exactly like what you'll have to do, but it should get you started. I add the listener to a Meteor instance, and you'll add yours to an AtmosphereResource. Each resource gets just one listener.
The overridden onDisconnect() method calls this Grails service method that handles the event. Of course, you'll want to call something that cleans up your database resource.
Note that the servlet is configured using these options. I think you might need the org.atmosphere.interceptor.HeartbeatInterceptor, but it's been so long since I initially set it up, I can't remember if it's necessary.
So I'm integrating SignalR and HotTowel, although really I think this is a matter of how to integrate with Durandal itself.
The issue is I have obviously multiple views. Some of these views I want to respond to SignalR messages. The question is how to do this integration considering that SignalR events have to be started before I call SignalR's hub start method.
So take the example I have view1 and view2. I want each to do something when a SignalR message is received and in the context of that view (so let's say update the DOM somehow). It's an SPA obviously so calling the SignalR start method for each view seems like a bad idea, so starting SignalR once at boot sounds like the right plan, but at that point my views may not have been loaded, and still how would I ensure that my events have the right context for the page.
This is based on my understanding that all events for SignalR have to be registered before I call start. Any thoughts clever people of StackOverflow?
Edit to expand on the problem
Part of the website involves uploading files for parsing and processing to import into a database. I have created a view where the file is selected and uploaded (using FineUploader) to a WebApiController. The controller does the basic steps of checking the uploaded file and then starts an async task to actually do the parsing and processing, while immediately returning the basic "Yep that uploaded fine" message.
This causes the list of 'in progress' files to refresh and the file appears with an 'Uploaded' status. As the async task occurs, the file is parsed, then processed against a rules system, and then finally imported into another back end data store. As each of these status changes occur, SignalR sends messages to the client to notify them of these changes, and thus update the status against the filename. In order for this to occur I must attach a function to the event as it received in SignalR. That even needs some kind of reference to my view (actually viewmodel) so it can update the correct value.
As SignalR should be started once with a call to hub.Start(), I am trying to do it during the 'boot' phase. However when my SPA starts, that view has not been loaded, and therefore neither has that viewmodel, and therefore my function that is responsible for initialising SignalR can have no understanding of the view/viewmodel it must update.
Examples I've seen on using SignalR show it being used in one view, but that doesn't really work surely if you need it in multiple views (you can't just keep calling hub.start() can you)?
Sorry, if this still doesn't make sense I'll post some code or something.
If you use
$.connection.myHub.on("myMethod", function (/* ... */) { /* ... */ });
instead of
$.connection.myHub.client.myMethod = function (/* ... */) { /* ... */ };
you can add client-side hub methods after calling $.connection.hub.start();
In one of the projects I'm working a custom 404 page needs to be implemented for each bundle.
Inside the documentation there is nothing mentioned for such functionality.
I was discussing the issue with some colleagues and was told that it has to use the kernel.exception event, alas this one lacks the information which bundle is calling it.
IMHO this should be fixed by applying a patch to symfony router component which would allow the developer to specify catch-all route which could handle the case further.
Another option would be to change the behavior of the RouterInterface::match method to return consistent output containing the matched path and the bundle which matched it. Currently this is not possible, because it throws an exception if match fails and does not give you any information at all, while it could.
For example, I have an ApiBundle which is defined to handle urls starting with "/api". Currently the only way to handle this one and set custom 404 page is to get the request at the time of the kernel.exception and preg_match() the url. This, however, is hardcoding that should be avoided as the bundle should not have such knowledge - it is defined under the app/config/routing file.
What's your opinion?
I would appreciate any other workarounds as well.
I've ended up implementing my custom ExceptionController which dispatches an event I called 'ourCompany.exception_response'.
The default bundle has a listener set with priority -1024.
If custom bundle processes the exception and sets its response, the event has to be marked and the propagation to be stopped.
The custom bundle can use the service container to get whatever it wants in order to determine whether to process the exception or no.