Search code examples
javachronicle

Thread safety of VanillaChronicle


I am using VanillaChronicle to write some messages to the disk.

public final class ConcurrentPersister{

    private final String location;
    private final Chronicle chronicle;
    private final ExcerptAppender writer;

    private final static int STRING_SIZE_OVERHEAD   = 1000;
    private final static String FILE_DATE_FORMAT    = "MM-dd-yyyy";
    private final static String NAME                = "ConcurrentPersister";
    private final static Logger LOGGER              = LoggerFactory.getLogger( NAME );



    public ConcurrentPersister( String location, VanillaChronicleConfig config ){
        this.chronicle      = new VanillaChronicle( location );
        this.writer         = chronicle.createAppender();
    }


   public final void appendMessage( final String message ){

        try{

            long length  =  STRING_SIZE_OVERHEAD + message.length();

            writer.startExcerpt( length );
            writer.append( message );
            writer.finish();

        }catch( Exception e ){
            LOGGER.warn("Failed to persist Message [{}]", message );
            LOGGER.warn("Exception: ", e );
        }

    }

}

Is the appendMessage(String message) method, as shown above, thread-safe if called from multiple threads?

I read somewhere that VanillaChronicle's append(String message) is thread-safe. However, am I correct in thinking that the compound action of startExcerpt() + append() + finish() is NOT thread-safe?

Thanks.


Solution

  • VanillaChronicle has a ThreadLocal cache of appenders/tailers:

    public VanillaAppender createAppender() throws IOException {
        WeakReference<VanillaAppender> ref = appenderCache.get();
        VanillaAppender appender = null;
        if (ref != null)
            appender = ref.get();
        if (appender == null) {
            appender = createAppender0();
            appenderCache.set(new WeakReference<VanillaAppender>(appender));
        }
        return appender;
    }
    

    If you do not have thousand short living threads you can use createAppender in your appendMessage method

    public final void appendMessage( final String message ) {
        try {
            ExcerptAppender writer = chronicle.createAppender();
            writer.startExcerpt( STRING_SIZE_OVERHEAD + message.length() );
            writer.append( message );
            writer.finish();
        } catch( Exception e ) {
            LOGGER.warn("Failed to persist Message [{}]", message );
            LOGGER.warn("Exception: ", e );
        }
    }
    

    I read somewhere that VanillaChronicle's append(String message) is thread-safe. However, am I correct in thinking that the compound action of startExcerpt() + append() + finish() is NOT thread-safe?

    VanillaChronicle can be used by concurrent thread, even concurrent processes, provided each thread uses it's own appender.