StructureMap 2.6+ Controlling Dispose Order - structuremap

I am new to StructureMap and am using it to construct an app that uses clrzmq, which is a .NET implementation of ZeroMQ.
ZeroMQ apps work by creating a single context instance and, from that instance, creating one or more ZMQ sockets to send stuff around.
In order to cleanly shut down a clrzmq app, you need to first close and Dispose any connected ZMQ sockets created from the ZMQ context, and then, only after that is done, you Dispose the ZMQ context.
If you attempt to Dispose the context prior to closing & Disposing one or more of the sockets created from that context, the Dispose call on the context will hang and your app will not exit.
So, I am looking for a way to ensure that this Dispose order is obeyed by the StructureMap containers in this app.
I've tried a registry class with wiring like so:
For< ZeroMQ.ZmqContext >().Singleton();
Profile( "SomeProfile", p =>
{
// ZmqContext instances are created with a
// custom factory method
p.For< ZeroMQ.ZmqContext >()
.Use( ZeroMQ.ZmqContext.Create() );
p.For< ISender >()
.Use< MyConcreteZmqSender >();
});
...in the above, "MyConcreteZmqSender" is a class that creates a ZMQ socket using the ZMQ context instance it receives in its constructor (the only constructor argument). It implements IDisposable, where the Dispose() implementation closes the created socket and calls Dispose() on it.
I also have a test case written to test out the Dispose behavior that looks like so:
[Test]
public void TestZmqSender()
{
ObjectFactory.Initialize( x =>
{
x.AddRegistry<MyZmqRegistry>();
} );
ObjectFactory.Profile = "SomeProfile";
ISender sender = ObjectFactory.Container.GetNestedContainer().GetInstance<ISender>();
sender.doAllTheThings();
ObjectFactory.Container.GetNestedContainer().Dispose();
ObjectFactory.Container.Dispose();
}
...in the above I tried using the nested container to get the Zmq sender instance, thinking that if I retrieve it that way, then if I later call Dispose on the nested cotainer, it will call Dispose on my socket sender before the ZMQ context gets disposed, which I assumed would happen when I called Dispose on the main parent container.
Alas, this does not appear to be what is happening, and this test case never completes. I have verified that the sender is getting properly constructed with a reference to the singleton ZMQ context. And, of course, if I manually call sender.Dispose() prior to disposing the main container, the test case completes successfully.
My first attempt didn't use the nested container at all, and it also hangs in the same way.
Anybody have any recommendations for how I can get this done without having to get a handle to all the sender instances and manually calling Dispose() on them and ensure that this is done prior to calling Dispose() on the main container?

Related

Stress Testing - EntityFramework issue - DBContext Creation

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.

When does code in a service worker outside of an event handler run?

