Merge remote-tracking branch 'origin/v8/dev' into netcore/netcore
# Conflicts: # src/SolutionInfo.cs # src/Umbraco.Core/Runtime/MainDom.cs # src/Umbraco.Infrastructure/Runtime/SqlMainDomLock.cs # src/Umbraco.Web.UI.NetCore/umbraco/UmbracoBackOffice/Preview.cshtml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/da.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en_us.xml
This commit is contained in:
@@ -157,7 +157,15 @@ namespace Umbraco.Core.Runtime
|
||||
_logger.LogInformation("Acquiring.");
|
||||
|
||||
// Get the lock
|
||||
var acquired = _mainDomLock.AcquireLockAsync(LockTimeoutMilliseconds).GetAwaiter().GetResult();
|
||||
var acquired = false;
|
||||
try
|
||||
{
|
||||
acquired = _mainDomLock.AcquireLockAsync(LockTimeoutMilliseconds).GetAwaiter().GetResult();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error while acquiring");
|
||||
}
|
||||
|
||||
if (!acquired)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Core.Configuration;
|
||||
using NPoco;
|
||||
using Umbraco.Core.Configuration.Models;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.Persistence;
|
||||
@@ -42,7 +42,7 @@ namespace Umbraco.Core.Runtime
|
||||
loggerFactory,
|
||||
globalSettings,
|
||||
connectionStrings,
|
||||
new Lazy<IMapperCollection>(() => new MapperCollection(Enumerable.Empty<BaseMapper>())),
|
||||
new Lazy<IMapperCollection>(() => new Persistence.Mappers.MapperCollection(Enumerable.Empty<BaseMapper>())),
|
||||
dbProviderFactoryCreator);
|
||||
|
||||
MainDomKey = MainDomKeyPrefix + "-" + (NetworkHelper.MachineName + MainDom.GetMainDomId(_hostingEnvironment)).GenerateHash<SHA1>();
|
||||
@@ -57,7 +57,9 @@ namespace Umbraco.Core.Runtime
|
||||
}
|
||||
|
||||
if (!(_dbFactory.SqlContext.SqlSyntax is SqlServerSyntaxProvider sqlServerSyntaxProvider))
|
||||
{
|
||||
throw new NotSupportedException("SqlMainDomLock is only supported for Sql Server");
|
||||
}
|
||||
|
||||
_sqlServerSyntax = sqlServerSyntaxProvider;
|
||||
|
||||
@@ -65,11 +67,13 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
var tempId = Guid.NewGuid().ToString();
|
||||
|
||||
using var db = _dbFactory.CreateDatabase();
|
||||
using var transaction = db.GetTransaction(IsolationLevel.ReadCommitted);
|
||||
IUmbracoDatabase db = null;
|
||||
|
||||
try
|
||||
{
|
||||
db = _dbFactory.CreateDatabase();
|
||||
db.BeginTransaction(IsolationLevel.ReadCommitted);
|
||||
|
||||
try
|
||||
{
|
||||
// wait to get a write lock
|
||||
@@ -110,7 +114,8 @@ namespace Umbraco.Core.Runtime
|
||||
}
|
||||
finally
|
||||
{
|
||||
transaction.Complete();
|
||||
db?.CompleteTransaction();
|
||||
db?.Dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -172,11 +177,11 @@ namespace Umbraco.Core.Runtime
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
using var db = _dbFactory.CreateDatabase();
|
||||
using var transaction = db.GetTransaction(IsolationLevel.ReadCommitted);
|
||||
IUmbracoDatabase db = null;
|
||||
try
|
||||
{
|
||||
db = _dbFactory.CreateDatabase();
|
||||
db.BeginTransaction(IsolationLevel.ReadCommitted);
|
||||
// get a read lock
|
||||
_sqlServerSyntax.ReadLock(db, Constants.Locks.MainDom);
|
||||
|
||||
@@ -202,7 +207,8 @@ namespace Umbraco.Core.Runtime
|
||||
}
|
||||
finally
|
||||
{
|
||||
transaction.Complete();
|
||||
db?.CompleteTransaction();
|
||||
db?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,34 +227,47 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
return Task.Run(() =>
|
||||
{
|
||||
using var db = _dbFactory.CreateDatabase();
|
||||
|
||||
var watch = new Stopwatch();
|
||||
watch.Start();
|
||||
while (true)
|
||||
try
|
||||
{
|
||||
// poll very often, we need to take over as fast as we can
|
||||
// local testing shows the actual query to be executed from client/server is approx 300ms but would change depending on environment/IO
|
||||
Thread.Sleep(1000);
|
||||
using var db = _dbFactory.CreateDatabase();
|
||||
|
||||
var acquired = TryAcquire(db, tempId, updatedTempId);
|
||||
if (acquired.HasValue)
|
||||
return acquired.Value;
|
||||
|
||||
if (watch.ElapsedMilliseconds >= millisecondsTimeout)
|
||||
var watch = new Stopwatch();
|
||||
watch.Start();
|
||||
while (true)
|
||||
{
|
||||
return AcquireWhenMaxWaitTimeElapsed(db);
|
||||
// poll very often, we need to take over as fast as we can
|
||||
// local testing shows the actual query to be executed from client/server is approx 300ms but would change depending on environment/IO
|
||||
Thread.Sleep(1000);
|
||||
|
||||
var acquired = TryAcquire(db, tempId, updatedTempId);
|
||||
if (acquired.HasValue)
|
||||
return acquired.Value;
|
||||
|
||||
if (watch.ElapsedMilliseconds >= millisecondsTimeout)
|
||||
{
|
||||
return AcquireWhenMaxWaitTimeElapsed(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "An error occurred trying to acquire and waiting for existing SqlMainDomLock to shutdown");
|
||||
return false;
|
||||
}
|
||||
|
||||
}, _cancellationTokenSource.Token);
|
||||
}
|
||||
|
||||
private bool? TryAcquire(IUmbracoDatabase db, string tempId, string updatedTempId)
|
||||
{
|
||||
using var transaction = db.GetTransaction(IsolationLevel.ReadCommitted);
|
||||
// Creates a separate transaction to the DB instance so we aren't allocating tons of new DB instances for each transaction
|
||||
// since this is executed in a tight loop
|
||||
|
||||
ITransaction transaction = null;
|
||||
|
||||
try
|
||||
{
|
||||
transaction = db.GetTransaction(IsolationLevel.ReadCommitted);
|
||||
// get a read lock
|
||||
_sqlServerSyntax.ReadLock(db, Constants.Locks.MainDom);
|
||||
|
||||
@@ -294,7 +313,8 @@ namespace Umbraco.Core.Runtime
|
||||
}
|
||||
finally
|
||||
{
|
||||
transaction.Complete();
|
||||
transaction?.Complete();
|
||||
transaction?.Dispose();
|
||||
}
|
||||
|
||||
return null; // continue
|
||||
@@ -302,6 +322,9 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
private bool AcquireWhenMaxWaitTimeElapsed(IUmbracoDatabase db)
|
||||
{
|
||||
// Creates a separate transaction to the DB instance so we aren't allocating tons of new DB instances for each transaction
|
||||
// since this is executed in a tight loop
|
||||
|
||||
// if the timeout has elapsed, it either means that the other main dom is taking too long to shutdown,
|
||||
// or it could mean that the previous appdomain was terminated and didn't clear out the main dom SQL row
|
||||
// and it's just been left as an orphan row.
|
||||
@@ -311,10 +334,12 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
_logger.LogDebug("Timeout elapsed, assuming orphan row, acquiring MainDom.");
|
||||
|
||||
using var transaction = db.GetTransaction(IsolationLevel.ReadCommitted);
|
||||
ITransaction transaction = null;
|
||||
|
||||
try
|
||||
{
|
||||
transaction = db.GetTransaction(IsolationLevel.ReadCommitted);
|
||||
|
||||
_sqlServerSyntax.WriteLock(db, Constants.Locks.MainDom);
|
||||
|
||||
// so now we update the row with our appdomain id
|
||||
@@ -337,7 +362,8 @@ namespace Umbraco.Core.Runtime
|
||||
}
|
||||
finally
|
||||
{
|
||||
transaction.Complete();
|
||||
transaction?.Complete();
|
||||
transaction?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -390,11 +416,12 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
if (_dbFactory.Configured)
|
||||
{
|
||||
using var db = _dbFactory.CreateDatabase();
|
||||
using var transaction = db.GetTransaction(IsolationLevel.ReadCommitted);
|
||||
|
||||
IUmbracoDatabase db = null;
|
||||
try
|
||||
{
|
||||
db = _dbFactory.CreateDatabase();
|
||||
db.BeginTransaction(IsolationLevel.ReadCommitted);
|
||||
|
||||
// get a write lock
|
||||
_sqlServerSyntax.WriteLock(db, Constants.Locks.MainDom);
|
||||
|
||||
@@ -421,7 +448,15 @@ namespace Umbraco.Core.Runtime
|
||||
}
|
||||
finally
|
||||
{
|
||||
transaction.Complete();
|
||||
try
|
||||
{
|
||||
db?.CompleteTransaction();
|
||||
db?.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Unexpected error during dispose when completing transaction.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,9 +239,10 @@ var app = angular.module("umbraco.preview", ['umbraco.resources', 'umbraco.servi
|
||||
// Ask to re-enter preview mode?
|
||||
|
||||
const localizeVarsFallback = {
|
||||
"returnToPreviewHeadline": "Preview content?",
|
||||
"returnToPreviewDescription":"You have ended preview mode, do you want to continue previewing this content?",
|
||||
"returnToPreviewButton":"Preview"
|
||||
"returnToPreviewHeadline": "Preview website?",
|
||||
"returnToPreviewDescription":"You have ended preview mode, do you want to enable it again to view the latest saved version of your website?",
|
||||
"returnToPreviewAcceptButton":"Preview latest version",
|
||||
"returnToPreviewDeclineButton":"View published version"
|
||||
};
|
||||
const umbLocalizedVars = Object.assign(localizeVarsFallback, $window.umbLocalizedVars);
|
||||
|
||||
@@ -344,10 +345,20 @@ var app = angular.module("umbraco.preview", ['umbraco.resources', 'umbraco.servi
|
||||
<div class="umbraco-preview-dialog__question">${umbLocalizedVars.returnToPreviewDescription}</div>`;
|
||||
con.appendChild(modal);
|
||||
|
||||
var declineButton = document.createElement("button");
|
||||
declineButton.type = "button";
|
||||
declineButton.innerHTML = umbLocalizedVars.returnToPreviewDeclineButton;
|
||||
declineButton.addEventListener("click", () => {
|
||||
bodyEl.removeChild(fragment);
|
||||
$scope.exitPreview();
|
||||
hasPreviewDialog = false;
|
||||
});
|
||||
modal.appendChild(declineButton);
|
||||
|
||||
var continueButton = document.createElement("button");
|
||||
continueButton.type = "button";
|
||||
continueButton.className = "umbraco-preview-dialog__continue";
|
||||
continueButton.innerHTML = umbLocalizedVars.returnToPreviewButton;
|
||||
continueButton.innerHTML = umbLocalizedVars.returnToPreviewAcceptButton;
|
||||
continueButton.addEventListener("click", () => {
|
||||
bodyEl.removeChild(fragment);
|
||||
reenterPreviewMode();
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
var OpenWebsiteTitle = LocalizedTextService.Localize("preview", "openWebsiteTitle");
|
||||
var returnToPreviewHeadline = LocalizedTextService.Localize("preview", "returnToPreviewHeadline");
|
||||
var returnToPreviewDescription = LocalizedTextService.Localize("preview", "returnToPreviewDescription");
|
||||
var returnToPreviewButton = LocalizedTextService.Localize("preview", "returnToPreviewButton");
|
||||
var returnToPreviewAcceptButton = LocalizedTextService.Localize("preview", "returnToPreviewAcceptButton");
|
||||
var returnToPreviewDeclineButton = LocalizedTextService.Localize("preview", "returnToPreviewDeclineButton");
|
||||
}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
@@ -44,7 +45,8 @@
|
||||
window.umbLocalizedVars = {
|
||||
'returnToPreviewHeadline': '@returnToPreviewHeadline',
|
||||
'returnToPreviewDescription':'@returnToPreviewDescription',
|
||||
'returnToPreviewButton':'@returnToPreviewButton'
|
||||
'returnToPreviewAcceptButton':'@returnToPreviewAcceptButton',
|
||||
'returnToPreviewDeclineButton':'@returnToPreviewDeclineButton'
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
||||
@@ -1439,7 +1439,7 @@ Mange hilsner fra Umbraco robotten
|
||||
<key alias="elementDoesNotSupport">Dette benyttes ikke for en Element-type</key>
|
||||
<key alias="propertyHasChanges">Du har lavet ændringer til denne egenskab. Er du sikker på at du vil kassere dem?</key>
|
||||
<key alias="displaySettingsHeadline">Visning</key>
|
||||
<key alias="displaySettingsLabelOnTop">Flyt label over editoren</key>
|
||||
<key alias="displaySettingsLabelOnTop">Label hen over (fuld brede)</key>
|
||||
</area>
|
||||
<area alias="languages">
|
||||
<key alias="addLanguage">Tilføj sprog</key>
|
||||
@@ -1873,8 +1873,9 @@ Mange hilsner fra Umbraco robotten
|
||||
<key alias="openWebsiteLabel">Vis i nyt vindue</key>
|
||||
<key alias="openWebsiteTitle">Åben forhåndsvisning i nyt vindue</key>
|
||||
<key alias="returnToPreviewHeadline">Forhåndsvisning af indholdet?</key>
|
||||
<key alias="returnToPreviewDescription">Du har afslutet forhåndsvisning, vil du se dette indhold i forhåndsvisning?</key>
|
||||
<key alias="returnToPreviewButton">Fortsæt</key>
|
||||
<key alias="returnToPreviewDescription">Du har afslutet forhåndsvisning, vil du starte forhåndsvisning igen for at se seneste gemte version af indholdet?</key>
|
||||
<key alias="returnToPreviewButton">Start forhåndsvisning</key>
|
||||
<key alias="returnToPreviewDeclineButton">Se udgivet indhold</key>
|
||||
<key alias="viewPublishedContentHeadline">Se udgivet indhold?</key>
|
||||
<key alias="viewPublishedContentDescription">Du er i forhåndsvisning, vil du afslutte for at se den udgivet version?</key>
|
||||
<key alias="viewPublishedContentAcceptButton">Se udgivet version</key>
|
||||
|
||||
@@ -1699,7 +1699,7 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="elementDoesNotSupport">This is not applicable for an Element type</key>
|
||||
<key alias="propertyHasChanges">You have made changes to this property. Are you sure you want to discard them?</key>
|
||||
<key alias="displaySettingsHeadline">Appearance</key>
|
||||
<key alias="displaySettingsLabelOnTop">Display label on top of editor.</key>
|
||||
<key alias="displaySettingsLabelOnTop">Label above (full-width)</key>
|
||||
</area>
|
||||
<area alias="languages">
|
||||
<key alias="addLanguage">Add language</key>
|
||||
@@ -2536,9 +2536,10 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="endTitle">End preview mode</key>
|
||||
<key alias="openWebsiteLabel">Preview website</key>
|
||||
<key alias="openWebsiteTitle">Open website in preview mode</key>
|
||||
<key alias="returnToPreviewHeadline">Preview content?</key>
|
||||
<key alias="returnToPreviewDescription">You have ended preview mode, do you want to continue previewing this content?</key>
|
||||
<key alias="returnToPreviewButton">Preview</key>
|
||||
<key alias="returnToPreviewHeadline">Preview website?</key>
|
||||
<key alias="returnToPreviewDescription">ou have ended preview mode, do you want to enable it again to view the latest saved version of your website?</key>
|
||||
<key alias="returnToPreviewAcceptButton">Preview latest version</key>
|
||||
<key alias="returnToPreviewDeclineButton">View published version</key>
|
||||
<key alias="viewPublishedContentHeadline">View published version?</key>
|
||||
<key alias="viewPublishedContentDescription">You are in Preview Mode, do you want exit in order to view the published version of your website?</key>
|
||||
<key alias="viewPublishedContentAcceptButton">View published version</key>
|
||||
|
||||
@@ -1717,7 +1717,7 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="elementDoesNotSupport">This is not applicable for an element type</key>
|
||||
<key alias="propertyHasChanges">You have made changes to this property. Are you sure you want to discard them?</key>
|
||||
<key alias="displaySettingsHeadline">Appearance</key>
|
||||
<key alias="displaySettingsLabelOnTop">Display label on top of editor.</key>
|
||||
<key alias="displaySettingsLabelOnTop">Label above (full-width)</key>
|
||||
</area>
|
||||
<area alias="languages">
|
||||
<key alias="addLanguage">Add language</key>
|
||||
@@ -2556,9 +2556,10 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="endTitle">End preview mode</key>
|
||||
<key alias="openWebsiteLabel">Preview website</key>
|
||||
<key alias="openWebsiteTitle">Open website in preview mode</key>
|
||||
<key alias="returnToPreviewHeadline">Preview content?</key>
|
||||
<key alias="returnToPreviewDescription">You have ended preview mode, do you want to continue previewing this content?</key>
|
||||
<key alias="returnToPreviewButton">Preview</key>
|
||||
<key alias="returnToPreviewHeadline">Preview website?</key>
|
||||
<key alias="returnToPreviewDescription">ou have ended preview mode, do you want to enable it again to view the latest saved version of your website?</key>
|
||||
<key alias="returnToPreviewAcceptButton">Preview latest version</key>
|
||||
<key alias="returnToPreviewDeclineButton">View published version</key>
|
||||
<key alias="viewPublishedContentHeadline">View published version?</key>
|
||||
<key alias="viewPublishedContentDescription">You are in Preview Mode, do you want exit in order to view the published version of your website?</key>
|
||||
<key alias="viewPublishedContentAcceptButton">View published version</key>
|
||||
|
||||
Reference in New Issue
Block a user