I have some ideas for developing a new AsyncAppenderSkeleton, based on recent 
experience developing a custom async appender that sends logging events to a 
Web API.

My current thoughts are:


1.       A new base class AsyncAppenderSkeleton that can be configured to work 
in synchronous mode (identical to AppenderSkeleton) or asynchronous mode, where 
DoAppend queues events on to a FIFO queue, and has a single background thread 
that dequeues events and calls the existing Append methods.


2.       When in asynchronous mode, there will be customizable and configurable 
retry logic that can call Append if it throws an exception.  The retry login 
will be able to inspect the exception that was thrown and keep a count of the 
number of retries so far.  For example, a derived appender that logs to a Web 
API might want to retry 5xx HTTP status codes, but treat 4xx status codes as 
permanent errors.   There will no retry logic in synchronous mode as this would 
impact performance.



3.       The default queue implementation would be a lossy in-memory Queue with 
a configurable maximum length.  It might be nice to provide the possibility to 
plug in alternate queue implementations, such as a persistent queue using MSMQ.



4.       A class AsyncForwardingAppender would derive from 
AsyncAppenderSkeleton and implement IAppenderAttachable.



5.       It would be easy to create asynchronous versions of existing custom 
appenders, by changing the base class from AppenderSkeleton to 
AsyncAppenderSkeleton and optionally implementing some retry logic.  E.g. we 
could have a new AdoNetAppender that can be configured to operate in 
synchronous mode when logging to a local database, or in asynchronous mode when 
logging to a cloud-based database.


In terms of timescales, I think it would be possible to produce something by 
the end of 2016.

To do it I need to reimplement AppenderSkeleton's DoAppend methods, to enqueue 
events if in asynchronous mode, or call Append in synchronous mode.

I don't want to duplicate code by reimplementing the rest of AppenderSkeleton, 
so I would like to do one of the following:

Option 1:

-          Refactor all of AppenderSkeleton's implementation except IAppender 
and IBulkAppender into a new base class AppenderSkeletonBase.  This includes 
filtering, IOptionHandler, layout.

-          Derive AppenderSkeleton and later the new AsyncAppenderSkeleton from 
AppenderSkeletonBase.

Option 2:

-          Make AppenderSkeleton's DoAppend methods virtual, and derive 
AsyncAppenderSkeleton from AppenderSkeleton.

Option 1 seems the cleanest to me; any thoughts?

Reply via email to