#20263: Fixing perf issue in DataMigrationManager

Work Item: 20263
This commit is contained in:
Sebastien Ros
2013-11-06 10:15:23 -08:00
parent d4d8e143cc
commit 68869cb06d

View File

@@ -22,8 +22,10 @@ namespace Orchard.Data.Migration {
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly ITransactionManager _transactionManager;
private List<string> _processedFeatures;
public DataMigrationManager(
IEnumerable<IDataMigration> dataMigrations,
IEnumerable<IDataMigration> dataMigrations,
IRepository<DataMigrationRecord> dataMigrationRepository,
IExtensionManager extensionManager,
IDataMigrationInterpreter interpreter,
@@ -36,6 +38,7 @@ namespace Orchard.Data.Migration {
_contentDefinitionManager = contentDefinitionManager;
_transactionManager = transactionManager;
_processedFeatures = new List<string>();
Logger = NullLogger.Instance;
}
public Localizer T { get; set; }
@@ -56,37 +59,45 @@ namespace Orchard.Data.Migration {
}
public void Update(IEnumerable<string> features) {
foreach(var feature in features) {
Update(feature);
foreach (var feature in features) {
if (!_processedFeatures.Contains(feature)) {
Update(feature);
}
}
}
public void Update(string feature){
public void Update(string feature) {
if (_processedFeatures.Contains(feature)) {
return;
}
_processedFeatures.Add(feature);
Logger.Information("Updating feature: {0}", feature);
// proceed with dependent features first, whatever the module it's in
var dependencies = _extensionManager.AvailableFeatures()
.Where(f => String.Equals(f.Id, feature, StringComparison.OrdinalIgnoreCase))
.Where(f => f.Dependencies != null)
.SelectMany( f => f.Dependencies )
.SelectMany(f => f.Dependencies)
.ToList();
foreach(var dependency in dependencies) {
foreach (var dependency in dependencies) {
Update(dependency);
}
var migrations = GetDataMigrations(feature);
// apply update methods to each migration class for the module
foreach ( var migration in migrations ) {
foreach (var migration in migrations) {
// copy the object for the Linq query
var tempMigration = migration;
// get current version for this migration
var dataMigrationRecord = GetDataMigrationRecord(tempMigration);
var current = 0;
if(dataMigrationRecord != null) {
if (dataMigrationRecord != null) {
current = dataMigrationRecord.Version.Value;
}
@@ -99,7 +110,7 @@ namespace Orchard.Data.Migration {
var createMethod = GetCreateMethod(migration);
if (createMethod != null) {
current = (int) createMethod.Invoke(migration, new object[0]);
current = (int)createMethod.Invoke(migration, new object[0]);
}
}
@@ -108,7 +119,7 @@ namespace Orchard.Data.Migration {
while (lookupTable.ContainsKey(current)) {
try {
Logger.Information("Applying migration for {0} from version {1}", feature, current);
current = (int) lookupTable[current].Invoke(migration, new object[0]);
current = (int)lookupTable[current].Invoke(migration, new object[0]);
}
catch (Exception ex) {
Logger.Error(ex, "An unexpected error occurred while applying migration on {0} from version {1}", feature, current);
@@ -129,7 +140,7 @@ namespace Orchard.Data.Migration {
_transactionManager.RequireNew();
}
catch(Exception e) {
catch (Exception e) {
Logger.Error(e, "Error while running migration version {0} for {1}", current, feature);
_transactionManager.Cancel();
}
@@ -155,7 +166,7 @@ namespace Orchard.Data.Migration {
uninstallMethod.Invoke(migration, new object[0]);
}
if ( dataMigrationRecord == null ) {
if (dataMigrationRecord == null) {
continue;
}
@@ -166,9 +177,9 @@ namespace Orchard.Data.Migration {
}
private DataMigrationRecord GetDataMigrationRecord(IDataMigration tempMigration) {
return _dataMigrationRepository.Table
.Where(dm => dm.DataMigrationClass == tempMigration.GetType().FullName)
.FirstOrDefault();
return _dataMigrationRepository
.Table
.FirstOrDefault(dm => dm.DataMigrationClass == tempMigration.GetType().FullName);
}
/// <summary>
@@ -225,7 +236,7 @@ namespace Orchard.Data.Migration {
/// </summary>
private static MethodInfo GetCreateMethod(IDataMigration dataMigration) {
var methodInfo = dataMigration.GetType().GetMethod("Create", BindingFlags.Public | BindingFlags.Instance);
if(methodInfo != null && methodInfo.ReturnType == typeof(int)) {
if (methodInfo != null && methodInfo.ReturnType == typeof(int)) {
return methodInfo;
}
@@ -237,7 +248,7 @@ namespace Orchard.Data.Migration {
/// </summary>
private static MethodInfo GetUninstallMethod(IDataMigration dataMigration) {
var methodInfo = dataMigration.GetType().GetMethod("Uninstall", BindingFlags.Public | BindingFlags.Instance);
if ( methodInfo != null && methodInfo.ReturnType == typeof(void) ) {
if (methodInfo != null && methodInfo.ReturnType == typeof(void)) {
return methodInfo;
}