update caching headers

This commit is contained in:
Luke Pulverenti 2016-11-27 14:36:56 -05:00
parent b485c4ca51
commit 26ef23d628
12 changed files with 139 additions and 67 deletions

View File

@ -397,16 +397,34 @@ namespace Emby.Common.Implementations.IO
private FileAccess GetFileAccess(FileAccessMode mode) private FileAccess GetFileAccess(FileAccessMode mode)
{ {
var val = (int)mode; switch (mode)
{
return (FileAccess)val; case FileAccessMode.ReadWrite:
return FileAccess.ReadWrite;
case FileAccessMode.Write:
return FileAccess.Write;
case FileAccessMode.Read:
return FileAccess.Read;
default:
throw new Exception("Unrecognized FileAccessMode");
}
} }
private FileShare GetFileShare(FileShareMode mode) private FileShare GetFileShare(FileShareMode mode)
{ {
var val = (int)mode; switch (mode)
{
return (FileShare)val; case FileShareMode.ReadWrite:
return FileShare.ReadWrite;
case FileShareMode.Write:
return FileShare.Write;
case FileShareMode.Read:
return FileShare.Read;
case FileShareMode.None:
return FileShare.None;
default:
throw new Exception("Unrecognized FileShareMode");
}
} }
public void SetHidden(string path, bool isHidden) public void SetHidden(string path, bool isHidden)

View File

@ -551,7 +551,7 @@ namespace Emby.Server.Core
DisplayPreferencesRepository = displayPreferencesRepo; DisplayPreferencesRepository = displayPreferencesRepo;
RegisterSingleInstance(DisplayPreferencesRepository); RegisterSingleInstance(DisplayPreferencesRepository);
var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager.GetLogger("SqliteItemRepository"), MemoryStreamFactory, assemblyInfo, FileSystemManager, EnvironmentInfo); var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager.GetLogger("SqliteItemRepository"), MemoryStreamFactory, assemblyInfo, FileSystemManager, EnvironmentInfo, TimerFactory);
ItemRepository = itemRepo; ItemRepository = itemRepo;
RegisterSingleInstance(ItemRepository); RegisterSingleInstance(ItemRepository);

View File

