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
gbonk commented Jan 10, 2014

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

@yangshuo

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

@stefanrufer

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