Skip to content

Commit

Permalink
Merge pull request #2768 from mitchelsellers/Fix/fileperformance
Browse files Browse the repository at this point in the history
Correction of File Access Issues
  • Loading branch information
ohine authored May 8, 2019
2 parents 9899bd3 + 2a3bd44 commit db68120
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 102 deletions.
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
#region Copyright
//
// DotNetNuke® - http://www.dotnetnuke.com
// Copyright (c) 2002-2018
// by DotNetNuke Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#region Usings

using System;
Expand All @@ -43,14 +27,14 @@ namespace DotNetNuke.Services.Installer.Installers
/// -----------------------------------------------------------------------------
public class ResourceFileInstaller : FileInstaller
{
private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof (ResourceFileInstaller));
#region "Public Contants"
private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof(ResourceFileInstaller));
#region "Public Contants"
public const string DEFAULT_MANIFESTEXT = ".manifest";
private string _Manifest;
#endregion
#region "Protected Properties"

#endregion

#region "Protected Properties"

/// -----------------------------------------------------------------------------
/// <summary>
Expand Down Expand Up @@ -88,10 +72,10 @@ protected string Manifest
return _Manifest;
}
}

#endregion

#region "Public Properties"
#endregion

#region "Public Properties"

/// -----------------------------------------------------------------------------
/// <summary>
Expand All @@ -106,10 +90,10 @@ public override string AllowableFiles
return "resources, zip";
}
}

#endregion

#region "Protected Methods"
#endregion

#region "Protected Methods"

/// -----------------------------------------------------------------------------
/// <summary>
Expand Down Expand Up @@ -138,96 +122,85 @@ protected override void DeleteFile(InstallFile file)
/// <param name = "insFile">The InstallFile to install</param>
protected override bool InstallFile(InstallFile insFile)
{
FileStream fs = null;
ZipInputStream unzip = null;
XmlWriter writer = null;
bool retValue = true;
try
{
Log.AddInfo(Util.FILES_Expanding);
unzip = new ZipInputStream(new FileStream(insFile.TempFileName, FileMode.Open));

//Create a writer to create the manifest for the resource file
//Create the folder for destination
_Manifest = insFile.Name + ".manifest";
if (!Directory.Exists(PhysicalBasePath))
{
Directory.CreateDirectory(PhysicalBasePath);
}
fs = new FileStream(Path.Combine(PhysicalBasePath, Manifest), FileMode.Create, FileAccess.Write);
var settings = new XmlWriterSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
settings.OmitXmlDeclaration = true;
settings.Indent = true;
using (var unzip = new ZipInputStream(new FileStream(insFile.TempFileName, FileMode.Open)))
using (var manifestStream = new FileStream(Path.Combine(PhysicalBasePath, Manifest), FileMode.Create, FileAccess.Write))
{
var settings = new XmlWriterSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
settings.OmitXmlDeclaration = true;
settings.Indent = true;

writer = XmlWriter.Create(fs, settings);
using (var writer = XmlWriter.Create(manifestStream, settings))
{

//Start the new Root Element
writer.WriteStartElement("dotnetnuke");
writer.WriteAttributeString("type", "ResourceFile");
writer.WriteAttributeString("version", "5.0");
//Start the new Root Element
writer.WriteStartElement("dotnetnuke");
writer.WriteAttributeString("type", "ResourceFile");
writer.WriteAttributeString("version", "5.0");

//Start files Element
writer.WriteStartElement("files");
//Start files Element
writer.WriteStartElement("files");

ZipEntry entry = unzip.GetNextEntry();
while (entry != null)
{
if (!entry.IsDirectory)
{
string fileName = Path.GetFileName(entry.Name);
ZipEntry entry = unzip.GetNextEntry();
while (entry != null)
{
if (!entry.IsDirectory)
{
string fileName = Path.GetFileName(entry.Name);

//Start file Element
writer.WriteStartElement("file");
//Start file Element
writer.WriteStartElement("file");

//Write path
writer.WriteElementString("path", entry.Name.Substring(0, entry.Name.IndexOf(fileName)));
//Write path
writer.WriteElementString("path",
entry.Name.Substring(0, entry.Name.IndexOf(fileName)));

//Write name
writer.WriteElementString("name", fileName);
//Write name
writer.WriteElementString("name", fileName);

string physicalPath = Path.Combine(PhysicalBasePath, entry.Name);
if (File.Exists(physicalPath))
{
Util.BackupFile(new InstallFile(entry.Name, Package.InstallerInfo), PhysicalBasePath, Log);
var physicalPath = Path.Combine(PhysicalBasePath, entry.Name);
if (File.Exists(physicalPath))
{
Util.BackupFile(new InstallFile(entry.Name, Package.InstallerInfo),
PhysicalBasePath,
Log);
}

Util.WriteStream(unzip, physicalPath);

//Close files Element
writer.WriteEndElement();

Log.AddInfo(string.Format(Util.FILE_Created, entry.Name));
}

entry = unzip.GetNextEntry();
}
Util.WriteStream(unzip, physicalPath);

//Close files Element
writer.WriteEndElement();

Log.AddInfo(string.Format(Util.FILE_Created, entry.Name));
Log.AddInfo(Util.FILES_CreatedResources);
}
entry = unzip.GetNextEntry();
}

//Close files Element
writer.WriteEndElement();

Log.AddInfo(Util.FILES_CreatedResources);
}
catch (Exception exc)
{
Logger.Error(exc);

retValue = false;
}
finally
{
if (writer != null)
{
//Close XmlWriter
writer.Close();
}
if (fs != null)
{
//Close FileStreams
fs.Close();
}
if (unzip != null)
{
unzip.Close();
}
}
return retValue;
}

Expand Down Expand Up @@ -259,7 +232,7 @@ protected override InstallFile ReadManifestItem(XPathNavigator nav, bool checkFi
{
_Manifest = insFile.FullName + DEFAULT_MANIFESTEXT;
}

//Call base method
return base.ReadManifestItem(nav, checkFileExists);
}
Expand Down Expand Up @@ -325,7 +298,7 @@ protected override void UnInstallFile(InstallFile unInstallFile)
Util.DeleteFile(Manifest, PhysicalBasePath, Log);
}
}
#endregion

#endregion
}
}
16 changes: 7 additions & 9 deletions DNN Platform/Library/Services/Installer/Util.cs
Original file line number Diff line number Diff line change
Expand Up @@ -582,8 +582,8 @@ public static void WriteStream(Stream sourceStream, string destFileName)
if (file.Directory != null && !file.Directory.Exists)
file.Directory.Create();