(I am paraphrasing question asked by Rich Harris in the "Stuff I wish I'd known sooner about service workers" gist.)
If I have code in my service worker that runs outside an event handler, when does it run?
And, closely related to that, what is the difference between putting inside an install handler and putting it outside an event handler entirely?
In general, code that's outside any event handler, in the "top-level" of the service worker's global scope, will run each and every time the service worker thread(/process) is started up. The service worker thread may start (and stop) at arbitrary times, and it's not tied to the lifetime of the web pages it controlled.
(Starting/stopping the service worker thread frequently is a performance/battery optimization, and ensures that, e.g., just because you browse to a page that has registered a service worker, you won't get an extra idle thread spinning in the background.)
The flip side of that is that every time the service worker thread is stopped, any existing global state is destroyed. So while you can make certain optimizations, like storing an open IndexedDB connection in global state in the hopes of sharing it across multiple events, you need to be prepared to re-initialize them if the thread had been killed in between event handler invocations.
Closely related to this question is a misconception I've seen about the install event handler. I have seen some developers use the install handler to initialize global state that they then rely on in other event handlers, like fetch. This is dangerous, and will likely lead to bugs in production. The install handler fires once per version of a service worker, and is normally best used for tasks that are tied to service worker versioning—like caching new or updated resources that are needed by that version. After the install handler has completed successfully, a given version of a service worker will be considered "installed", and the install handler won't be triggered again when the service worker starts up to handle, e.g., a fetch or message event.
So, if there is global state that needs to be initialized prior to handling, e.g., a fetch event, you can do that in the top-level service worker global scope (optionally waiting on a promise to resolve inside the fetch event handler to ensure that any asynchronous operations have completed). Do not rely on the install handler to set up global scope!
Here's an example that illustrates some of these points:
// Assume this code lives in service-worker.js
// This is top-level code, outside of an event handler.
// You can use it to manage global state.
// _db will cache an open IndexedDB connection.
let _db;
const dbPromise = () => {
if (_db) {
return Promise.resolve(_db);
}
// Assume we're using some Promise-friendly IndexedDB wrapper.
// E.g., https://www.npmjs.com/package/idb
return idb.open('my-db', 1, upgradeDB => {
return upgradeDB.createObjectStore('key-val');
}).then(db => {
_db = db;
return db;
});
};
self.addEventListener('install', event => {
// `install` is fired once per version of service-worker.js.
// Do **not** use it to manage global state!
// You can use it to, e.g., cache resources using the Cache Storage API.
});
self.addEventListener('fetch', event => {
event.respondWith(
// Wait on dbPromise to resolve. If _db is already set, because the
// service worker hasn't been killed in between event handlers, the promise
// will resolve right away and the open connection will be reused.
// Otherwise, if the global state was reset, then a new IndexedDB
// connection will be opened.
dbPromise().then(db => {
// Do something with IndexedDB, and eventually return a `Response`.
});
);
});

Do I really need to dispose IUnityContainer on shutdown of application

I'm maintaining code for a web application built using Asp.NET MVC. An MVC dependency resolver has been implemented using Unity container. Here's the cleanup code that's called on application shutdown.
public static void Shutdown()
{
IUnityContainer container = UnityConfig.GetConfiguredContainer();
container.Dispose(); //currently when called causes stack overflow
}
The issue we're having is that during a shutdown the call to dispose (above) causes a stack overflow exception and then the process crashes because of it. This also occurs during development when debugging the app and making changes to web.config (since changes to web.config seems to restart the application) which also stops the debugging session which normally shouldn't end. No stack overflow seems to occur if I remove the call to dispose, and the application then exits or restarts normally without the process crashing during debugging sessions.
I'm thinking of simply permanently removing the call to Dispose but I'm uncertain of the consequences, wouldn't an application shut down inevitably lead to the disposing of the container anyway?
If removing the call to dispose is not recommended then the only option would be to find the real cause which I believe lie in a circular dependency within the container itself, but I can't find it, how should I debug this issue ?
The cause of the stackoverflow is infinite recursive call to Dispose of UnityContainer, which I think is (weirdly) caused by the automatically registered IUnityContainer which is not managed by our code and should be handled in unity library. I was able to stop the infinite recursion simply by swapping out the usage of the UnityContainer class with a derived class that override Dispose and returns on a recursive call:
public class CustomUnityContainer : UnityContainer
{
private bool inDispose = false;
protected override void Dispose(bool disposing)
{
if (inDispose) //prevents recursive calls into Dispose
return;
inDispose = true;
base.Dispose(disposing);
inDispose = false;
}
}

How do I clean up in Dispose if I can't call UIKit from another thread?

Most of my UIKit Dispose overrides do something with other views before they get destroyed:
protected override void Dispose (bool disposing)
{
if (ScrollView != null) {
ScrollView.RemoveObserver (this, new NSString ("contentOffset"));
ScrollView.RemoveObserver (this, new NSString ("contentInset"));
ScrollView = null;
}
base.Dispose (disposing);
}
I just recently realized that Dispose will run on finalizer thread if disposing is false.
In this case ScrollView.RemoveObserver will be called from non-UI thread which is Bad.
What's the safe way to do UIKit-related cleanup in Dispose?
If disposing is false, then you would probably be better off not calling that code.
protected override void Dispose (bool disposing)
{
if (disposing)
{
if (ScrollView != null) {
ScrollView.RemoveObserver (this, new NSString ("contentOffset"));
ScrollView.RemoveObserver (this, new NSString ("contentInset"));
ScrollView = null;
}
}
base.Dispose (disposing);
}
As a more general answer to your question - assuming this code is in a UIViewController - it might be better to attach/detach these observers inside ViewDidAppear, ViewDidDisappear - then you can avoid this issue altogether.
Adam Kemp posted a great explanation in a mirror thread on Xamarin forums.
Only if disposing is true should you do any of that work. If it's
false then you're being called from a finalizer and so it's not safe
to access that other object. The only things you should access in that
case would be any unmanaged resources (like an IntPtr which stores a
native allocation you need to free or a native thread you need to
kill).
This obviously brings up the question of when to do the work you're
currently doing there. If you're in a view controller then you could
use a method like WillDisappear. If you are in a view then you could
just use WillMoveToWindow (which gets called with null as the window
if you are being removed from the window).
Another important bit regarding ReleaseDesignerOutlets:
You can't call ReleaseDesignerOutlets when called from a finalizer
either. Remember, it is not safe to look at any other managed objects
referenced by your object in your finalizer. Those objects may no
longer exist.
This is safe to skip because each of those other objects already has a
similar finalizer. If you never get around to calling Dispose() on
them then they will have their finalizers called from the finalizer
thread, and in that case their own finalizer will call their own
Dispose(bool) with a false, which means "you're being called from a
finalizer". Since the native object is an unmanaged resource (just an
IntPtr) it is safe for their Dispose(bool) method to release the
reference to those native resources to allow those native objects to
leave memory.
You can actually use the assembly browser to look at what NSObject's
Finalize and Dispose(bool) methods do to verify what I just described.
Whatever you do, never access your managed resources from within a
finalizer, which means never access them from Dispose(bool) when the
disposing argument is false.
Thanks Adam!
Could you use
InvokeOnMainThread(delegate {....})
to kill the UIKit stuff? Not 100% sure it'd do what you want, but thats the normal way of doing UIKit stuff when you might be on / are on a different thread.

Does EF 4 Code First's ContextBuilder Dispose its SqlConnection?

Looking at Code First in ADO.Net EF 4 CTP 3 and wondered how the SqlConnection in their walkthrough is disposed. Is that the responsibility of ContextBuilder? Is it missing from the example?
var connection = new SqlConnection(DB_CONN);
var builder = new ContextBuilder<BloggingModel>();
var connection = new SqlConnection(DB_CONN);
using (var ctx = builder.Create(connection))
{
//...
}
I just realized that I can add an event handler to ObjectContext.Disposing and resolve this.
In CTP 3 at least, Connection is not disposed when the ObjectContext is disposed.
Since I'm subclassing ObjectContext already, I implemented IDisposable in my subclass and call Connection.Dispose() from there.
Close and Dispose in SqlConnection are functionally equivalent. Therefore, as long as the connection is closed -- and I think you'll find that it is, but don't take my word for it -- the sample code works.
But since you asked, you should probably dispose of it anyway. It will do no harm, and will stop others from asking the same question.

Resources