package com.skp.experiment.common.mapreduce;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.util.Random;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.WritableComparable;
@SuppressWarnings("rawtypes")
public class ReferenceWithLockMapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT, K extends WritableComparable, V extends Writable>
extends ReferenceMapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT, K, V> {
public static final String LOCK_PATH = ReferenceWithLockMapper.class.getName() + ".lockPath";
public static final String LOCK_NUMS = ReferenceWithLockMapper.class.getName() + ".lockNums";
private String lockPath = null;
private long sleepPeriod = 30000;
private int lockNums;
private Path currentLockPath = null;
@Override
protected void setup(Context ctx)
throws IOException, InterruptedException {
super.setup(ctx);
Configuration conf = ctx.getConfiguration();
lockPath = conf.get(LOCK_PATH);
lockNums = conf.getInt(LOCK_NUMS, 1);
if (lockPath != null) {
checkLock(ctx, lockNums);
}
}
private void checkLock(Context ctx, int lockNums) throws InterruptedException, IOException {
InetAddress thisIp =InetAddress.getLocalHost();
String hostIp = thisIp.getHostAddress();
// busy wait
Configuration conf = ctx.getConfiguration();
long totalSleep = 0;
boolean haveLock = false;
FileSystem fs = FileSystem.get(conf);
while (haveLock == false) {
for (int i = 0; i < lockNums; i++) {
Path checkPath = new Path(lockPath, hostIp + "_" + i);
if (fs.exists(checkPath) == false) {
haveLock = true;
currentLockPath = checkPath;
BufferedWriter br = new BufferedWriter(
new OutputStreamWriter(fs.create(currentLockPath)));
br.write(ctx.getTaskAttemptID().toString());
break;
}
}
if (haveLock == false) {
Random random = new Random();
int diff = 1000 + random.nextInt(1000) % 1000;
totalSleep += diff + sleepPeriod;
ctx.setStatus("sleeping: " + String.valueOf(totalSleep));
Thread.sleep(sleepPeriod + diff);
}
}
}
@Override
protected void cleanup(Context ctx) throws IOException,
InterruptedException {
super.cleanup(ctx);
if (currentLockPath != null) {
FileSystem fs = FileSystem.get(ctx.getConfiguration());
fs.deleteOnExit(currentLockPath);
}
}
}