Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
FileLockSimulator: a small application for simulate the behavior of FileAppender in prudent mode
/**
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2011, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
/**
* FileLockSimulator is a small application intended to simulate FileAppender in prudent mode.
* In this mode, the application obtains an exclusive lock on the file, writes to the file and
* then releases the lock.
*
* <pre> Usage:
* javac FileLockSimulator.java
* java FileLockSimulator instanceName pathToLogFile delay
* where
* "instanceName" is the name given to the current instance of the application
* "pathToLogFile" is the path to the log file
* "delay" is the number of milliseconds of sleep observed every 128 writes
* </pre>
*
* <b>This small application requires only the JDK to compile and to execute.</b>
*
* <p>FileLockSimulator should be launched as many times and from as many hosts as there will be
* JVMs writing to a log file in prudent mode. Performance should be quite good if
* "pathToLogFile" is on a local file system. On networked file systems such as NFS, performance
* depends on the speed of the network and NFS implementation. It has been observed that file
* locking over NFS is biased so that the current owner of the lock is favored over other
* processes. Thus, while one process hogs the lock for the log file, other processes starve
* waiting for the lock to the point of appearing deadlocked.
*
*/
public class FileLockSimulator {
static String LINE_SEPARATOR = System.getProperty("line.separator");
static final int DOT_FREQ = 128;
static final int DOT_WITH_NEW_LINE_FREQ = DOT_FREQ * 80;
static String instanceName;
static int delay;
static FileOutputStream fos;
static FileChannel fileChannel;
public static void main(String[] args) throws IOException, InterruptedException {
String instanceName = args[0];
System.out.println("Instance named as [" + instanceName + "]");
String fileStr = args[1];
System.out.println("Output target specified as [" + fileStr + "]");
int delay = Integer.parseInt(args[2]);
System.out.println("Sleep delay specified as [" + delay + "] milliseconds");
fos = new FileOutputStream(fileStr, true);
fileChannel = fos.getChannel();
for (int i = 1; ; i++) {
printDotAndSleep(i);
lockAndWrite(i);
}
}
static void lockAndWrite(int i) throws InterruptedException, IOException {
FileLock fileLock = null;
try {
fileLock = fileChannel.lock();
long position = fileChannel.position();
long size = fileChannel.size();
if (size != position) {
fileChannel.position(size);
}
String msg = "hello from" + instanceName + " " + i + LINE_SEPARATOR;
fos.write(msg.getBytes());
} finally {
if (fileLock != null) {
fileLock.release();
}
}
}
static void printDotAndSleep(int i) throws InterruptedException {
if (i % DOT_FREQ == 0) {
System.out.print(".");
Thread.sleep(delay);
}
if (i % DOT_WITH_NEW_LINE_FREQ == 0) System.out.println("");
}
}

gbonk commented Jan 10, 2014

There's a bug in line 59 you should be using the instance var

There is a bug in line 65, you should not declare a new local variable with name delay, then the value of global variable with name deploy will always be zero

You can use my fork to fix the above two bugs.

https://gist.github.com/stefanrufer/bc66547bf6d35ccf2992

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment