pondělí 8. června 2015

C# Safe Event Pattern

C# language has a very good support for event programming. However, is does not address a two common issues with event handlers:
  1. An event handler is registered more times, but we want to call it just once.
  2. An event handler is registered from longer living object then the event source. Then the event handler must be unregistered. Otherwise it may cause memory leaks.
First issue is usually simple to solve. The memory leaks are best avoided when using weak references. There are several solutions to .NET weak event references. e.g. see The .NET weak event pattern in C#. I have decided to go with .NET 4.5 WeakEventManager. The following pattern makes it easy for MyEvent consumer to write the code without worrying about event handler unregistering.
private event MyEventArgs _myEvent;

public event EventHandler<MyEventArgs> MyEvent
{
    add
    {
        // first unregister if registered
        MyEvent-= value;
        // register
        WeakEventManager<ThisType, MyEventArgs>.AddHandler(_myEvent, "MyEvent", value);
    }
    remove
    {
        WeakEventManager<ThisType, MyEventArgs>.RemoveHandler(_myEvent, "MyEvent", value);
    }
}

úterý 19. května 2015

Log4net Configuration for Desktop Application

I have configured log4net for out current project, a plain Windows Desktop application. I wanted log to rolling file into the AppData\Local folder. Not the Roaming folder, since log are specific to the machine and it is waste of resources to let them roam around. Also I wanted to see logs in console, but in DEBUG mode only, not in production. First problem to find the AppData\Local\MyAppName has been solved by log4net.Util.PatternString class. It parses a special %envFolderPath and %appdomain patterns. The second problem, to configure ConsoleAppender just in DEBUG mode has several solutions. It is possible to load different configs, or to configure ConsoleAppender programatically. I have decided to create own DebugFilter, which denies all log in production mode. This way I have just one log4net config file. The cons is that it is very slightly less efficient to have configured an Appender which denies all log, but it's OK for most of applications.
<log4net>
  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <file type="log4net.Util.PatternString" value="%envFolderPath{LocalApplicationData}\%appdomain\log.txt" />
    <appendToFile value="true" />
    <maxSizeRollBackups value="2" />
    <maximumFileSize value="10MB" />
    <rollingStyle value="Size" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>
  <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
    <filter type="cvtBackend.Logging.DebugFilter" />
  </appender>
  <!-- Setup the root category, add the appenders and set the default level -->
  <root>
    <level value="INFO" />
    <appender-ref ref="RollingLogFileAppender" />
    <appender-ref ref="ConsoleAppender" />
  </root>
</log4net>
And the DebugFilter:
    /// 
    /// log4net filter which allows logging in DEBUG mode only.
    /// 
    public class DebugFilter : FilterSkeleton
    {
        public override FilterDecision Decide(LoggingEvent loggingEvent)
        {
#if DEBUG
            return FilterDecision.Neutral;
#else
            return FilterDecision.Deny;
#endif
        }
    }

pátek 13. února 2015

Java: Fast Date Formatting in Web Containers

Java SimpleDateFormat is not thread safe. When it is used in multithreaded applications, like Java web containers, it's forbidden use it as a static constant
public static final DateFormat DATE_FORMAT = new SimpleDateFormat('YYYY.MM.dd'); // DON'T!
Most developers properly constructs new SimpleDateFormat everytime they need
DateFormat dateFormat = new SimpleDateFormat('YYYY.MM.dd');
String str = dateFormat.format(date);
However, constructing new SimpleDateFormat is not so cheap operation. So, how to safe CPU and memory like in static final pattern in a multithreaded environment?

Solution 1: clone


Fortunatelly, SimpleDateFormat implements clone() method, which is fasters than constructing a new one form a String:
private static final DateFormat DATE_FORMAT_TEMPLATE = new SimpleDateFormat('YYYY.MM.dd'); // Do not use directly

/**
 * @return every time a new SimpleDateFormat.
 */
public static DateFormat getDateFormat() {
 return DATE_FORMAT_TEMPLATE.clone();
}

Solution 2: ThreadLocal


A general solution for sharing non-thread safe objects is to have one copy for each thread. Java has a very nice ThreadLocal. Together with lazy initialization we got the proper thread safe and fast solution:
private static final ThreadLocal DATE_FORMAT_TL = new ThreadLocal() {
 protected DateFormat initialValue() {
  return new SimpleDateFormat('YYYY.MM.dd');
 };
};

/**
 * @return SimpleDateFormat, new one for every thread.
 */
public static DateFormat getDateFormat() {
 return DATE_FORMAT_TL .get();
}

/**
 * Simple, optimized Date formatting.
 */
public static String format(Date d) {
 return format == null ? null : getDateFormat().format(d);
}
This solution has advantage over clone() method, that calling getDateFormat() multiple times in one thread (e.g. inside a loop) does not create a new object. I like to add format() to simplify usage and handle null values. Note: ThreadLocal may cause redeploy memory leaks when it's value from a WAR class. E.g. see Java Web Container: Hunting Redeploy Memory Leaks