Stress Testing - EntityFramework issue - DBContext Creation - entity-framework-6

I am doing stress testing for web api (webapi2) with 20 users on boarding in 0 seconds. I am getting the following errors.
System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.InvalidOperationException: Invalid operation. The connection is closed.
Another error
System.Data.Entity.Core.EntityException: The underlying provider failed on Open. ---> System.InvalidOperationException: The connection was not closed. The connection's current state is connecting.
My code to get the DBContext, each time a new DBContext is getting created:
public static ForcesChecker_Context GetDataContext()
{
return new ForcesChecker_Context();
}
For one web api request this code is getting executed multiple times and multiple instances of this object is getting created. When I call 20 users at a time, it generates 20* ~10 = ~200 objects are created.
My connection string:
Min Pool Size=1;Max Pool Size=200;
It seems there is a race condition.
What settings would help to allow more users to access my system concurrently?

I fixed it. The reason was, Connection Leak. There are other places in the application wherein the DBContext object wasn't disposed properly. Particularly in UnitOfWork class, DBContext object is used, but not disposed inside the Dispose() method. That led to the connection leak. Subsequently, that led to the race condition when new threads (http requests) try to use a connection from the connection pool. Here is the solution code.
public class UnitOfWork: IDisposable, IUnitOfWork
{
ForcesChecker_Context forcesContext; //EntityFramework DBContext
...
public void Dispose()
{
forcesContext.Dispose(); //Leak prevented by this new line.
}
...
}
Thumb rule is, always remember to use Transient Life Time for the DBContext. That is a new instance every time, and dispose them immediately after use.

Related

Why private static variable becomes null at some point and what can I do to resolve?

A picture is worth a thousand words:
On first page load, result is not null but at some point, after some time, when Gmail action is called from Javascript, it becomes null (after one of these 10 minute interval calls). It is declared as private static, initialized in Index action and should be alive (not null) all the time.
I managed to catch it by leaving the app running it in a Debug mode for a few hours.
Thank you.
Why dont you just save the cancellation token and recreate the "result" instance on Gmail() function call ?
private CancellationToken token = token; (on index call)
public ActionResult Gmail() {
result = new Authresult(token);
...
}
To diagnose the problem first it is work to double check whether you are accessing the variable in the same AppDomain where it was initialized - to check this you could just add some logging. It could be possible that this is a different AppDomain, because some event triggered IIS AppDomain pool recycling.
If it is the case, then you have 2 options:
either store the state using another mechanism or
have lazy initialization on demand with a null check, so the value can be initialized each time it's needed

Recover from trigger ERROR state after Job constructor threw an exception?

When using Quartz.net to schedule jobs, I occasionally receive an exception when instantiating a job. This, in turn causes Quartz to set the trigger for the job to an error state. When this occurs, the trigger will cease firing until some manual intervention occurs (restarting the service since I'm using in-memory job scheduling).
How can I prevent the error state from being set, or at the very least, tell Quartz to retry triggers that are in the error state?
The reason for the exception is due to flaky network calls that are required to get configuration data that is passed in to the job's constructor. I'm using a custom IJobFactory to do this.
I've seen other references to this without resolutions:
https://groups.google.com/forum/#!topic/quartznet/8qaT70jfJPw
http://forums.terracotta.org/forums/posts/list/2881.page
For the record, I consider this a design flaw of Quartz. If a job can't be constructed once, that doesn't mean it can't always be constructed. This is a transient error and should be treated as such. Stopping all future scheduled jobs violates the principle of least astonishment.
Anyway, my hack solution is to catch any errors that are the result of my job construction and instead of throwing an error or returning null to return a custom IJob instead that simply logs an error. This isn't perfect, but at least it doesn't prevent future triggering of the job.
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
try
{
var job = this.container.Resolve(bundle.JobDetail.JobType) as IJob;
return job;
}
catch (Exception ex)
{
this.logger.Error(ex, "Exception creating job. Giving up and returning a do-nothing logging job.");
return new LoggingJob(this.logger);
}
}
When exception occurs on trigger instatiating IJob class, then trigger change it TRIGGER_STATE to ERROR, and then trigger in this state will no longer fire.To reenable trigger your need to change it state to WAITING, and then it could to fire again.
Here the example how your can reenable yours misfired trigger.
var trigerKey = new TriggerKey("trigerKey", "trigerGroup");
if (scheduler.GetTriggerState(trigerKey) == TriggerState.Error)
{
scheduler.ResumeTrigger(trigerKey);
}
Actually the best way to reset Trigger from ERROR state is:
private final SchedulerFactoryBean schedulerFactoryBean;
Scheduler scheduler = schedulerFactoryBean.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
if (scheduler.getTriggerState(triggerKey).equals(Trigger.TriggerState.ERROR)) {
scheduler.resetTriggerFromErrorState(triggerKey);
}
Note:
You should never modify the records in a table from a third-party library or software manually. All changes should be made through the API to that library if there is any functionality.
JobStoreSupport.resetTriggerFromErrorState
How can I prevent the error state from being set, or at the very least, tell Quartz to retry triggers that are in the error state?
Unfortunately, in current version, you cannot retry those triggers. As per the documentation of Quartz,
It should be extremely rare for this method to throw an exception -
basically only the case where there is no way at all to instantiate
and prepare the Job for execution. When the exception is thrown, the
Scheduler will move all triggers associated with the Job into the state, which will require human
intervention (e.g. an application restart after fixing whatever
configuration problem led to the issue with instantiating the Job).
Simply put, you should follow good object oriented practices: constructors should not throw exceptions. Try to move pulling of configuration data to job's execution phase (Execute method) where retries will be handled correctly. This might mean providing a service/func via constructor that allows pulling the data.
To change the trigger state to WAITING the author also suggests that a way could be to manually update the database.
[...] You might need to update database manually, but yeah - if jobs cannot be instantiated it's considered quite bad thing and Quartz will flag them as broken.
I created another job scheduled at app startup that updates the triggers in error state to recover them.
UPDATE QRTZ_TRIGGERS SET [TRIGGER_STATE] = 'WAITING' WHERE [TRIGGER_STATE] = 'ERROR'
More information in this github discussion.

