Browse Source

Adding PostProcessingEventHandler Fixes #74

Former-commit-id: f6dcf6a1303211b1123e5b6130d700d0c5699e33
af/merge-core
James South 12 years ago
parent
commit
d9722b2dcc
  1. 32
      src/ImageProcessor.Web/Helpers/AsyncDuplicateLock.cs
  2. 25
      src/ImageProcessor.Web/Helpers/PostProcessingEventArgs.cs
  3. 27
      src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs
  4. 3
      src/ImageProcessor.Web/ImageProcessor.Web.csproj
  5. 2
      src/ImageProcessor/Imaging/Formats/JpegFormat.cs
  6. 7
      src/TestWebsites/MVC/Global.asax.cs

32
src/ImageProcessor.Web/Helpers/AsyncDeDuperLock.cs → src/ImageProcessor.Web/Helpers/AsyncDuplicateLock.cs

@ -1,5 +1,5 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AsyncDeDuperLock.cs" company="James South">
// <copyright file="AsyncDuplicateLock.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
@ -18,24 +18,24 @@ namespace ImageProcessor.Web.Helpers
/// Throttles duplicate requests.
/// Based loosely on <see href="http://stackoverflow.com/a/21011273/427899"/>
/// </summary>
public sealed class AsyncDeDuperLock
public sealed class AsyncDuplicateLock
{
/// <summary>
/// The semaphore slims.
/// The collection of semaphore slims.
/// </summary>
private static readonly ConcurrentDictionary<string, SemaphoreSlim> SemaphoreSlims
= new ConcurrentDictionary<string, SemaphoreSlim>();
private static readonly ConcurrentDictionary<object, SemaphoreSlim> SemaphoreSlims
= new ConcurrentDictionary<object, SemaphoreSlim>();
/// <summary>
/// The lock.
/// Locks against the given key.
/// </summary>
/// <param name="key">
/// The hash.
/// The key that identifies the current object.
/// </param>
/// <returns>
/// The <see cref="IDisposable"/>.
/// The disposable <see cref="Task"/>.
/// </returns>
public IDisposable Lock(string key)
public IDisposable Lock(object key)
{
DisposableScope releaser = new DisposableScope(
key,
@ -55,15 +55,15 @@ namespace ImageProcessor.Web.Helpers
}
/// <summary>
/// The lock async.
/// Asynchronously locks against the given key.
/// </summary>
/// <param name="key">
/// The key.
/// The key that identifies the current object.
/// </param>
/// <returns>
/// The <see cref="Task"/>.
/// The disposable <see cref="Task"/>.
/// </returns>
public Task<IDisposable> LockAsync(string key)
public Task<IDisposable> LockAsync(object key)
{
DisposableScope releaser = new DisposableScope(
key,
@ -100,12 +100,12 @@ namespace ImageProcessor.Web.Helpers
/// <summary>
/// The key
/// </summary>
private readonly string key;
private readonly object key;
/// <summary>
/// The close scope action.
/// </summary>
private readonly Action<string> closeScopeAction;
private readonly Action<object> closeScopeAction;
/// <summary>
/// Initializes a new instance of the <see cref="DisposableScope"/> class.
@ -116,7 +116,7 @@ namespace ImageProcessor.Web.Helpers
/// <param name="closeScopeAction">
/// The close scope action.
/// </param>
public DisposableScope(string key, Action<string> closeScopeAction)
public DisposableScope(object key, Action<object> closeScopeAction)
{
this.key = key;
this.closeScopeAction = closeScopeAction;

25
src/ImageProcessor.Web/Helpers/PostProcessingEventArgs.cs

@ -0,0 +1,25 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PostProcessingEventArgs.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// The post processing event arguments.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Web.Helpers
{
using System;
/// <summary>
/// The post processing event arguments.
/// </summary>
public class PostProcessingEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the cached image path.
/// </summary>
public string CachedImagePath { get; set; }
}
}

27
src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs

@ -62,7 +62,7 @@ namespace ImageProcessor.Web.HttpModules
/// <summary>
/// The locker for preventing duplicate requests.
/// </summary>
private static readonly AsyncDeDuperLock Locker = new AsyncDeDuperLock();
private static readonly AsyncDuplicateLock Locker = new AsyncDuplicateLock();
/// <summary>
/// The value to prefix any remote image requests with to ensure they get captured.
@ -108,6 +108,11 @@ namespace ImageProcessor.Web.HttpModules
}
#endregion
/// <summary>
/// The event that is called when a new image is processed.
/// </summary>
public static event EventHandler<PostProcessingEventArgs> OnPostProcessing;
#region IHttpModule Members
/// <summary>
/// Initializes a module and prepares it to handle requests.
@ -129,12 +134,8 @@ namespace ImageProcessor.Web.HttpModules
preserveExifMetaData = ImageProcessorConfiguration.Instance.PreserveExifMetaData;
}
#if NET45 && !__MonoCS__
EventHandlerTaskAsyncHelper wrapper = new EventHandlerTaskAsyncHelper(this.PostAuthorizeRequest);
context.AddOnPostAuthorizeRequestAsync(wrapper.BeginEventHandler, wrapper.EndEventHandler);
#else
context.PostAuthorizeRequest += this.PostAuthorizeRequest;
#endif
context.PreSendRequestHeaders += this.ContextPreSendRequestHeaders;
}
@ -385,6 +386,13 @@ namespace ImageProcessor.Web.HttpModules
// Trim the cache.
await cache.TrimCachedFolderAsync(cachedPath);
// Fire the post processing event.
EventHandler<PostProcessingEventArgs> handler = OnPostProcessing;
if (handler != null)
{
handler.Invoke(this, new PostProcessingEventArgs() { CachedImagePath = cachedPath });
}
// Store the response type and cache dependency in the context for later retrieval.
context.Items[CachedResponseTypeKey] = imageFactory.CurrentImageFormat.MimeType;
context.Items[CachedResponseFileDependency] = new List<string> { cachedPath };
@ -418,6 +426,13 @@ namespace ImageProcessor.Web.HttpModules
// Trim the cache.
await cache.TrimCachedFolderAsync(cachedPath);
// Fire the post processing event.
EventHandler<PostProcessingEventArgs> handler = OnPostProcessing;
if (handler != null)
{
handler.Invoke(this, new PostProcessingEventArgs() { CachedImagePath = cachedPath });
}
// Store the response type and cache dependencies in the context for later retrieval.
context.Items[CachedResponseTypeKey] = imageFactory.CurrentImageFormat.MimeType;
context.Items[CachedResponseFileDependency] = new List<string> { requestPath, cachedPath };
@ -467,7 +482,7 @@ namespace ImageProcessor.Web.HttpModules
}
else if (isRemote)
{
// Just repoint to the external url.
// Just re-point to the external url.
HttpContext.Current.Response.Redirect(requestPath);
}
}

