aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Common
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Common')
-rw-r--r--MediaBrowser.Common/Kernel/BaseKernel.cs60
-rw-r--r--MediaBrowser.Common/Kernel/IApplicationHost.cs42
-rw-r--r--MediaBrowser.Common/Kernel/IKernel.cs18
-rw-r--r--MediaBrowser.Common/Kernel/TcpManager.cs6
-rw-r--r--MediaBrowser.Common/MediaBrowser.Common.csproj7
-rw-r--r--MediaBrowser.Common/Net/BaseRestService.cs458
-rw-r--r--MediaBrowser.Common/Net/Handlers/BaseActionHandler.cs31
-rw-r--r--MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs133
-rw-r--r--MediaBrowser.Common/Net/IHttpClient.cs8
-rw-r--r--MediaBrowser.Common/Net/IHttpServer.cs6
-rw-r--r--MediaBrowser.Common/Net/IRestfulService.cs2
-rw-r--r--MediaBrowser.Common/Net/WebSocketConnection.cs28
-rw-r--r--MediaBrowser.Common/Plugins/BasePlugin.cs5
-rw-r--r--MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs424
-rw-r--r--MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs56
-rw-r--r--MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs86
-rw-r--r--MediaBrowser.Common/ScheduledTasks/ITaskManager.cs35
-rw-r--r--MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs2
18 files changed, 146 insertions, 1261 deletions
diff --git a/MediaBrowser.Common/Kernel/BaseKernel.cs b/MediaBrowser.Common/Kernel/BaseKernel.cs
index eb5381e206..5b8da5d094 100644
--- a/MediaBrowser.Common/Kernel/BaseKernel.cs
+++ b/MediaBrowser.Common/Kernel/BaseKernel.cs
@@ -40,9 +40,6 @@ namespace MediaBrowser.Common.Kernel
internal void OnConfigurationUpdated()
{
EventHelper.QueueEventIfNotNull(ConfigurationUpdated, this, EventArgs.Empty, Logger);
-
- // Notify connected clients
- TcpManager.SendWebSocketMessage("ConfigurationUpdated", Configuration);
}
#endregion
@@ -141,12 +138,6 @@ namespace MediaBrowser.Common.Kernel
}
/// <summary>
- /// Gets a value indicating whether this instance is first run.
- /// </summary>
- /// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value>
- public bool IsFirstRun { get; private set; }
-
- /// <summary>
/// Gets or sets a value indicating whether this instance has changes that require the entire application to restart.
/// </summary>
/// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value>
@@ -177,12 +168,6 @@ namespace MediaBrowser.Common.Kernel
public TcpManager TcpManager { get; private set; }
/// <summary>
- /// Gets the rest services.
- /// </summary>
- /// <value>The rest services.</value>
- public IEnumerable<IRestfulService> RestServices { get; private set; }
-
- /// <summary>
/// Gets the UDP server port number.
/// This can't be configurable because then the user would have to configure their client to discover the server.
/// </summary>
@@ -280,19 +265,7 @@ namespace MediaBrowser.Common.Kernel
/// Initializes the Kernel
/// </summary>
/// <returns>Task.</returns>
- public Task Init()
- {
- IsFirstRun = !File.Exists(ApplicationPaths.SystemConfigurationFilePath);
-
- // Performs initializations that can be reloaded at anytime
- return Reload();
- }
-
- /// <summary>
- /// Performs initializations that can be reloaded at anytime
- /// </summary>
- /// <returns>Task.</returns>
- public async Task Reload()
+ public async Task Init()
{
OnReloadBeginning();
@@ -312,8 +285,6 @@ namespace MediaBrowser.Common.Kernel
// Set these to null so that they can be lazy loaded again
Configuration = null;
- Logger.Info("Version {0} initializing", ApplicationVersion);
-
await OnConfigurationLoaded().ConfigureAwait(false);
FindParts();
@@ -348,7 +319,6 @@ namespace MediaBrowser.Common.Kernel
/// </summary>
protected virtual void FindParts()
{
- RestServices = ApplicationHost.GetExports<IRestfulService>();
WebSocketListeners = ApplicationHost.GetExports<IWebSocketListener>();
Plugins = ApplicationHost.GetExports<IPlugin>();
}
@@ -426,18 +396,6 @@ namespace MediaBrowser.Common.Kernel
}
/// <summary>
- /// Gets the current application version
- /// </summary>
- /// <value>The application version.</value>
- public Version ApplicationVersion
- {
- get
- {
- return GetType().Assembly.GetName().Version;
- }
- }
-
- /// <summary>
/// Performs the pending restart.
/// </summary>
/// <returns>Task.</returns>
@@ -445,7 +403,9 @@ namespace MediaBrowser.Common.Kernel
{
if (HasPendingRestart)
{
- RestartApplication();
+ Logger.Info("Restarting the application");
+
+ ApplicationHost.Restart();
}
else
{
@@ -454,16 +414,6 @@ namespace MediaBrowser.Common.Kernel
}
/// <summary>
- /// Restarts the application.
- /// </summary>
- protected void RestartApplication()
- {
- Logger.Info("Restarting the application");
-
- ApplicationHost.Restart();
- }
-
- /// <summary>
/// Gets the system status.
/// </summary>
/// <returns>SystemInfo.</returns>
@@ -472,7 +422,7 @@ namespace MediaBrowser.Common.Kernel
return new SystemInfo
{
HasPendingRestart = HasPendingRestart,
- Version = ApplicationVersion.ToString(),
+ Version = ApplicationHost.ApplicationVersion.ToString(),
IsNetworkDeployed = ApplicationHost.CanSelfUpdate,
WebSocketPortNumber = TcpManager.WebSocketPortNumber,
SupportsNativeWebSocket = TcpManager.SupportsNativeWebSocket,
diff --git a/MediaBrowser.Common/Kernel/IApplicationHost.cs b/MediaBrowser.Common/Kernel/IApplicationHost.cs
index 4b564581b4..af9b039bc0 100644
--- a/MediaBrowser.Common/Kernel/IApplicationHost.cs
+++ b/MediaBrowser.Common/Kernel/IApplicationHost.cs
@@ -22,6 +22,12 @@ namespace MediaBrowser.Common.Kernel
void ReloadLogger();
/// <summary>
+ /// Gets the application version.
+ /// </summary>
+ /// <value>The application version.</value>
+ Version ApplicationVersion { get; }
+
+ /// <summary>
/// Gets the log file path.
/// </summary>
/// <value>The log file path.</value>
@@ -34,10 +40,16 @@ namespace MediaBrowser.Common.Kernel
bool CanSelfUpdate { get; }
/// <summary>
+ /// Gets a value indicating whether this instance is first run.
+ /// </summary>
+ /// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value>
+ bool IsFirstRun { get; }
+
+ /// <summary>
/// Gets the failed assemblies.
/// </summary>
/// <value>The failed assemblies.</value>
- IEnumerable<string> FailedAssemblies { get; }
+ List<string> FailedAssemblies { get; }
/// <summary>
/// Gets all concrete types.
@@ -73,34 +85,6 @@ namespace MediaBrowser.Common.Kernel
object CreateInstance(Type type);
/// <summary>
- /// Registers a service that other classes can use as a dependancy.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="obj">The obj.</param>
- void RegisterSingleInstance<T>(T obj) where T : class;
-
- /// <summary>
- /// Registers the single instance.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="func">The func.</param>
- void RegisterSingleInstance<T>(Func<T> func) where T : class;
-
- /// <summary>
- /// Registers the specified func.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="func">The func.</param>
- void Register<T>(Func<T> func) where T : class;
-
- /// <summary>
- /// Registers the specified service type.
- /// </summary>
- /// <param name="serviceType">Type of the service.</param>
- /// <param name="implementation">Type of the implementation.</param>
- void Register(Type serviceType, Type implementation);
-
- /// <summary>
/// Resolves this instance.
/// </summary>
/// <typeparam name="T"></typeparam>
diff --git a/MediaBrowser.Common/Kernel/IKernel.cs b/MediaBrowser.Common/Kernel/IKernel.cs
index fb629a24df..06c2e7b64c 100644
--- a/MediaBrowser.Common/Kernel/IKernel.cs
+++ b/MediaBrowser.Common/Kernel/IKernel.cs
@@ -38,12 +38,6 @@ namespace MediaBrowser.Common.Kernel
Task Init();
/// <summary>
- /// Reloads this instance.
- /// </summary>
- /// <returns>Task.</returns>
- Task Reload();
-
- /// <summary>
/// Gets or sets a value indicating whether this instance has pending kernel reload.
/// </summary>
/// <value><c>true</c> if this instance has pending kernel reload; otherwise, <c>false</c>.</value>
@@ -107,12 +101,6 @@ namespace MediaBrowser.Common.Kernel
string HttpServerUrlPrefix { get; }
/// <summary>
- /// Gets a value indicating whether this instance is first run.
- /// </summary>
- /// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value>
- bool IsFirstRun { get; }
-
- /// <summary>
/// Gets the TCP manager.
/// </summary>
/// <value>The TCP manager.</value>
@@ -140,12 +128,6 @@ namespace MediaBrowser.Common.Kernel
event EventHandler<EventArgs> ConfigurationUpdated;
/// <summary>
- /// Gets the rest services.
- /// </summary>
- /// <value>The rest services.</value>
- IEnumerable<IRestfulService> RestServices { get; }
-
- /// <summary>
/// Notifies the pending restart.
/// </summary>
void NotifyPendingRestart();
diff --git a/MediaBrowser.Common/Kernel/TcpManager.cs b/MediaBrowser.Common/Kernel/TcpManager.cs
index 1c76b42f96..2dfed501af 100644
--- a/MediaBrowser.Common/Kernel/TcpManager.cs
+++ b/MediaBrowser.Common/Kernel/TcpManager.cs
@@ -39,7 +39,7 @@ namespace MediaBrowser.Common.Kernel
/// </summary>
/// <value>The json serializer.</value>
private readonly IJsonSerializer _jsonSerializer;
-
+
/// <summary>
/// This subscribes to HttpListener requests and finds the appropriate BaseHandler to process it
/// </summary>
@@ -133,7 +133,7 @@ namespace MediaBrowser.Common.Kernel
_applicationHost = applicationHost;
_networkManager = networkManager;
- if (kernel.IsFirstRun)
+ if (applicationHost.IsFirstRun)
{
RegisterServerWithAdministratorAccess();
}
@@ -215,7 +215,7 @@ namespace MediaBrowser.Common.Kernel
/// <param name="e">The <see cref="WebSocketConnectEventArgs" /> instance containing the event data.</param>
void HttpServer_WebSocketConnected(object sender, WebSocketConnectEventArgs e)
{
- var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, ProcessWebSocketMessageReceived, _jsonSerializer, _logger);
+ var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger) { OnReceive = ProcessWebSocketMessageReceived };
_webSocketConnections.Add(connection);
}
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj
index bc3678a5e2..333c20beb7 100644
--- a/MediaBrowser.Common/MediaBrowser.Common.csproj
+++ b/MediaBrowser.Common/MediaBrowser.Common.csproj
@@ -95,8 +95,6 @@
<Compile Include="Kernel\IApplicationHost.cs" />
<Compile Include="Kernel\IKernel.cs" />
<Compile Include="Kernel\TcpManager.cs" />
- <Compile Include="Net\BaseRestService.cs" />
- <Compile Include="Net\Handlers\BaseActionHandler.cs" />
<Compile Include="Net\Handlers\IHttpServerHandler.cs" />
<Compile Include="Net\Handlers\StaticFileHandler.cs" />
<Compile Include="Net\IHttpClient.cs" />
@@ -122,6 +120,8 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
+ <Compile Include="ScheduledTasks\IScheduledTask.cs" />
+ <Compile Include="ScheduledTasks\IScheduledTaskWorker.cs" />
<Compile Include="ScheduledTasks\ITaskManager.cs" />
<Compile Include="ScheduledTasks\ITaskTrigger.cs" />
<Compile Include="ScheduledTasks\ScheduledTaskHelpers.cs" />
@@ -130,13 +130,10 @@
<Compile Include="Kernel\BaseKernel.cs" />
<Compile Include="Kernel\KernelContext.cs" />
<Compile Include="Net\Handlers\BaseHandler.cs" />
- <Compile Include="Net\Handlers\BaseSerializationHandler.cs" />
<Compile Include="Plugins\BasePlugin.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="ScheduledTasks\BaseScheduledTask.cs" />
<Compile Include="ScheduledTasks\DailyTrigger.cs" />
<Compile Include="ScheduledTasks\IntervalTrigger.cs" />
- <Compile Include="ScheduledTasks\IScheduledTask.cs" />
<Compile Include="ScheduledTasks\WeeklyTrigger.cs" />
</ItemGroup>
<ItemGroup>
diff --git a/MediaBrowser.Common/Net/BaseRestService.cs b/MediaBrowser.Common/Net/BaseRestService.cs
deleted file mode 100644
index a7e95fca2f..0000000000
--- a/MediaBrowser.Common/Net/BaseRestService.cs
+++ /dev/null
@@ -1,458 +0,0 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Kernel;
-using MediaBrowser.Model.Logging;
-using ServiceStack.Common;
-using ServiceStack.Common.Web;
-using ServiceStack.ServiceHost;
-using ServiceStack.ServiceInterface;
-using ServiceStack.WebHost.Endpoints;
-using System;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Common.Net
-{
- /// <summary>
- /// Class BaseRestService
- /// </summary>
- public class BaseRestService : Service, IRestfulService
- {
- /// <summary>
- /// Gets or sets the kernel.
- /// </summary>
- /// <value>The kernel.</value>
- public IKernel Kernel { get; set; }
-
- /// <summary>
- /// Gets or sets the logger.
- /// </summary>
- /// <value>The logger.</value>
- public ILogger Logger { get; set; }
-
- /// <summary>
- /// Gets a value indicating whether this instance is range request.
- /// </summary>
- /// <value><c>true</c> if this instance is range request; otherwise, <c>false</c>.</value>
- protected bool IsRangeRequest
- {
- get
- {
- return Request.Headers.AllKeys.Contains("Range");
- }
- }
-
- /// <summary>
- /// Adds the routes.
- /// </summary>
- /// <param name="appHost">The app host.</param>
- public virtual void Configure(IAppHost appHost)
- {
- }
-
- /// <summary>
- /// To the optimized result.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="result">The result.</param>
- /// <returns>System.Object.</returns>
- /// <exception cref="System.ArgumentNullException">result</exception>
- protected object ToOptimizedResult<T>(T result)
- where T : class
- {
- if (result == null)
- {
- throw new ArgumentNullException("result");
- }
-
- Response.AddHeader("Vary", "Accept-Encoding");
-
- return RequestContext.ToOptimizedResult(result);
- }
-
- /// <summary>
- /// To the optimized result using cache.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="cacheKey">The cache key.</param>
- /// <param name="lastDateModified">The last date modified.</param>
- /// <param name="cacheDuration">Duration of the cache.</param>
- /// <param name="factoryFn">The factory fn.</param>
- /// <returns>System.Object.</returns>
- /// <exception cref="System.ArgumentNullException">cacheKey</exception>
- protected object ToOptimizedResultUsingCache<T>(Guid cacheKey, DateTime lastDateModified, TimeSpan? cacheDuration, Func<T> factoryFn)
- where T : class
- {
- if (cacheKey == Guid.Empty)
- {
- throw new ArgumentNullException("cacheKey");
- }
- if (factoryFn == null)
- {
- throw new ArgumentNullException("factoryFn");
- }
-
- var key = cacheKey.ToString("N");
-
- var result = PreProcessCachedResult(cacheKey, key, lastDateModified, cacheDuration, string.Empty);
-
- if (result != null)
- {
- return result;
- }
-
- return ToOptimizedResult(factoryFn());
- }
-
- /// <summary>
- /// To the cached result.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="cacheKey">The cache key.</param>
- /// <param name="lastDateModified">The last date modified.</param>
- /// <param name="cacheDuration">Duration of the cache.</param>
- /// <param name="factoryFn">The factory fn.</param>
- /// <param name="contentType">Type of the content.</param>
- /// <returns>System.Object.</returns>
- /// <exception cref="System.ArgumentNullException">cacheKey</exception>
- protected object ToCachedResult<T>(Guid cacheKey, DateTime lastDateModified, TimeSpan? cacheDuration, Func<T> factoryFn, string contentType)
- where T : class
- {
- if (cacheKey == Guid.Empty)
- {
- throw new ArgumentNullException("cacheKey");
- }
- if (factoryFn == null)
- {
- throw new ArgumentNullException("factoryFn");
- }
-
- var key = cacheKey.ToString("N");
-
- var result = PreProcessCachedResult(cacheKey, key, lastDateModified, cacheDuration, contentType);
-
- if (result != null)
- {
- return result;
- }
-
- return factoryFn();
- }
-
- /// <summary>
- /// To the static file result.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns>System.Object.</returns>
- /// <exception cref="System.ArgumentNullException">path</exception>
- protected object ToStaticFileResult(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException("path");
- }
-
- var dateModified = File.GetLastWriteTimeUtc(path);
-
- var cacheKey = path + dateModified.Ticks;
-
- return ToStaticResult(cacheKey.GetMD5(), dateModified, null, MimeTypes.GetMimeType(path), () => Task.FromResult(GetFileStream(path)));
- }
-
- /// <summary>
- /// Gets the file stream.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns>Stream.</returns>
- private Stream GetFileStream(string path)
- {
- return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous);
- }
-
- /// <summary>
- /// To the static result.
- /// </summary>
- /// <param name="cacheKey">The cache key.</param>
- /// <param name="lastDateModified">The last date modified.</param>
- /// <param name="cacheDuration">Duration of the cache.</param>
- /// <param name="contentType">Type of the content.</param>
- /// <param name="factoryFn">The factory fn.</param>
- /// <returns>System.Object.</returns>
- /// <exception cref="System.ArgumentNullException">cacheKey</exception>
- protected object ToStaticResult(Guid cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration, string contentType, Func<Task<Stream>> factoryFn)
- {
- if (cacheKey == Guid.Empty)
- {
- throw new ArgumentNullException("cacheKey");
- }
- if (factoryFn == null)
- {
- throw new ArgumentNullException("factoryFn");
- }
-
- var key = cacheKey.ToString("N");
-
- var result = PreProcessCachedResult(cacheKey, key, lastDateModified, cacheDuration, contentType);
-
- if (result != null)
- {
- return result;
- }
-
- var compress = ShouldCompressResponse(contentType);
-
- if (compress)
- {
- Response.AddHeader("Vary", "Accept-Encoding");
- }
-
- return ToStaticResult(contentType, factoryFn, compress).Result;
- }
-
- /// <summary>
- /// Shoulds the compress response.
- /// </summary>
- /// <param name="contentType">Type of the content.</param>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
- private bool ShouldCompressResponse(string contentType)
- {
- // It will take some work to support compression with byte range requests
- if (IsRangeRequest)
- {
- return false;
- }
-
- // Don't compress media
- if (contentType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase) || contentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase))
- {
- return false;
- }
-
- // Don't compress images
- if (contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
- {
- return false;
- }
-
- if (contentType.StartsWith("font/", StringComparison.OrdinalIgnoreCase))
- {
- return false;
- }
- if (contentType.StartsWith("application/", StringComparison.OrdinalIgnoreCase))
- {
- return false;
- }
-
- return true;
- }
-
- /// <summary>
- /// To the static result.
- /// </summary>
- /// <param name="contentType">Type of the content.</param>
- /// <param name="factoryFn">The factory fn.</param>
- /// <param name="compress">if set to <c>true</c> [compress].</param>
- /// <returns>System.Object.</returns>
- private async Task<object> ToStaticResult(string contentType, Func<Task<Stream>> factoryFn, bool compress)
- {
- if (!compress || string.IsNullOrEmpty(RequestContext.CompressionType))
- {
- Response.ContentType = contentType;
-
- var stream = await factoryFn().ConfigureAwait(false);
-
- return new StreamWriter(stream);
- }
-
- string content;
-
- using (var stream = await factoryFn().ConfigureAwait(false))
- {
- using (var reader = new StreamReader(stream))
- {
- content = await reader.ReadToEndAsync().ConfigureAwait(false);
- }
- }
-
- var contents = content.Compress(RequestContext.CompressionType);
-
- return new CompressedResult(contents, RequestContext.CompressionType, contentType);
- }
-
- /// <summary>
- /// Pres the process optimized result.
- /// </summary>
- /// <param name="cacheKey">The cache key.</param>
- /// <param name="cacheKeyString">The cache key string.</param>
- /// <param name="lastDateModified">The last date modified.</param>
- /// <param name="cacheDuration">Duration of the cache.</param>
- /// <param name="contentType">Type of the content.</param>
- /// <returns>System.Object.</returns>
- private object PreProcessCachedResult(Guid cacheKey, string cacheKeyString, DateTime? lastDateModified, TimeSpan? cacheDuration, string contentType)
- {
- Response.AddHeader("ETag", cacheKeyString);
-
- if (IsNotModified(cacheKey, lastDateModified, cacheDuration))
- {
- AddAgeHeader(lastDateModified);
- AddExpiresHeader(cacheKeyString, cacheDuration);
- //ctx.Response.SendChunked = false;
-
- if (!string.IsNullOrEmpty(contentType))
- {
- Response.ContentType = contentType;
- }
-
- return new HttpResult(new byte[] { }, HttpStatusCode.NotModified);
- }
-
- SetCachingHeaders(cacheKeyString, lastDateModified, cacheDuration);
-
- return null;
- }
-
- /// <summary>
- /// Determines whether [is not modified] [the specified cache key].
- /// </summary>
- /// <param name="cacheKey">The cache key.</param>
- /// <param name="lastDateModified">The last date modified.</param>
- /// <param name="cacheDuration">Duration of the cache.</param>
- /// <returns><c>true</c> if [is not modified] [the specified cache key]; otherwise, <c>false</c>.</returns>
- private bool IsNotModified(Guid? cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration)
- {
- var isNotModified = true;
-
- if (Request.Headers.AllKeys.Contains("If-Modified-Since"))
- {
- DateTime ifModifiedSince;
-
- if (DateTime.TryParse(Request.Headers["If-Modified-Since"], out ifModifiedSince))
- {
- isNotModified = IsNotModified(ifModifiedSince.ToUniversalTime(), cacheDuration, lastDateModified);
- }
- }
-
- // Validate If-None-Match
- if (isNotModified && (cacheKey.HasValue || !string.IsNullOrEmpty(Request.Headers["If-None-Match"])))
- {
- Guid ifNoneMatch;
-
- if (Guid.TryParse(Request.Headers["If-None-Match"] ?? string.Empty, out ifNoneMatch))
- {
- if (cacheKey.HasValue && cacheKey.Value == ifNoneMatch)
- {
- return true;
- }
- }
- }
-
- return false;
- }
-
- /// <summary>
- /// Determines whether [is not modified] [the specified if modified since].
- /// </summary>
- /// <param name="ifModifiedSince">If modified since.</param>
- /// <param name="cacheDuration">Duration of the cache.</param>
- /// <param name="dateModified">The date modified.</param>
- /// <returns><c>true</c> if [is not modified] [the specified if modified since]; otherwise, <c>false</c>.</returns>
- private bool IsNotModified(DateTime ifModifiedSince, TimeSpan? cacheDuration, DateTime? dateModified)
- {
- if (dateModified.HasValue)
- {
- var lastModified = NormalizeDateForComparison(dateModified.Value);
- ifModifiedSince = NormalizeDateForComparison(ifModifiedSince);
-
- return lastModified <= ifModifiedSince;
- }
-
- if (cacheDuration.HasValue)
- {
- var cacheExpirationDate = ifModifiedSince.Add(cacheDuration.Value);
-
- if (DateTime.UtcNow < cacheExpirationDate)
- {
- return true;
- }
- }
-
- return false;
- }
-
-
- /// <summary>
- /// When the browser sends the IfModifiedDate, it's precision is limited to seconds, so this will account for that
- /// </summary>
- /// <param name="date">The date.</param>
- /// <returns>DateTime.</returns>
- private DateTime NormalizeDateForComparison(DateTime date)
- {
- return new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Kind);
- }
-
- /// <summary>
- /// Sets the caching headers.
- /// </summary>
- /// <param name="cacheKey">The cache key.</param>
- /// <param name="lastDateModified">The last date modified.</param>
- /// <param name="cacheDuration">Duration of the cache.</param>
- private void SetCachingHeaders(string cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration)
- {
- // Don't specify both last modified and Etag, unless caching unconditionally. They are redundant
- // https://developers.google.com/speed/docs/best-practices/caching#LeverageBrowserCaching
- if (lastDateModified.HasValue && (string.IsNullOrEmpty(cacheKey) || cacheDuration.HasValue))
- {
- AddAgeHeader(lastDateModified);
- Response.AddHeader("LastModified", lastDateModified.Value.ToString("r"));
- }
-
- if (cacheDuration.HasValue)
- {
- Response.AddHeader("Cache-Control", "public, max-age=" + Convert.ToInt32(cacheDuration.Value.TotalSeconds));
- }
- else if (!string.IsNullOrEmpty(cacheKey))
- {
- Response.AddHeader("Cache-Control", "public");
- }
- else
- {
- Response.AddHeader("Cache-Control", "no-cache, no-store, must-revalidate");
- Response.AddHeader("pragma", "no-cache, no-store, must-revalidate");
- }
-
- AddExpiresHeader(cacheKey, cacheDuration);
- }
-
- /// <summary>
- /// Adds the expires header.
- /// </summary>
- /// <param name="cacheKey">The cache key.</param>
- /// <param name="cacheDuration">Duration of the cache.</param>
- private void AddExpiresHeader(string cacheKey, TimeSpan? cacheDuration)
- {
- if (cacheDuration.HasValue)
- {
- Response.AddHeader("Expires", DateTime.UtcNow.Add(cacheDuration.Value).ToString("r"));
- }
- else if (string.IsNullOrEmpty(cacheKey))
- {
- Response.AddHeader("Expires", "-1");
- }
- }
-
- /// <summary>
- /// Adds the age header.
- /// </summary>
- /// <param name="lastDateModified">The last date modified.</param>
- private void AddAgeHeader(DateTime? lastDateModified)
- {
- if (lastDateModified.HasValue)
- {
- Response.AddHeader("Age", Convert.ToInt64((DateTime.UtcNow - lastDateModified.Value).TotalSeconds).ToString(CultureInfo.InvariantCulture));
- }
- }
- }
-}
diff --git a/MediaBrowser.Common/Net/Handlers/BaseActionHandler.cs b/MediaBrowser.Common/Net/Handlers/BaseActionHandler.cs
deleted file mode 100644
index 72df88519b..0000000000
--- a/MediaBrowser.Common/Net/Handlers/BaseActionHandler.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using MediaBrowser.Common.Kernel;
-using MediaBrowser.Model.Entities;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Common.Net.Handlers
-{
- /// <summary>
- /// Class BaseActionHandler
- /// </summary>
- /// <typeparam name="TKernelType">The type of the T kernel type.</typeparam>
- public abstract class BaseActionHandler<TKernelType> : BaseSerializationHandler<TKernelType, EmptyRequestResult>
- where TKernelType : IKernel
- {
- /// <summary>
- /// Gets the object to serialize.
- /// </summary>
- /// <returns>Task{EmptyRequestResult}.</returns>
- protected override async Task<EmptyRequestResult> GetObjectToSerialize()
- {
- await ExecuteAction();
-
- return new EmptyRequestResult();
- }
-
- /// <summary>
- /// Performs the action.
- /// </summary>
- /// <returns>Task.</returns>
- protected abstract Task ExecuteAction();
- }
-}
diff --git a/MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs b/MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs
deleted file mode 100644
index a00152d784..0000000000
--- a/MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.Kernel;
-using System;
-using System.IO;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Common.Net.Handlers
-{
- /// <summary>
- /// Class BaseSerializationHandler
- /// </summary>
- /// <typeparam name="TKernelType">The type of the T kernel type.</typeparam>
- /// <typeparam name="T"></typeparam>
- public abstract class BaseSerializationHandler<TKernelType, T> : BaseHandler<TKernelType>
- where TKernelType : IKernel
- where T : class
- {
- /// <summary>
- /// Gets the serialization format.
- /// </summary>
- /// <value>The serialization format.</value>
- public SerializationFormat SerializationFormat
- {
- get
- {
- var format = QueryString["dataformat"];
-
- if (string.IsNullOrEmpty(format))
- {
- return SerializationFormat.Json;
- }
-
- return (SerializationFormat)Enum.Parse(typeof(SerializationFormat), format, true);
- }
- }
-
- /// <summary>
- /// Gets the type of the content.
- /// </summary>
- /// <value>The type of the content.</value>
- protected string ContentType
- {
- get
- {
- switch (SerializationFormat)
- {
- case SerializationFormat.Protobuf:
- return "application/x-protobuf";
- default:
- return MimeTypes.JsonMimeType;
- }
- }
- }
-
- /// <summary>
- /// Gets the response info.
- /// </summary>
- /// <returns>Task{ResponseInfo}.</returns>
- protected override Task<ResponseInfo> GetResponseInfo()
- {
- return Task.FromResult(new ResponseInfo
- {
- ContentType = ContentType
- });
- }
-
- /// <summary>
- /// Called when [processing request].
- /// </summary>
- /// <param name="responseInfo">The response info.</param>
- /// <returns>Task.</returns>
- protected override async Task OnProcessingRequest(ResponseInfo responseInfo)
- {
- _objectToSerialize = await GetObjectToSerialize().ConfigureAwait(false);
-
- if (_objectToSerialize == null)
- {
- throw new ResourceNotFoundException();
- }
-
- await base.OnProcessingRequest(responseInfo).ConfigureAwait(false);
- }
-
- /// <summary>
- /// The _object to serialize
- /// </summary>
- private T _objectToSerialize;
-
- /// <summary>
- /// Gets the object to serialize.
- /// </summary>
- /// <returns>Task{`0}.</returns>
- protected abstract Task<T> GetObjectToSerialize();
-
- /// <summary>
- /// Writes the response to output stream.
- /// </summary>
- /// <param name="stream">The stream.</param>
- /// <param name="responseInfo">The response info.</param>
- /// <param name="contentLength">Length of the content.</param>
- /// <returns>Task.</returns>
- protected override Task WriteResponseToOutputStream(Stream stream, ResponseInfo responseInfo, long? contentLength)
- {
- return Task.Run(() =>
- {
- //switch (SerializationFormat)
- //{
- // case SerializationFormat.Protobuf:
- // Kernel.ProtobufSerializer.SerializeToStream(_objectToSerialize, stream);
- // break;
- // default:
- // JsonSerializer.SerializeToStream(_objectToSerialize, stream);
- // break;
- //}
- });
- }
- }
-
- /// <summary>
- /// Enum SerializationFormat
- /// </summary>
- public enum SerializationFormat
- {
- /// <summary>
- /// The json
- /// </summary>
- Json,
- /// <summary>
- /// The protobuf
- /// </summary>
- Protobuf
- }
-}
diff --git a/MediaBrowser.Common/Net/IHttpClient.cs b/MediaBrowser.Common/Net/IHttpClient.cs
index ef0dd69b70..d02f08572d 100644
--- a/MediaBrowser.Common/Net/IHttpClient.cs
+++ b/MediaBrowser.Common/Net/IHttpClient.cs
@@ -6,6 +6,9 @@ using System.Threading.Tasks;
namespace MediaBrowser.Common.Net
{
+ /// <summary>
+ /// Interface IHttpClient
+ /// </summary>
public interface IHttpClient : IDisposable
{
/// <summary>
@@ -52,10 +55,5 @@ namespace MediaBrowser.Common.Net
/// <returns>Task{MemoryStream}.</returns>
/// <exception cref="MediaBrowser.Model.Net.HttpException"></exception>
Task<MemoryStream> GetMemoryStream(string url, SemaphoreSlim resourcePool, CancellationToken cancellationToken);
-
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- void Dispose();
}
} \ No newline at end of file
diff --git a/MediaBrowser.Common/Net/IHttpServer.cs b/MediaBrowser.Common/Net/IHttpServer.cs
index a640fb2626..45da18e1b8 100644
--- a/MediaBrowser.Common/Net/IHttpServer.cs
+++ b/MediaBrowser.Common/Net/IHttpServer.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
namespace MediaBrowser.Common.Net
{
@@ -40,5 +41,10 @@ namespace MediaBrowser.Common.Net
/// Occurs when [web socket connected].
/// </summary>
event EventHandler<WebSocketConnectEventArgs> WebSocketConnected;
+
+ /// <summary>
+ /// Inits this instance.
+ /// </summary>
+ void Init(IEnumerable<IRestfulService> services);
}
} \ No newline at end of file
diff --git a/MediaBrowser.Common/Net/IRestfulService.cs b/MediaBrowser.Common/Net/IRestfulService.cs
index 7fc6bb61ec..36055cd8a3 100644
--- a/MediaBrowser.Common/Net/IRestfulService.cs
+++ b/MediaBrowser.Common/Net/IRestfulService.cs
@@ -1,5 +1,4 @@
using ServiceStack.ServiceHost;
-using ServiceStack.WebHost.Endpoints;
using System;
namespace MediaBrowser.Common.Net
@@ -9,6 +8,5 @@ namespace MediaBrowser.Common.Net
/// </summary>
public interface IRestfulService : IService, IRequiresRequestContext, IDisposable
{
- void Configure(IAppHost appHost);
}
}
diff --git a/MediaBrowser.Common/Net/WebSocketConnection.cs b/MediaBrowser.Common/Net/WebSocketConnection.cs
index 36d649e3b1..1ad0e8f06f 100644
--- a/MediaBrowser.Common/Net/WebSocketConnection.cs
+++ b/MediaBrowser.Common/Net/WebSocketConnection.cs
@@ -41,17 +41,22 @@ namespace MediaBrowser.Common.Net
/// The _json serializer
/// </summary>
private readonly IJsonSerializer _jsonSerializer;
-
+
+ /// <summary>
+ /// Gets or sets the receive action.
+ /// </summary>
+ /// <value>The receive action.</value>
+ public Action<WebSocketMessageInfo> OnReceive { get; set; }
+
/// <summary>
/// Initializes a new instance of the <see cref="WebSocketConnection" /> class.
/// </summary>
/// <param name="socket">The socket.</param>
/// <param name="remoteEndPoint">The remote end point.</param>
- /// <param name="receiveAction">The receive action.</param>
/// <param name="jsonSerializer">The json serializer.</param>
/// <param name="logger">The logger.</param>
/// <exception cref="System.ArgumentNullException">socket</exception>
- public WebSocketConnection(IWebSocket socket, string remoteEndPoint, Action<WebSocketMessageInfo> receiveAction, IJsonSerializer jsonSerializer, ILogger logger)
+ public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger)
{
if (socket == null)
{
@@ -61,10 +66,6 @@ namespace MediaBrowser.Common.Net
{
throw new ArgumentNullException("remoteEndPoint");
}
- if (receiveAction == null)
- {
- throw new ArgumentNullException("receiveAction");
- }
if (jsonSerializer == null)
{
throw new ArgumentNullException("jsonSerializer");
@@ -76,7 +77,7 @@ namespace MediaBrowser.Common.Net
_jsonSerializer = jsonSerializer;
_socket = socket;
- _socket.OnReceiveDelegate = info => OnReceive(info, receiveAction);
+ _socket.OnReceiveDelegate = OnReceiveInternal;
RemoteEndPoint = remoteEndPoint;
_logger = logger;
}
@@ -85,21 +86,24 @@ namespace MediaBrowser.Common.Net
/// Called when [receive].
/// </summary>
/// <param name="bytes">The bytes.</param>
- /// <param name="callback">The callback.</param>
- private void OnReceive(byte[] bytes, Action<WebSocketMessageInfo> callback)
+ private void OnReceiveInternal(byte[] bytes)
{
+ if (OnReceive == null)
+ {
+ return;
+ }
try
{
WebSocketMessageInfo info;
using (var memoryStream = new MemoryStream(bytes))
{
- info = _jsonSerializer.DeserializeFromStream<WebSocketMessageInfo>(memoryStream);
+ info = (WebSocketMessageInfo)_jsonSerializer.DeserializeFromStream(memoryStream, typeof(WebSocketMessageInfo));
}
info.Connection = this;
- callback(info);
+ OnReceive(info);
}
catch (Exception ex)
{
diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs
index dad3867fcb..72c83a5cee 100644
--- a/MediaBrowser.Common/Plugins/BasePlugin.cs
+++ b/MediaBrowser.Common/Plugins/BasePlugin.cs
@@ -1,12 +1,12 @@
using MediaBrowser.Common.Kernel;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Plugins;
+using MediaBrowser.Model.Serialization;
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
-using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Common.Plugins
{
@@ -393,9 +393,6 @@ namespace MediaBrowser.Common.Plugins
{
XmlSerializer.SerializeToFile(Configuration, ConfigurationFilePath);
}
-
- // Notify connected UI's
- Kernel.TcpManager.SendWebSocketMessage("PluginConfigurationUpdated-" + Name, Configuration);
}
/// <summary>
diff --git a/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs b/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs
deleted file mode 100644
index 09ceaa9aee..0000000000
--- a/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs
+++ /dev/null
@@ -1,424 +0,0 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.Kernel;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Tasks;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Common.ScheduledTasks
-{
- /// <summary>
- /// Represents a task that can be executed at a scheduled time
- /// </summary>
- /// <typeparam name="TKernelType">The type of the T kernel type.</typeparam>
- public abstract class BaseScheduledTask<TKernelType> : IScheduledTask
- where TKernelType : class, IKernel
- {
- /// <summary>
- /// Gets the kernel.
- /// </summary>
- /// <value>The kernel.</value>
- protected TKernelType Kernel { get; private set; }
-
- /// <summary>
- /// Gets the logger.
- /// </summary>
- /// <value>The logger.</value>
- protected ILogger Logger { get; private set; }
-
- /// <summary>
- /// Gets the task manager.
- /// </summary>
- /// <value>The task manager.</value>
- protected ITaskManager TaskManager { get; private set; }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="BaseScheduledTask{TKernelType}" /> class.
- /// </summary>
- /// <param name="kernel">The kernel.</param>
- /// <param name="taskManager">The task manager.</param>
- /// <param name="logger">The logger.</param>
- /// <exception cref="System.ArgumentNullException">kernel</exception>
- protected BaseScheduledTask(TKernelType kernel, ITaskManager taskManager, ILogger logger)
- {
- if (kernel == null)
- {
- throw new ArgumentNullException("kernel");
- }
- if (taskManager == null)
- {
- throw new ArgumentNullException("taskManager");
- }
- if (logger == null)
- {
- throw new ArgumentNullException("logger");
- }
-
- Kernel = kernel;
- TaskManager = taskManager;
- Logger = logger;
-
- ReloadTriggerEvents(true);
- }
-
- /// <summary>
- /// The _last execution result
- /// </summary>
- private TaskResult _lastExecutionResult;
- /// <summary>
- /// The _last execution resultinitialized
- /// </summary>
- private bool _lastExecutionResultinitialized;
- /// <summary>
- /// The _last execution result sync lock
- /// </summary>
- private object _lastExecutionResultSyncLock = new object();
- /// <summary>
- /// Gets the last execution result.
- /// </summary>
- /// <value>The last execution result.</value>
- public TaskResult LastExecutionResult
- {
- get
- {
- LazyInitializer.EnsureInitialized(ref _lastExecutionResult, ref _lastExecutionResultinitialized, ref _lastExecutionResultSyncLock, () =>
- {
- try
- {
- return TaskManager.GetLastExecutionResult(this);
- }
- catch (IOException)
- {
- // File doesn't exist. No biggie
- return null;
- }
- });
-
- return _lastExecutionResult;
- }
- private set
- {
- _lastExecutionResult = value;
-
- _lastExecutionResultinitialized = value != null;
- }
- }
-
- /// <summary>
- /// Gets the current cancellation token
- /// </summary>
- /// <value>The current cancellation token source.</value>
- private CancellationTokenSource CurrentCancellationTokenSource { get; set; }
-
- /// <summary>
- /// Gets or sets the current execution start time.
- /// </summary>
- /// <value>The current execution start time.</value>
- private DateTime CurrentExecutionStartTime { get; set; }
-
- /// <summary>
- /// Gets the state.
- /// </summary>
- /// <value>The state.</value>
- public TaskState State
- {
- get
- {
- if (CurrentCancellationTokenSource != null)
- {
- return CurrentCancellationTokenSource.IsCancellationRequested
- ? TaskState.Cancelling
- : TaskState.Running;
- }
-
- return TaskState.Idle;
- }
- }
-
- /// <summary>
- /// Gets the current progress.
- /// </summary>
- /// <value>The current progress.</value>
- public double? CurrentProgress { get; private set; }
-
- /// <summary>
- /// The _triggers
- /// </summary>
- private IEnumerable<ITaskTrigger> _triggers;
- /// <summary>
- /// The _triggers initialized
- /// </summary>
- private bool _triggersInitialized;
- /// <summary>
- /// The _triggers sync lock
- /// </summary>
- private object _triggersSyncLock = new object();
- /// <summary>
- /// Gets the triggers that define when the task will run
- /// </summary>
- /// <value>The triggers.</value>
- /// <exception cref="System.ArgumentNullException">value</exception>
- public IEnumerable<ITaskTrigger> Triggers
- {
- get
- {
- LazyInitializer.EnsureInitialized(ref _triggers, ref _triggersInitialized, ref _triggersSyncLock, () => TaskManager.LoadTriggers(this));
-
- return _triggers;
- }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- // Cleanup current triggers
- if (_triggers != null)
- {
- DisposeTriggers();
- }
-
- _triggers = value.ToList();
-
- _triggersInitialized = true;
-
- ReloadTriggerEvents(false);
-
- TaskManager.SaveTriggers(this, _triggers);
- }
- }
-
- /// <summary>
- /// Creates the triggers that define when the task will run
- /// </summary>
- /// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- public abstract IEnumerable<ITaskTrigger> GetDefaultTriggers();
-
- /// <summary>
- /// Returns the task to be executed
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task.</returns>
- protected abstract Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress);
-
- /// <summary>
- /// Gets the name of the task
- /// </summary>
- /// <value>The name.</value>
- public abstract string Name { get; }
-
- /// <summary>
- /// Gets the description.
- /// </summary>
- /// <value>The description.</value>
- public abstract string Description { get; }
-
- /// <summary>
- /// Gets the category.
- /// </summary>
- /// <value>The category.</value>
- public virtual string Category
- {
- get { return "Application"; }
- }
-
- /// <summary>
- /// The _id
- /// </summary>
- private Guid? _id;
-
- /// <summary>
- /// Gets the unique id.
- /// </summary>
- /// <value>The unique id.</value>
- public Guid Id
- {
- get
- {
- if (!_id.HasValue)
- {
- _id = GetType().FullName.GetMD5();
- }
-
- return _id.Value;
- }
- }
-
- /// <summary>
- /// Reloads the trigger events.
- /// </summary>
- /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param>
- private void ReloadTriggerEvents(bool isApplicationStartup)
- {
- foreach (var trigger in Triggers)
- {
- trigger.Stop();
-
- trigger.Triggered -= trigger_Triggered;
- trigger.Triggered += trigger_Triggered;
- trigger.Start(isApplicationStartup);
- }
- }
-
- /// <summary>
- /// Handles the Triggered event of the trigger control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
- async void trigger_Triggered(object sender, EventArgs e)
- {
- var trigger = (ITaskTrigger)sender;
-
- Logger.Info("{0} fired for task: {1}", trigger.GetType().Name, Name);
-
- trigger.Stop();
-
- TaskManager.QueueScheduledTask(this);
-
- await Task.Delay(1000).ConfigureAwait(false);
-
- trigger.Start(false);
- }
-
- /// <summary>
- /// Executes the task
- /// </summary>
- /// <returns>Task.</returns>
- /// <exception cref="System.InvalidOperationException">Cannot execute a Task that is already running</exception>
- public async Task Execute()
- {
- // Cancel the current execution, if any
- if (CurrentCancellationTokenSource != null)
- {
- throw new InvalidOperationException("Cannot execute a Task that is already running");
- }
-
- CurrentCancellationTokenSource = new CancellationTokenSource();
-
- Logger.Info("Executing {0}", Name);
-
- var progress = new Progress<double>();
-
- progress.ProgressChanged += progress_ProgressChanged;
-
- TaskCompletionStatus status;
- CurrentExecutionStartTime = DateTime.UtcNow;
-
- Kernel.TcpManager.SendWebSocketMessage("ScheduledTaskBeginExecute", Name);
-
- try
- {
- await Task.Run(async () => await ExecuteInternal(CurrentCancellationTokenSource.Token, progress).ConfigureAwait(false)).ConfigureAwait(false);
-
- status = TaskCompletionStatus.Completed;
- }
- catch (OperationCanceledException)
- {
- status = TaskCompletionStatus.Cancelled;
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error", ex);
-
- status = TaskCompletionStatus.Failed;
- }
-
- var startTime = CurrentExecutionStartTime;
- var endTime = DateTime.UtcNow;
-
- Kernel.TcpManager.SendWebSocketMessage("ScheduledTaskEndExecute", LastExecutionResult);
-
- progress.ProgressChanged -= progress_ProgressChanged;
- CurrentCancellationTokenSource.Dispose();
- CurrentCancellationTokenSource = null;
- CurrentProgress = null;
-
- TaskManager.OnTaskCompleted(this, startTime, endTime, status);
- }
-
- /// <summary>
- /// Progress_s the progress changed.
- /// </summary>
- /// <param name="sender">The sender.</param>
- /// <param name="e">The e.</param>
- void progress_ProgressChanged(object sender, double e)
- {
- CurrentProgress = e;
- }
-
- /// <summary>
- /// Stops the task if it is currently executing
- /// </summary>
- /// <exception cref="System.InvalidOperationException">Cannot cancel a Task unless it is in the Running state.</exception>
- public void Cancel()
- {
- if (State != TaskState.Running)
- {
- throw new InvalidOperationException("Cannot cancel a Task unless it is in the Running state.");
- }
-
- CancelIfRunning();
- }
-
- /// <summary>
- /// Cancels if running.
- /// </summary>
- public void CancelIfRunning()
- {
- if (State == TaskState.Running)
- {
- Logger.Info("Attempting to cancel Scheduled Task {0}", Name);
- CurrentCancellationTokenSource.Cancel();
- }
- }
-
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected virtual void Dispose(bool dispose)
- {
- if (dispose)
- {
- DisposeTriggers();
-
- if (State == TaskState.Running)
- {
- TaskManager.OnTaskCompleted(this, CurrentExecutionStartTime, DateTime.UtcNow, TaskCompletionStatus.Aborted);
- }
-
- if (CurrentCancellationTokenSource != null)
- {
- CurrentCancellationTokenSource.Dispose();
- }
- }
- }
-
- /// <summary>
- /// Disposes each trigger
- /// </summary>
- private void DisposeTriggers()
- {
- foreach (var trigger in Triggers)
- {
- trigger.Triggered -= trigger_Triggered;
- trigger.Stop();
- }
- }
- }
-}
diff --git a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs
index 6f3a3857fe..351e96c7d5 100644
--- a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs
+++ b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs
@@ -1,40 +1,16 @@
-using MediaBrowser.Model.Tasks;
-using System;
+using System;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Common.ScheduledTasks
{
/// <summary>
- /// Interface IScheduledTask
+ /// Interface IScheduledTaskWorker
/// </summary>
- public interface IScheduledTask : IDisposable
+ public interface IScheduledTask
{
/// <summary>
- /// Gets the triggers.
- /// </summary>
- /// <value>The triggers.</value>
- IEnumerable<ITaskTrigger> Triggers { get; set; }
-
- /// <summary>
- /// Gets the last execution result.
- /// </summary>
- /// <value>The last execution result.</value>
- TaskResult LastExecutionResult { get; }
-
- /// <summary>
- /// Gets the state.
- /// </summary>
- /// <value>The state.</value>
- TaskState State { get; }
-
- /// <summary>
- /// Gets the current progress.
- /// </summary>
- /// <value>The current progress.</value>
- double? CurrentProgress { get; }
-
- /// <summary>
/// Gets the name of the task
/// </summary>
/// <value>The name.</value>
@@ -53,28 +29,12 @@ namespace MediaBrowser.Common.ScheduledTasks
string Category { get; }
/// <summary>
- /// Gets the unique id.
- /// </summary>
- /// <value>The unique id.</value>
- Guid Id { get; }
-
- /// <summary>
/// Executes the task
/// </summary>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <param name="progress">The progress.</param>
/// <returns>Task.</returns>
- /// <exception cref="System.InvalidOperationException">Cannot execute a Task that is already running</exception>
- Task Execute();
-
- /// <summary>
- /// Stops the task if it is currently executing
- /// </summary>
- /// <exception cref="System.InvalidOperationException">Cannot cancel a Task unless it is in the Running state.</exception>
- void Cancel();
-
- /// <summary>
- /// Cancels if running.
- /// </summary>
- void CancelIfRunning();
+ Task Execute(CancellationToken cancellationToken, IProgress<double> progress);
/// <summary>
/// Gets the default triggers.
@@ -82,4 +42,4 @@ namespace MediaBrowser.Common.ScheduledTasks
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
IEnumerable<ITaskTrigger> GetDefaultTriggers();
}
-} \ No newline at end of file
+}
diff --git a/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs b/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs
new file mode 100644
index 0000000000..31cb4bcb89
--- /dev/null
+++ b/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs
@@ -0,0 +1,86 @@
+using MediaBrowser.Model.Tasks;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Common.ScheduledTasks
+{
+ /// <summary>
+ /// Interface IScheduledTaskWorker
+ /// </summary>
+ public interface IScheduledTaskWorker : IDisposable
+ {
+ /// <summary>
+ /// Gets or sets the scheduled task.
+ /// </summary>
+ /// <value>The scheduled task.</value>
+ IScheduledTask ScheduledTask { get; }
+
+ /// <summary>
+ /// Gets the last execution result.
+ /// </summary>
+ /// <value>The last execution result.</value>
+ TaskResult LastExecutionResult { get; }
+
+ /// <summary>
+ /// Gets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ string Name { get; }
+
+ /// <summary>
+ /// Gets the description.
+ /// </summary>
+ /// <value>The description.</value>
+ string Description { get; }
+
+ /// <summary>
+ /// Gets the category.
+ /// </summary>
+ /// <value>The category.</value>
+ string Category { get; }
+
+ /// <summary>
+ /// Gets the state.
+ /// </summary>
+ /// <value>The state.</value>
+ TaskState State { get; }
+
+ /// <summary>
+ /// Gets the current progress.
+ /// </summary>
+ /// <value>The current progress.</value>
+ double? CurrentProgress { get; }
+
+ /// <summary>
+ /// Gets the triggers that define when the task will run
+ /// </summary>
+ /// <value>The triggers.</value>
+ /// <exception cref="System.ArgumentNullException">value</exception>
+ IEnumerable<ITaskTrigger> Triggers { get; set; }
+
+ /// <summary>
+ /// Gets the unique id.
+ /// </summary>
+ /// <value>The unique id.</value>
+ Guid Id { get; }
+
+ /// <summary>
+ /// Executes the task
+ /// </summary>
+ /// <returns>Task.</returns>
+ /// <exception cref="System.InvalidOperationException">Cannot execute a Task that is already running</exception>
+ Task Execute();
+
+ /// <summary>
+ /// Stops the task if it is currently executing
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">Cannot cancel a Task unless it is in the Running state.</exception>
+ void Cancel();
+
+ /// <summary>
+ /// Cancels if running.
+ /// </summary>
+ void CancelIfRunning();
+ }
+} \ No newline at end of file
diff --git a/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs b/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs
index 42d7020e60..d06f1f1946 100644
--- a/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs
+++ b/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Model.Tasks;
-using System;
+using System;
using System.Collections.Generic;
namespace MediaBrowser.Common.ScheduledTasks
@@ -10,7 +9,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// Gets the list of Scheduled Tasks
/// </summary>
/// <value>The scheduled tasks.</value>
- IScheduledTask[] ScheduledTasks { get; }
+ IScheduledTaskWorker[] ScheduledTasks { get; }
/// <summary>
/// Cancels if running and queue.
@@ -37,35 +36,5 @@ namespace MediaBrowser.Common.ScheduledTasks
/// </summary>
/// <param name="tasks">The tasks.</param>
void AddTasks(IEnumerable<IScheduledTask> tasks);
-
- /// <summary>
- /// Called when [task completed].
- /// </summary>
- /// <param name="task">The task.</param>
- /// <param name="startTime">The start time.</param>
- /// <param name="endTime">The end time.</param>
- /// <param name="status">The status.</param>
- void OnTaskCompleted(IScheduledTask task, DateTime startTime, DateTime endTime, TaskCompletionStatus status);
-
- /// <summary>
- /// Gets the last execution result.
- /// </summary>
- /// <param name="task">The task.</param>
- /// <returns>TaskResult.</returns>
- TaskResult GetLastExecutionResult(IScheduledTask task);
-
- /// <summary>
- /// Loads the triggers.
- /// </summary>
- /// <param name="task">The task.</param>
- /// <returns>IEnumerable{BaseTaskTrigger}.</returns>
- IEnumerable<ITaskTrigger> LoadTriggers(IScheduledTask task);
-
- /// <summary>
- /// Saves the triggers.
- /// </summary>
- /// <param name="task">The task.</param>
- /// <param name="triggers">The triggers.</param>
- void SaveTriggers(IScheduledTask task, IEnumerable<ITaskTrigger> triggers);
}
} \ No newline at end of file
diff --git a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs
index 2c3d21a4b0..ebfc94591e 100644
--- a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs
+++ b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs
@@ -14,7 +14,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// </summary>
/// <param name="task">The task.</param>
/// <returns>TaskInfo.</returns>
- public static TaskInfo GetTaskInfo(IScheduledTask task)
+ public static TaskInfo GetTaskInfo(IScheduledTaskWorker task)
{
return new TaskInfo
{