how to lock an asp.net mvc action?

I've written a controller and action that I use as a service.
This service runs quite a costly action.
I'd like to limit the access to this action if there is already a currently running action.
Is there any built in way to lock an asp.net mvc action?
Thanks
Are you looking for something like this?
public MyController : Controller
{
private static object Lock = new object();
public ActionResult MyAction()
{
lock (Lock)
{
// do your costly action here
}
}
}
The above will prevent any other threads from executing the action if a thread is currently processing code within the lock block.
Update: here is how this works
Method code is always executed by a thread. On a heavily-loaded server, it is possible for 2 or more different threads to enter and begin executing a method in parallel. According to the question, this is what you want to prevent.
Note how the private Lock object is static. This means it is shared across all instances of your controller. So, even if there are 2 instances of this controller constructed on the heap, both of them share the same Lock object. (The object doesn't even have to be named Lock, you could name it Jerry or Samantha and it would still serve the same purpose.)
Here is what happens. Your processor can only allow 1 thread to enter a section of code at a time. Under normal circumstances, thread A could begin executing a code block, and then thread B could begin executing it. So in theory you can have 2 threads executing the same method (or any block of code) at the same time.
The lock keyword can be used to prevent this. When a thread enters a block of code wrapped in a lock section, it "picks up" the lock object (what is in parenthesis after the lock keyword, a.k.a. Lock, Jerry, or Samantha, which should be marked as a static field). For the duration of time where the locked section is being executed, it "holds onto" the lock object. When the thread exits the locked section, it "gives up" the lock object. From the time the thread picks up the lock object, until it gives up the lock object, all other threads are prevented from entering the locked section of code. In effect, they are "paused" until the currently executing thread gives up the lock object.
So thread A picks up the lock object at the beginning of your MyAction method. Before it gives up the lock object, thread B also tries to execute this method. However, it cannot pick up the lock object because it is already held by thread A. So it waits for thread A to give up the lock object. When it does, thread B then picks up the lock object and begins executing the block of code. When thread B is finished executing the block, it gives up the lock object for the next thread that is delegated to handle this method.
... but I'm not sure if this is what you are looking for...
Using this approach will not necessarily make your code run any faster. It only ensures that a block of code can only be executed by 1 thread at a time. It is usually used for concurrency reasons, not performance reasons. If you can provide more information about your specific problem in the question, there may be a better answer than this one.
Remember that the code I presented above will cause other threads to wait before executing the block. If this is not what you want, and you want the entire action to be "skipped" if it is already being executed by another thread, then use something more like Oshry's answer. You can store this info in cache, session, or any other data storage mechanism.
I prefer to use SemaphoreSlim because it support async operations.
If you need to control the read/write then you can use the ReaderWriterLockSlim.
The following code snip uses the SemaphoreSlim:
public class DemoController : Controller
{
private static readonly SemaphoreSlim ProtectedActionSemaphore =
new SemaphoreSlim(1);
[HttpGet("paction")] //--or post, put, delete...
public IActionResult ProtectedAction()
{
ProtectedActionSemaphore.Wait();
try
{
//--call your protected action here
}
finally
{
ProtectedActionSemaphore.Release();
}
return Ok(); //--or any other response
}
[HttpGet("paction2")] //--or post, put, delete...
public async Task<IActionResult> ProtectedActionAsync()
{
await ProtectedActionSemaphore.WaitAsync();
try
{
//--call your protected action here
}
finally
{
ProtectedActionSemaphore.Release();
}
return Ok(); //--or any other response
}
}
I hope it helps.
Having read and agreed with the above answer I wanted a slightly different solution:
If you want to detect a second call to an action, use Monitor.TryEnter:
if (!Monitor.TryEnter(Lock, new TimeSpan(0)))
{
throw new ServiceBusyException("Locked!");
}
try
{
...
}
finally {
Monitor.Exit(Lock);
}
Use the same static Lock object as detailed by #danludwig
You can create a custom attribute like [UseLock] as per your requirements and put it before your Action
i have suggestions about that.
1- https://github.com/madelson/DistributedLock
system wide lock solution
2- Hangfire BackgroundJob.Enqueue with [DisableConcurrentExecution(1000)] attribute.
Two solution are pending for process to be finished. i don't want to throw error when request same time.
The simplest way to do that would be save to the cache a Boolean value indicating the action is running the required BL already:
if (System.Web.HttpContext.Current.Cache["IsProcessRunning"])
{
System.Web.HttpContext.Current.Cache["IsProcessRunning"] = true;
// run your logic here
System.Web.HttpContext.Current.Cache["IsProcessRunning"] = false
}
Of course you can do this, or something similar, as an attribute as well.

Delete a row from VerticalFieldManager

I am trying to establish a PIM listener that will update a MainScreen where all the contacts of the phone are listed.
What I am doing is the following:
I am loading for one time only a form called ContactsForm and I am storing it into the RuntimeStore
I created a PIMListListener to listen for all the changes that will occur in the address book.
When a contact is added, I am adding it to the contactsForm successfully
When a contact is removed, I am facing a big problem deleting it :S!!!
I am getting this exeption: "IllegalArgumentException"; this exception's text is : UiEngine accessed without holding the event lock. I know such errors and I know how to resolve them. So I used the following code:
UiApplication.getUiApplication().invokeLater( new Runnable() { public void run() {
synchronized(UiApplication.getEventLock()) {
uiContacts.vm.delete(uiContacts.vm.getField(j));
}
}});
This should resolve the problem. But I keep getting this error again and again. How to resolve this?
Listeners, like the PIMListListener, do not receive their callbacks in the same Application context as your UiApplication. So, in your code, UiApplication.getUiApplication() doesn't really work the way you'd expect it to.
The best thing to do would be to store a reference to your UiApplication in a place where the callback can reach it (during initialization of the UiApplication, perhaps), and then replace UiApplication.getUiApplication().invokeLater(...) with myUiApp.invokeLater(...), where myUiApp is the reference to your UiApplication which you stored earlier.

MQ Connection - 2009 error

am connectting the MQ with below code. I am able connected to MQ successfully. My case is i place the messages to MQ every 1 min once. After disconnecting the cable i get a ResonCode error but IsConnected property still show true. Is this is the right way to check if the connection is still connected ? Or there any best pratcices around that.
I would like to open the connection when applicaiton is started keep it open for ever.
public static MQQueueManager ConnectMQ()
{
if ((queueManager == null) || (!queueManager.IsConnected)||(queueManager.ReasonCode == 2009))
{
queueManager = new MQQueueManager();
}
return queueManager;
}
The behavior of the WMQ client connection is that when idle it will appear to be connected until an API call fails or the connection times out. So isConnected() will likely report true until a get, put or inquire call is attempted and fails, at which point QMgr will then report disconnected.
The other thing to consider here is that 2009 is not the only code you might get. It happens to be the one you get when the connection is severed but there are connection codes for QMgr shutting down, channel shutting down, and a variety of resource and other errors.
Typically for a requirement to maintain a constant connection you would want to wrap the connect and message processing loop inside a try/catch block nested inside a while statement. When you catch an exception other than an intentional exit, close the objects and QMgr, sleep at least 5 seconds, then loop around to the top of the while. The sleep is crucial because if you get caught in a tight reconnect loop and throw hundreds of connection attempts at the QMgr, you can bring even a mainframe QMgr to its knees.
An alternative is to use a v7 WMQ client and QMgr. With this combination, automatic reconnection is configurable as a channel configuration.

Resources