TryToCreateAndExecute(destFileName, (f) => StreamToStream(sourceStream, f), 1000);

//HACK: Temporary fix, upping retry limit due to locking for existing filesystem access. This "fixes" azure, but isn't the most elegant
TryToCreateAndExecute(destFileName, (f) => StreamToStream(sourceStream, f), 3500);
}

/// <summary>
Expand All @@ -595,18 +595,16 @@ public static void WriteStream(Stream sourceStream, string destFileName)
/// <returns>true if action occur and false otherwise</returns>
public static bool TryToCreateAndExecute(string path, Action<FileStream> action, int milliSecondMax = Timeout.Infinite)
{
bool result = false;
DateTime dateTimestart = DateTime.Now;
var result = false;
var dateTimeStart = DateTime.Now;
Tuple < AutoResetEvent, FileSystemWatcher > tuple = null;

while (true)
{
try
{
using (var file = File.Open(path,
FileMode.Create,
FileAccess.ReadWrite,
FileShare.Write))
//Open for create, requesting read/write access, allow others to read/write as well
using (var file = File.Open(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
{
action(file);
result = true;
Expand Down Expand Up @@ -640,7 +638,7 @@ public static bool TryToCreateAndExecute(string path, Action<FileStream> action,
int milliSecond = Timeout.Infinite;
if (milliSecondMax != Timeout.Infinite)
{
milliSecond = (int) (DateTime.Now - dateTimestart).TotalMilliseconds;
milliSecond = (int) (DateTime.Now - dateTimeStart).TotalMilliseconds;
if (milliSecond >= milliSecondMax)
{
result = false;
Expand Down

0 comments on commit db68120

Please sign in to comment.