@ -88,11 +88,14 @@ namespace Emby.Server.Implementations.Data
var queries = new List<string> var queries = new List<string>
{ {
"PRAGMA temp_store = memory",
//"PRAGMA journal_mode=WAL"
//"PRAGMA cache size=-10000" //"PRAGMA cache size=-10000"
}; };
if (EnableTempStoreMemory)
{
queries.Add("PRAGMA temp_store = memory");
}
//var cacheSize = CacheSize; //var cacheSize = CacheSize;
//if (cacheSize.HasValue) //if (cacheSize.HasValue)
//{ //{
@ -116,7 +119,7 @@ namespace Emby.Server.Implementations.Data
db.ExecuteAll(string.Join(";", queries.ToArray())); db.ExecuteAll(string.Join(";", queries.ToArray()));
} }
} }
else else if (queries.Count > 0)
{ {
db.ExecuteAll(string.Join(";", queries.ToArray())); db.ExecuteAll(string.Join(";", queries.ToArray()));
} }
@ -124,6 +127,14 @@ namespace Emby.Server.Implementations.Data
return db; return db;
} }
protected virtual bool EnableTempStoreMemory
{
get
{
return false;
}
}
protected virtual int? CacheSize protected virtual int? CacheSize
{ {
get get

View File

@ -63,8 +63,8 @@ namespace Emby.Server.Implementations.Data
string[] queries = { string[] queries = {
"create table if not exists userdisplaypreferences (id GUID, userId GUID, client text, data BLOB)", "create table if not exists userdisplaypreferences (id GUID, userId GUID, client text, data BLOB)",
"create unique index if not exists userdisplaypreferencesindex on userdisplaypreferences (id, userId, client)" "create unique index if not exists userdisplaypreferencesindex on userdisplaypreferences (id, userId, client)"
}; };
connection.RunQueries(queries); connection.RunQueries(queries);
@ -107,10 +107,10 @@ namespace Emby.Server.Implementations.Data
private void SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client, IDatabaseConnection connection) private void SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client, IDatabaseConnection connection)
{ {
using (var statement = connection.PrepareStatement("replace into userdisplaypreferences (id, userid, client, data) values (@id, @userid, @client, @data)")) var serialized = _jsonSerializer.SerializeToBytes(displayPreferences, _memoryStreamProvider);
{
var serialized = _jsonSerializer.SerializeToBytes(displayPreferences, _memoryStreamProvider);
using (var statement = connection.PrepareStatement("replace into userdisplaypreferences (id, userid, client, data) values (@id, @userId, @client, @data)"))
{
statement.TryBind("@id", displayPreferences.Id.ToGuidParamValue()); statement.TryBind("@id", displayPreferences.Id.ToGuidParamValue());
statement.TryBind("@userId", userId.ToGuidParamValue()); statement.TryBind("@userId", userId.ToGuidParamValue());
statement.TryBind("@client", client); statement.TryBind("@client", client);

View File

@ -30,6 +30,7 @@ using MediaBrowser.Server.Implementations.Playlists;
using MediaBrowser.Model.Reflection; using MediaBrowser.Model.Reflection;
using SQLitePCL.pretty; using SQLitePCL.pretty;
using MediaBrowser.Model.System; using MediaBrowser.Model.System;
using MediaBrowser.Model.Threading;
namespace Emby.Server.Implementations.Data namespace Emby.Server.Implementations.Data
{ {
@ -68,11 +69,13 @@ namespace Emby.Server.Implementations.Data
private readonly IMemoryStreamFactory _memoryStreamProvider; private readonly IMemoryStreamFactory _memoryStreamProvider;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly IEnvironmentInfo _environmentInfo; private readonly IEnvironmentInfo _environmentInfo;
private readonly ITimerFactory _timerFactory;
private ITimer _shrinkMemoryTimer;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class. /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
/// </summary> /// </summary>
public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogger logger, IMemoryStreamFactory memoryStreamProvider, IAssemblyInfo assemblyInfo, IFileSystem fileSystem, IEnvironmentInfo environmentInfo) public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogger logger, IMemoryStreamFactory memoryStreamProvider, IAssemblyInfo assemblyInfo, IFileSystem fileSystem, IEnvironmentInfo environmentInfo, ITimerFactory timerFactory)
: base(logger) : base(logger)
{ {
if (config == null) if (config == null)
@ -89,6 +92,7 @@ namespace Emby.Server.Implementations.Data
_memoryStreamProvider = memoryStreamProvider; _memoryStreamProvider = memoryStreamProvider;
_fileSystem = fileSystem; _fileSystem = fileSystem;
_environmentInfo = environmentInfo; _environmentInfo = environmentInfo;
_timerFactory = timerFactory;
_typeMapper = new TypeMapper(assemblyInfo); _typeMapper = new TypeMapper(assemblyInfo);
_criticReviewsPath = Path.Combine(_config.ApplicationPaths.DataPath, "critic-reviews"); _criticReviewsPath = Path.Combine(_config.ApplicationPaths.DataPath, "critic-reviews");
@ -119,6 +123,14 @@ namespace Emby.Server.Implementations.Data
} }
} }
protected override bool EnableTempStoreMemory
{
get
{
return true;
}
}
private SQLiteDatabaseConnection _backgroundConnection; private SQLiteDatabaseConnection _backgroundConnection;
protected override void CloseConnection() protected override void CloseConnection()
{ {
@ -129,6 +141,12 @@ namespace Emby.Server.Implementations.Data
_backgroundConnection.Dispose(); _backgroundConnection.Dispose();
_backgroundConnection = null; _backgroundConnection = null;
} }
if (_shrinkMemoryTimer != null)
{
_shrinkMemoryTimer.Dispose();
_shrinkMemoryTimer = null;
}
} }
/// <summary> /// <summary>
@ -364,13 +382,35 @@ namespace Emby.Server.Implementations.Data
connection.RunQueries(postQueries); connection.RunQueries(postQueries);
//SqliteExtensions.Attach(_connection, Path.Combine(_config.ApplicationPaths.DataPath, "userdata_v2.db"), "UserDataDb");
//await Vacuum(_connection).ConfigureAwait(false); //await Vacuum(_connection).ConfigureAwait(false);
} }
userDataRepo.Initialize(WriteLock); userDataRepo.Initialize(WriteLock);
_backgroundConnection = CreateConnection(true); _backgroundConnection = CreateConnection(true);
_shrinkMemoryTimer = _timerFactory.Create(OnShrinkMemoryTimerCallback, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(30));
}
private void OnShrinkMemoryTimerCallback(object state)
{
try
{
using (WriteLock.Write())
{
using (var connection = CreateConnection())
{
connection.RunQueries(new string[]
{
"pragma shrink_memory"
});
}
}
}
catch (Exception ex)
{
Logger.ErrorException("Error running shrink memory", ex);
}
} }
private readonly string[] _retriveItemColumns = private readonly string[] _retriveItemColumns =
@ -666,7 +706,7 @@ namespace Emby.Server.Implementations.Data
{ {
var requiresReset = false; var requiresReset = false;
var statements = db.PrepareAll(string.Join(";", new string[] var statements = db.PrepareAll(string.Join(";", new string[]
{ {
GetSaveItemCommandText(), GetSaveItemCommandText(),
"delete from AncestorIds where ItemId=@ItemId", "delete from AncestorIds where ItemId=@ItemId",

View File

@ -84,6 +84,14 @@ namespace Emby.Server.Implementations.Data
} }
} }
protected override bool EnableTempStoreMemory
{
get
{
return true;
}
}
private void ImportUserDataIfNeeded(IDatabaseConnection connection) private void ImportUserDataIfNeeded(IDatabaseConnection connection)
{ {
if (!_fileSystem.FileExists(_importFile)) if (!_fileSystem.FileExists(_importFile))

View File

@ -735,7 +735,7 @@ namespace Emby.Server.Implementations.HttpServer
/// <returns><c>true</c> if [is not modified] [the specified cache key]; otherwise, <c>false</c>.</returns> /// <returns><c>true</c> if [is not modified] [the specified cache key]; otherwise, <c>false</c>.</returns>
private bool IsNotModified(IRequest requestContext, Guid? cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration) private bool IsNotModified(IRequest requestContext, Guid? cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration)
{ {
var isNotModified = true; //var isNotModified = true;
var ifModifiedSinceHeader = requestContext.Headers.Get("If-Modified-Since"); var ifModifiedSinceHeader = requestContext.Headers.Get("If-Modified-Since");
@ -745,18 +745,23 @@ namespace Emby.Server.Implementations.HttpServer
if (DateTime.TryParse(ifModifiedSinceHeader, out ifModifiedSince)) if (DateTime.TryParse(ifModifiedSinceHeader, out ifModifiedSince))
{ {
isNotModified = IsNotModified(ifModifiedSince.ToUniversalTime(), cacheDuration, lastDateModified); if (IsNotModified(ifModifiedSince.ToUniversalTime(), cacheDuration, lastDateModified))
{
return true;
}
} }
} }
var ifNoneMatchHeader = requestContext.Headers.Get("If-None-Match"); var ifNoneMatchHeader = requestContext.Headers.Get("If-None-Match");
// Validate If-None-Match // Validate If-None-Match
if (isNotModified && (cacheKey.HasValue || !string.IsNullOrEmpty(ifNoneMatchHeader))) if ((cacheKey.HasValue || !string.IsNullOrEmpty(ifNoneMatchHeader)))
{ {
Guid ifNoneMatch; Guid ifNoneMatch;
if (Guid.TryParse(ifNoneMatchHeader ?? string.Empty, out ifNoneMatch)) ifNoneMatchHeader = (ifNoneMatchHeader ?? string.Empty).Trim('\"');
if (Guid.TryParse(ifNoneMatchHeader, out ifNoneMatch))
{ {
if (cacheKey.HasValue && cacheKey.Value == ifNoneMatch) if (cacheKey.HasValue && cacheKey.Value == ifNoneMatch)
{ {

View File

@ -83,6 +83,14 @@ namespace Emby.Server.Implementations.Sync
} }
} }
protected override bool EnableTempStoreMemory
{
get
{
return true;
}
}
private const string BaseJobSelectText = "select Id, TargetId, Name, Profile, Quality, Bitrate, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs"; private const string BaseJobSelectText = "select Id, TargetId, Name, Profile, Quality, Bitrate, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs";
private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex, ItemDateModifiedTicks from SyncJobItems"; private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex, ItemDateModifiedTicks from SyncJobItems";

View File

@ -369,7 +369,6 @@ namespace MediaBrowser.Model.IO
Append = 6 Append = 6
} }
[Flags]
public enum FileAccessMode public enum FileAccessMode
{ {
// //
@ -388,7 +387,6 @@ namespace MediaBrowser.Model.IO
ReadWrite = 3 ReadWrite = 3
} }
[Flags]
public enum FileShareMode public enum FileShareMode
{ {
// //
@ -417,16 +415,7 @@ namespace MediaBrowser.Model.IO
// or another process) will fail until the file is closed. However, even if this // or another process) will fail until the file is closed. However, even if this
// flag is specified, additional permissions might still be needed to access the // flag is specified, additional permissions might still be needed to access the
// file. // file.
ReadWrite = 3, ReadWrite = 3
//
// Summary:
// Allows subsequent deleting of a file.
Delete = 4,
//
// Summary:
// Makes the file handle inheritable by child processes. This is not directly supported
// by Win32.
Inheritable = 16
} }
} }

View File

@ -32,7 +32,6 @@ namespace MediaBrowser.Model.LiveTv
public LiveTvOptions() public LiveTvOptions()
{ {
EnableMovieProviders = true; EnableMovieProviders = true;
EnableRecordingSubfolders = true;
TunerHosts = new List<TunerHostInfo>(); TunerHosts = new List<TunerHostInfo>();
ListingProviders = new List<ListingsProviderInfo>(); ListingProviders = new List<ListingsProviderInfo>();
MediaLocationsCreated = new string[] { }; MediaLocationsCreated = new string[] { };

View File

@ -78,16 +78,15 @@ namespace MediaBrowser.Providers.Manager
bool hasRefreshedMetadata = true; bool hasRefreshedMetadata = true;
bool hasRefreshedImages = true; bool hasRefreshedImages = true;
var isFirstRefresh = item.DateLastRefreshed == default(DateTime);
// Next run metadata providers // Next run metadata providers
if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None) if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None)
{ {
var providers = GetProviders(item, refreshOptions, requiresRefresh) var providers = GetProviders(item, refreshOptions, isFirstRefresh, requiresRefresh)
.ToList(); .ToList();
var dateLastRefresh = item.DateLastRefreshed; if (providers.Count > 0 || isFirstRefresh)
if (providers.Count > 0 || dateLastRefresh == default(DateTime))
{ {
if (item.BeforeMetadataRefresh()) if (item.BeforeMetadataRefresh())
{ {
@ -110,11 +109,7 @@ namespace MediaBrowser.Providers.Manager
var result = await RefreshWithProviders(metadataResult, id, refreshOptions, providers, itemImageProvider, cancellationToken).ConfigureAwait(false); var result = await RefreshWithProviders(metadataResult, id, refreshOptions, providers, itemImageProvider, cancellationToken).ConfigureAwait(false);
updateType = updateType | result.UpdateType; updateType = updateType | result.UpdateType;
if (result.Failures == 0) if (result.Failures > 0)
{
hasRefreshedMetadata = true;
}
else
{ {
hasRefreshedMetadata = false; hasRefreshedMetadata = false;
} }
@ -138,19 +133,13 @@ namespace MediaBrowser.Providers.Manager
var result = await itemImageProvider.RefreshImages(itemOfType, libraryOptions, providers, refreshOptions, config, cancellationToken).ConfigureAwait(false); var result = await itemImageProvider.RefreshImages(itemOfType, libraryOptions, providers, refreshOptions, config, cancellationToken).ConfigureAwait(false);
updateType = updateType | result.UpdateType; updateType = updateType | result.UpdateType;
if (result.Failures == 0) if (result.Failures > 0)
{
hasRefreshedImages = true;
}
else
{ {
hasRefreshedImages = false; hasRefreshedImages = false;
} }
} }
} }
var isFirstRefresh = item.DateLastRefreshed == default(DateTime);
var beforeSaveResult = await BeforeSave(itemOfType, isFirstRefresh || refreshOptions.ReplaceAllMetadata || refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || requiresRefresh, updateType).ConfigureAwait(false); var beforeSaveResult = await BeforeSave(itemOfType, isFirstRefresh || refreshOptions.ReplaceAllMetadata || refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || requiresRefresh, updateType).ConfigureAwait(false);
updateType = updateType | beforeSaveResult; updateType = updateType | beforeSaveResult;
@ -373,15 +362,18 @@ namespace MediaBrowser.Providers.Manager
/// Gets the providers. /// Gets the providers.
/// </summary> /// </summary>
/// <returns>IEnumerable{`0}.</returns> /// <returns>IEnumerable{`0}.</returns>
protected IEnumerable<IMetadataProvider> GetProviders(IHasMetadata item, MetadataRefreshOptions options, bool requiresRefresh) protected IEnumerable<IMetadataProvider> GetProviders(IHasMetadata item, MetadataRefreshOptions options, bool isFirstRefresh, bool requiresRefresh)
{ {
// Get providers to refresh // Get providers to refresh
var providers = ((ProviderManager)ProviderManager).GetMetadataProviders<TItemType>(item).ToList(); var providers = ((ProviderManager)ProviderManager).GetMetadataProviders<TItemType>(item).ToList();
var dateLastRefresh = item.DateLastRefreshed; var metadataRefreshMode = options.MetadataRefreshMode;
// Run all if either of these flags are true // Run all if either of these flags are true
var runAllProviders = options.ReplaceAllMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || dateLastRefresh == default(DateTime) || requiresRefresh; var runAllProviders = options.ReplaceAllMetadata ||
metadataRefreshMode == MetadataRefreshMode.FullRefresh ||
(isFirstRefresh && metadataRefreshMode >= MetadataRefreshMode.Default) ||
(requiresRefresh && metadataRefreshMode >= MetadataRefreshMode.Default);
if (!runAllProviders) if (!runAllProviders)
{ {
@ -404,6 +396,9 @@ namespace MediaBrowser.Providers.Manager
} }
else else
{ {
var anyRemoteProvidersChanged = providersWithChanges.OfType<IRemoteMetadataProvider>()
.Any();
providers = providers.Where(i => providers = providers.Where(i =>
{ {
// If any provider reports a change, always run local ones as well // If any provider reports a change, always run local ones as well
@ -412,9 +407,6 @@ namespace MediaBrowser.Providers.Manager
return true; return true;
} }
var anyRemoteProvidersChanged = providersWithChanges.OfType<IRemoteMetadataProvider>()
.Any();
// If any remote providers changed, run them all so that priorities can be honored // If any remote providers changed, run them all so that priorities can be honored
if (i is IRemoteMetadataProvider) if (i is IRemoteMetadataProvider)
{ {

View File

@ -911,17 +911,14 @@ namespace MediaBrowser.XbmcMetadata.Savers
var image = item.GetImageInfo(ImageType.Primary, 0); var image = item.GetImageInfo(ImageType.Primary, 0);
if (image != null && image.IsLocalFile) if (image != null)
{ {
writer.WriteElementString("poster", GetPathToSave(image.Path, libraryManager, config)); writer.WriteElementString("poster", GetImagePathToSave(image, libraryManager, config));
} }
foreach (var backdrop in item.GetImages(ImageType.Backdrop)) foreach (var backdrop in item.GetImages(ImageType.Backdrop))
{ {
if (backdrop.IsLocalFile) writer.WriteElementString("fanart", GetImagePathToSave(backdrop, libraryManager, config));
{
writer.WriteElementString("fanart", GetPathToSave(backdrop.Path, libraryManager, config));
}
} }
writer.WriteEndElement(); writer.WriteEndElement();
@ -1012,9 +1009,9 @@ namespace MediaBrowser.XbmcMetadata.Savers
var personEntity = libraryManager.GetPerson(person.Name); var personEntity = libraryManager.GetPerson(person.Name);
var image = personEntity.GetImageInfo(ImageType.Primary, 0); var image = personEntity.GetImageInfo(ImageType.Primary, 0);
if (image != null && image.IsLocalFile) if (image != null)
{ {
writer.WriteElementString("thumb", GetPathToSave(image.Path, libraryManager, config)); writer.WriteElementString("thumb", GetImagePathToSave(image, libraryManager, config));
} }
} }
catch (Exception) catch (Exception)
@ -1026,9 +1023,14 @@ namespace MediaBrowser.XbmcMetadata.Savers
} }
} }
private static string GetPathToSave(string path, ILibraryManager libraryManager, IServerConfigurationManager config) private static string GetImagePathToSave(ItemImageInfo image, ILibraryManager libraryManager, IServerConfigurationManager config)
{ {
return libraryManager.GetPathAfterNetworkSubstitution(path); if (!image.IsLocalFile)
{
return image.Path;
}
return libraryManager.GetPathAfterNetworkSubstitution(image.Path);
} }
private static bool IsPersonType(PersonInfo person, string type) private static bool IsPersonType(PersonInfo person, string type)