3
src/ImageProcessor.Web/ImageProcessor.Web.csproj

@ -56,8 +56,9 @@
<Compile Include="Extensions\DirectoryInfoExtensions.cs" />
<Compile Include="Extensions\StringExtensions.cs" />
<Compile Include="Helpers\CommonParameterParserUtility.cs" />
<Compile Include="Helpers\AsyncDeDuperLock.cs" />
<Compile Include="Helpers\AsyncHighlanderLock.cs" />
<Compile Include="Helpers\NativeMethods.cs" />
<Compile Include="Helpers\PostProcessingEventArgs.cs" />
<Compile Include="Helpers\ResourceHelpers.cs" />
<Compile Include="Helpers\ImageHelpers.cs" />
<Compile Include="Helpers\RemoteFile.cs" />

2
src/ImageProcessor/Imaging/Formats/JpegFormat.cs

@ -75,7 +75,7 @@ namespace ImageProcessor.Imaging.Formats
{
base.ApplyProcessor(processor, factory);
// Set the property item information from any Exif metadata.
// Set the property item information from any Exif metadata.
// We do this here so that they can be changed between processor methods.
if (factory.PreserveExifData)
{

7
src/TestWebsites/MVC/Global.asax.cs

@ -8,6 +8,10 @@ using System.Web.Routing;
namespace Test_Website_NET45
{
using System.Diagnostics;
using ImageProcessor.Web.HttpModules;
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
@ -19,6 +23,9 @@ namespace Test_Website_NET45
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
// Test the post processing event.
ImageProcessingModule.OnPostProcessing += (sender, args) => Debug.WriteLine(args.CachedImagePath);
}
}
}
Loading…
Cancel
Save