I've got a Vaadin application and I'm getting some strange behaviour when running two instances of the application at the same time (one in FF, another in IE). I've already removed most static objects (these caused the application to completely reload when used parallel to another open application) and now I can interact normally with the UI without the complete reset. However, I'm now noticing that I'm getting only one user's data in both interfaces. I assume this is caused by singleton objects I'm using to manage some data caching and a SOAP connection. I'd like to know if it's the singleton pattern itself that's causing the strange output or is it just the static instance object I'm keeping?
I've tried using ThreadLocal with my singleton, but all my variables are always null when I try to use them in my singleton's functions. Currently my singleton contains this, which is probably terribly, terribly wrong since it doesn't work.
private static ThreadLocal<SoapClient> instance = new ThreadLocal<SoapClient>();
public static synchronized SoapClient getInstance(){
if (instance.get() == null) {
instance.set(new SoapClient());
}
return instance.get();
}
I chose a singleton object so I'd always have access to the cached data and my user's soap connection everywhere in my application instance, and the only other way I can think of for doing that is to have a static object somewhere, but the static keyword seems to be the cause of all my problems in the first place. Is there any way around this or is there something else causing it?
A better way to instantiate your thread local would be this
ThreadLocal<SoapClient> instance = new ThreadLocal<String>() {
#Override
protected String initialValue() {
return new SoapClient();
}
}
However, your problem here is web app servers "pool" and re-use threads. In Vaadin terms,not every request for an application is processed same thread - i.e. Thread1 could process requests for both App instance 1 and App Instance 2. If your SoapClient caches information appropriate to App instance 1, the UI for App 2 could end up using the SoapClient for App 1.
Assuming (from your description) that "app specific" information is cached in the SoapClient, I would suggest that you
Create and store the SoapClient on your Application object as a normal field (not static, not threadlocal)
If you need to access the application (in order to get the SoapClient), and it's tricky from where you are, use the ThreadLocal access pattern. See the second example on the link. Note that the ThreadLocal is set at the beginning of the HttpRequest, and "unset" at the end, ensuring that any subsequent requests on the same thread do NOT get the same application instance.
Related
In my AspNetCore application, I process messages that arrive from a queue. In order to process a message, I need to resolve some services. Some of those services have a dependency on ITenantId, which I bind using information from the received message. To solve this, the processing of a messages starts with the creation of a child container, which I then use to create an IServiceScope from which I resolve all the needed dependencies.
The messages can be processed in parallel, so the scopes must be isolated from each other.
I can see to ways of creating the child container, but I'm not sure which is best in terms of performance, memory chrurn etc:
Option A: Each time a message arrives, clone the IServiceCollection into a new ServiceCollection, and rebind ITenantId on the cloned instance.
Option B: When the program starts, create an immutable copy of the IServiceCollection (using ImmutableList<ServiceDescriptor> or ImmutableArray<ServiceDescriptor>). Each time a message arrives, replace ITenantId (resulting in a new instance of ImmutableList<ServiceDescriptor>) and call CreateScope() on the new immutable instance.
The thing I don't like about option A is that the whole collection of services needs to be cloned every time a message arrives. I'm not sure if the immutable collections in option B handles this in a smarter way?
Both options cause the creation of a new container instance for each incoming messages. Although this allows each message to run in a completely isolated bubble, this has severe implications on performance and memory use of the application. Creating container instances is expensive and resolving a registered instance for the first time (per container) causes generation of expression trees, compilation of delegates, and JIT compiling them. This can even cause memory leaks.
Besides, it also means that any registered singleton class, will have a lifetime that equals that of any scoped classes. State can't be shared any longer.
So instead, I propose Option 3:
Use only one Container instance and don't call BuildProvider more than once
Create a ITenantId implementation that allows setting the Id after instantiation
Register that implementation as Scoped
At the start of every new IServiceScope, resolve that implementation and set its id.
This might look as follows:
// Code
class TenentIdImpl : ITenantId
{
public Guid Id { get; set; } // settable
}
// Startup:
services.AddScoped<TenentIdImpl>();
services.AddScoped<ITenantId>(c => c.GetRequiredService<TenantIdImpl>());
// In message pipeline
using (var scope = provider.CreateScope())
{
var tenant = scope.ServiceProvider.GetRequiredService<TenantIdImpl>();
tenant.Id = messageEnvelope.TenantId;
var handler =
scope.ServiceProvider.GetRequiredService<IMessageHandler<TMessage>>();
handler.Handle(messageEnvelope.Message);
}
This particular model, where you store state inside your object graph, which I explain in my blog, is called the Closure Composition Model.
I am using spring webflux to call one service from another via Schedulers.elastic()
Mono<Integer> anaNotificationCountObservable = wrapWithRetryForFlux(wrapWithTimeoutForFlux(
notificationServiceMediatorFlux.getANANotificationCountForUser(userId).subscribeOn(reactor.core.scheduler.Schedulers.elastic())
)).onErrorReturn(0);
In main thread i am setting one InhertitableThreadLocal variable and in the child thread I am trying to access it and it is working fine.
This is my class for storing threadlocal
#Component
public class RequestCorrelation {
public static final String CORRELATION_ID = "correlation-id";
private InheritableThreadLocal<String> id = new InheritableThreadLocal<>();
public String getId() {
return id.get();
}
public void setId(final String correlationId) {
id.set(correlationId);
}
public void removeCorrelationId() {
id.remove();
}
}
Now the issue is first time its working fine meaning the value i am setting in threadlocal is passed to other services.
But second time also, it is using old id(generated in last request).
I tried using Schedulers.newSingle() instead of elastic(), then its working fine.
So think since elastic() is re-using threads, thats why it is not able to clear / or it is re-using.
How should i resolve issue.
I am setting thread local in my filter and clearing the same in myfiler
requestCorrelation.setId(UUID.randomUUID().toString());
chain.doFilter(req,res)
requestCorrelation.removeCorrelationId();
You should never tie resources or information to a particular thread when leveraging a reactor pipeline. Reactor is itself scheduling agnostic; developers using your library can choose to schedule work on another scheduler - if you decide to force a scheduling model you might lose performance benefits.
Instead you can store data inside the reactor context. This is a map-like structure that’s tied to the subscriber and independent of the scheduling arrangement.
This is how projects like spring security and micrometer store information that usually belongs in a threadlocal.
I need to extract several header values at the start of each request and place them into a ClientContext object that can be injected into my application code by MEF. I am using Preview 5 of the WCF Web API and don't see a way to do this.
In 'standard' WCF, I would create a class that implements IExtension<OperationContext> and have the following property to wire it all together:
[Export(typeof(IClientContext)]
[PartCreationPolicy(CreationPolicy.NonShared)]
public static ClientContextExtension Current
{
get
{
var operationContext = OperationContext.Current;
if (operationContext == null)
return null;
var extension = operationContext.Extensions.Find<ClientContextExtension>();
if (extension == null)
{
extension = new ClientContextExtension();
operationContext.Extensions.Add(extension);
}
return extension;
}
}
A custom DelegatingHandler calls ClientContextExtension.Current and sets the properties from the header values. Unfortunately, with WCF Web API, OperationContext.Current is always null!
I cannot figure out a way to make this work with the Web API. Any help is appreciated!!!
I've come up with a working solution but remain open to other options. First, some rationale behind the original approach...
Because WCF uses thread pooling, anything based on a per-thread model may (and will) have a lifetime that extends beyond an individual request. I needed a way to store client context information pulled from the HTTP headers for each request as the information will be different each time. This means I can't persist the context information per-thread because the thread will be re-used.
Or can I?
The flaw in my logic was that thread re-use was the problem. In reality, each thread is only every servicing a single request at one time thereby making any information in that thread isolated to that request. Therefore, all I need to do is make sure that the information is relavent to that request and my problem is solved.
My solution was to refactor the Current property to reference a private static field marked with the [ThreadStatic()] attribute, ensuring that each instance was specific to the thread. Then, in my DelegatingHandler, which executes for each request, I reset the properties of the object for that request. Subsequent calls to Current during that request return the request-specific information and the next request handled by the thread gets updated in the DelegatingHandler so as far as my other code is concerned, the context is per-request.
Not perfect, but it at least gets me up and running for the moment. As I said, I am open to other solutions.
UPDATE
Upon closer inspection, this solution is not working as there is no thread affinity between the DelegatingHandler and the service code that is making use of the context object. As a result, sometimes my call to retrieve the ThreadStatic object works as expected but on other occasions I get a new instance because the code is operating on a different thread than the handler.
So, disregard this solution. Back to the drawing board.
UPDATE TO MY UPDATE
After discussing my problem with Glenn Block, it turns out that it is just a matter of making sure the context is set on the same thread the request handler (the service) is executing. The solution is to use an HttpOperationHandler instead of a MessageHandler.
According to Glenn, message handlers operate asynchronously which means they could execute on a different thread from the request handler (service) so we should never do anything in a message handler that requires thread affinity. On the other hand, operation handlers run synchronously on the same thread as the request handler, therefore we can rely on thread affinity.
So, I simply moved my code from a MessageHandler to an HttpOperationHandler and have the desired results.
You can read a full explanation here: http://sonofpirate.blogspot.com/2011/11/modeling-client-context-in-wcf-web-api.html
You can try to use a
HttpOperationHandler<HttpRequestMessage, HttpRequestMessage>
There you should be able to access the headers.
Here is the scenario. I have a WCF service, when this service is called it passes control to an instance of another class (created via Ninject). In that class I need to do some work, specifically with Entity Framework and repositories. To cut a long story short, I have the following binding declared.
Bind<IGenericProductRepository>()
.To<GenericProductRepository>()
.WithConstructorArgument( "context", new StagingDataContext());
When I want to use this repository I have the following.
using (var genericProductRepository = IoC.Resolve<IGenericProductRepository>())
The problem is, that I only get a new instance of genericProductRepository if it's a brand new request, if the method is called multiple times in the same request I get an error stating that the context (the EF context) is already disposed, this is because it seems like I am getting the same instance back that was already disposed in the using statement. To explain it another way, using the Microsoft WCF Test Client, if I invoke it the first time, the code runs fine, if I push the invoke button again (without restarting the test client, i.e. the same request) then it throws this error about it being disposed already.
I have tried to play around with the various "scopes" that come with Ninject, but clearly I am missing something.
So my basic question is, how do I get a new repository whenever it hits that line, instead of using the same one ? Help would be greatly appreciated, I'm really trying to push for my company to adopt Ninject and drop Spring.
Look at your binding again. Even without any knowledge about Ninject you should notice that the instance of your context is created exactly once at the time the binding is defined. But what you want is have a new context on every resolve. Best it is done by not using WithConstructorArgument and let Ninject create the instance. Therefore you have to define a additional binding for the type of context. If this is not possible for some reason you have to use the lazy version of WithConstructorArgument
WithConstructorArgument("context", ctx => new StagingDataContext())
Furthermore, you might want to try The WCF extension for Ninject:
https://github.com/ninject/ninject.extensions.wcf
That way you can get rid of the ServiceLocator like usage.
Greetings, I would like to ask if creating Singleton to have only one active connection to db is a good idea. What i would like to do is:
1) I have a wcf service
2) wcf service gets data from db
3) i would like to create a singleton like this to have only one connection to db:
private static PersistanceSingleton _Instance;
public static PersistanceSingleton Instance
{
get
{
if (_Instance == null)
{
_Instance = new PersistanceSingleton();
}
return _Instance;
}
}
I know this is not an ideal singleton but i just wrote it for this post purpose.
I would like to have some persistance repositories here and which I will be instantiating them in constructor.
Inside my service class I would have the following code inside constructor
_DBPersistanceSingleton = PersistanceSingleton.Instance;
Then when some request comes (e.g. GetUsersRequest) i would like to do something like:
_DBPersistanceSingleton.GetUsers()
Before each call to db is executed I will also check whether SqlConnection is open or not.
Please let me know if this is a good practice. The reason why I think about this solution is because of large number of users that will be connecting to that service via client application
It's not a good practice to reuse SqlConnection like that. Open it when you need it and close it as soon as you're done with it. Connection pooling will work for you under the hood reusing the connection.
No, I'd strongly recommend you don't. What happens if multiple requests come in at the same time? They can't all use the same connection at the same, at best you'd just be introducing a big bottleneck.
Connection pooling is handled automatically for you, and takes the hassle away from you so you don't need to worry about it. Just open and close connections as needed.
Putting the sql connection aside...
This singleton pattern is not thread safe and is a bad idea to use in a multi-threaded application (as your WCF service is likely to be).
With this code, if multiple simultaneous requests arrive, it is possible that multiple instances will be created.