Skip to content

Instantly share code, notes, and snippets.

@davybrion
Created September 10, 2012 19:26
Show Gist options
  • Save davybrion/3693200 to your computer and use it in GitHub Desktop.
Save davybrion/3693200 to your computer and use it in GitHub Desktop.
code snippets for "Using Copy-On-Write In Multithreaded Code To Reduce Locking Overhead" post
public class TenantSessionFactoryManager : ITenantSessionFactoryManager
{
private readonly ITenantContext tenantContext;
private readonly ITenantInfoHolder tenantInfoHolder;
private readonly string mappingAssemblyName;
private readonly object writeLock = new object();
private Dictionary<Guid, ISessionFactory> sessionFactories;
public TenantSessionFactoryManager(ITenantContext tenantContext, ITenantInfoHolder tenantInfoHolder, string mappingAssemblyName)
{
this.tenantContext = tenantContext;
this.tenantInfoHolder = tenantInfoHolder;
this.mappingAssemblyName = mappingAssemblyName;
sessionFactories = new Dictionary<Guid, ISessionFactory>();
}
public ISession CreateSessionForCurrentTenant()
{
var tenantId = tenantContext.CurrentTenantId;
if (!sessionFactories.ContainsKey(tenantId))
{
CreateSessionFactoryForCurrentTenant();
}
return sessionFactories[tenantId].OpenSession();
}
private void CreateSessionFactoryForCurrentTenant()
{
lock (writeLock)
{
var tenantId = tenantContext.CurrentTenantId;
if (!sessionFactories.ContainsKey(tenantId))
{
var connectionString = tenantInfoHolder.GetDatabaseConnectionString(tenantId);
var sessionFactory = new Configuration()
.Configure()
.AddProperties(new Dictionary<string, string>
{
{ "connection.connection_string", connectionString },
{ "cache.region_prefix", "Tenant_" + tenantId }
})
.AddAssembly(mappingAssemblyName)
.BuildSessionFactory();
var newDictionary = new Dictionary<Guid, ISessionFactory>(sessionFactories);
newDictionary[tenantId] = sessionFactory;
sessionFactories = newDictionary;
}
}
}
public void RemoveSessionFactoryForTenant(Guid tenantId)
{
if (!sessionFactories.ContainsKey(tenantId))
{
return;
}
lock (writeLock)
{
if (!sessionFactories.ContainsKey(tenantId))
{
return;
}
var sessionFactory = sessionFactories[tenantId];
var newDictionary = new Dictionary<Guid, ISessionFactory>(sessionFactories);
newDictionary.Remove(tenantId);
sessionFactories = newDictionary;
sessionFactory.Dispose();
}
}
}
if (sessionFactories.ContainsKey(tenantId))
{
return sessionFactories[tenantId].OpenSession();
}
private void CreateSessionFactoryForCurrentTenant()
{
lock (writeLock)
{
var tenantId = tenantContext.CurrentTenantId;
if (!sessionFactories.ContainsKey(tenantId))
{
var connectionString = tenantInfoHolder.GetDatabaseConnectionString(tenantId);
var sessionFactory = new Configuration()
.Configure()
.AddProperties(new Dictionary<string, string>
{
{ "connection.connection_string", connectionString },
{ "cache.region_prefix", "Tenant_" + tenantId }
})
.AddAssembly(mappingAssemblyName)
.BuildSessionFactory();
var newDictionary = new Dictionary<Guid, ISessionFactory>(sessionFactories);
newDictionary[tenantId] = sessionFactory;
sessionFactories = newDictionary;
}
}
}
public void RemoveSessionFactoryForTenant(Guid tenantId)
{
if (!sessionFactories.ContainsKey(tenantId))
{
return;
}
lock (writeLock)
{
if (!sessionFactories.ContainsKey(tenantId))
{
return;
}
var sessionFactory = sessionFactories[tenantId];
var newDictionary = new Dictionary<Guid, ISessionFactory>(sessionFactories);
newDictionary.Remove(tenantId);
sessionFactories = newDictionary;
sessionFactory.Dispose();
}
}
public void RemoveSessionFactoryForTenant(Guid tenantId)
{
lock (writeLock)
{
if (!sessionFactories.ContainsKey(tenantId))
{
return;
}
var sessionFactory = sessionFactories[tenantId];
var newDictionary = new Dictionary<Guid, ISessionFactory>(sessionFactories);
newDictionary.Remove(tenantId);
sessionFactories = newDictionary;
sessionFactory.Dispose();
}
}
public ISession CreateSessionForCurrentTenant()
{
var tenantId = tenantContext.CurrentTenantId;
if (!sessionFactories.ContainsKey(tenantId))
{
CreateSessionFactoryForCurrentTenant();
}
return sessionFactories[tenantId].OpenSession();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment