Thanks, Valerie.  

Yes, we are caching our configuration but you're making me think.  What we 
aren't doing (and I don't yet know how I could) is caching the mappings and 
creating the factories from whatever that might be.  I'll have to start 
exploring to see if that is feasible....

On Wednesday, May 29, 2013 10:03:35 AM UTC-5, Valeriu Caraulean wrote:
>
>   As a guess, have you tried to reuse the Configuration object?
> If only connection string or database name changes, you can cache the 
> Configuration and re-use it. It’s one of the most expensive operations when 
> bootstrapping NHibernate...
>  
> Valeriu
>   
>  *From:* Kerry <javascript:> 
> *Sent:* Wednesday, May 29, 2013 3:48 PM
> *To:* [email protected] <javascript:> 
> *Subject:* [nhusers] Bootstrapping with multiple Session Factories
>  
> We have a need in our app to support multiple "connections" to different 
> databases, with each connection supporting the same set of mappings.  We 
> have a huge number of mappings (this is a decade-old legacy application), 
> and each connection and database has the same schema.  We recently added a 
> feature to the application that allows a user on one connection to view 
> data on all of the other connections, which requires having all of the 
> connections available at the time of the request. 
>  
> Bootstrapping a single connection can take up to 20 seconds over a slow 
> wire.  When one of our customers tried to view data on 7 connections, the 
> application (unsurprisingly) timed out.  To address this, we are taking a 
> two-pronged approach:
>  
>    1. bootstrap all connections prior to login of the first user (at 
>    app_start); and
>    2. at bootstrap, create the session factories for each connection in a 
>    multi-threaded environment to reduce the timeout problem.
>    
>  
> The second approach is proving to be problematic.  When calling 
> BuildSessionFactory in a multi-threaded environment, the logs show that the 
> factories are being constructed serially.  (i.e. I spin off the threads at 
> time A, and they come back at times B, B+10, B+20, B+30, etc).  Another 
> developer reporting setting up an integration environment to test this, and 
> received a duplicate key exception from within NHIbernate.  I have not yet 
> had time to review that error or his code, but it points to something 
> problematic with using nHibernate in a multi-threaded environment.
>  
> Would somebody mind taking a look at the following code and commenting on 
> our approach?  Thanks very much.
>  
>
>         public void ConstructSessionFactories(IEnumerable<string> 
> connectionNames)         {             var maps = connectionMap.Map.Where(m 
> => connectionNames.Contains(m.Key)).Select(m => m.Value);             
> maps.ForEach(info =>                 {                     if 
> (factoryMap.ContainsKey(info.ConnectionString)) return;                     
> WaitForCompletionIfFactoryUnderConstruction(info.ConnectionString);           
>           if (factoryMap.ContainsKey(info.ConnectionString)) return;          
>            var task = new Task(() => CreateNewFactory(info));                 
>     task.ContinueWith(FactoryConstructed, 
> TaskContinuationOptions.OnlyOnRanToCompletion);                     
> task.ContinueWith(FactoryNotConstructed, 
> TaskContinuationOptions.NotOnRanToCompletion);                     
> task.ContinueWith(FactoryConstructionCausedError, 
> TaskContinuationOptions.OnlyOnFaulted);                     
> factoriesUnderConstruction[info.ConnectionString] = task;                     
> task.Start();                                      });         }
>
>
>         protected virtual ISessionFactory CreateNewFactory(ConnectionElement 
> info)         {             if 
> (factoryMap.ContainsKey(info.ConnectionString)) return 
> factoryMap[info.ConnectionString];             logger.DebugFormat("Creating 
> new SessionFactory for connection '{0}'", info.Name);             var cfg = 
> configurationProvider.Get(info);             ExposeConfiguration(cfg);        
>      configData.AddOrUpdate(info.Name, cfg, (key, oldValue) => cfg);          
>    var factory = cfg.BuildSessionFactory();             
> factoryMap[info.ConnectionString] = factory;             return factory;      
>    }
>
>
>         private void WaitForCompletionIfFactoryUnderConstruction(string 
> connection)         {             while 
> (factoriesUnderConstruction.ContainsKey(connection))             {            
>      Task task;                 
> factoriesUnderConstruction.TryGetValue(connection, out task);                 
> if (task != null) task.Wait();             }                     }
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "nhusers" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected] <javascript:>.
> To post to this group, send email to [email protected] <javascript:>
> .
> Visit this group at http://groups.google.com/group/nhusers?hl=en-US.
> For more options, visit https://groups.google.com/groups/opt_out.
>  
>  
>

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/nhusers?hl=en-US.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to