Skip to content

Instantly share code, notes, and snippets.

@gkhays
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gkhays/d9baf8dd639c2fb51a52 to your computer and use it in GitHub Desktop.
Save gkhays/d9baf8dd639c2fb51a52 to your computer and use it in GitHub Desktop.
A simple inter-process communication (IPC) utility that watches for the creation of tiles in a specific subdirectory and then queues them for processing. Currently hard-coded to watch a subdirectory called "Locker" located in the test directory relative to the execution path.
package org.gkh.test;
import java.nio.file.Path;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* This is a demonstration Producer/Consumer that queues and dequeues new file
* items as they are created in the directory we are watching.
*
* @see TestWatchService
*
* @author gkhays
*
*/
public class TestQueuingThread extends Thread {
// Let's use a queue of fixed capacity for now.
private BlockingQueue<Path> requests = new ArrayBlockingQueue<Path>(100);
private volatile boolean queuingTerminated;
private volatile boolean shuttingDown;
public void put(Path path) {
if (shuttingDown || queuingTerminated) return;
try {
requests.put(path);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
throw new RuntimeException("Unexpected interruption");
}
}
public Path peek() {
return requests.peek();
}
public void run() {
try {
Path item;
while ((item = requests.take()) != null) {
// TODO - This is where we pull work items out of the queue.
System.out.println("Working on request item: " + item);
}
} catch (InterruptedException ex) {
// At least log this.
} finally {
queuingTerminated = true;
}
}
public void shutDown() throws InterruptedException {
// TODO - Shut 'er down!
shuttingDown = true;
requests.put(null);
}
}
package org.gkh.test;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import static java.nio.file.StandardWatchEventKinds.*;
public class TestWatchService {
// http://andreinc.net/2013/12/06/java-7-nio-2-tutorial-writing-a-simple-filefolder-monitor-using-the-watch-service-api/
// http://codingjunkie.net/java-7-watchservice/
// http://baptiste-wicht.com/posts/2010/03/nio-2-path-api-java-7.html
// These are diffent ways to establish a path.
// File filePath = new File(WATCH_PATH);
//Path dir = filePath.toPath();
//Alternatively...
//Path dir = Paths.get(WATCH_PATH);
//Alternatively...
//Path dir = FileSystems.getDefault().getPath(WATCH_PATH);
// You can register for different event types.
// WatchKey key = dir.register(watcher,
// ENTRY_CREATE,
// ENTRY_DELETE,
// ENTRY_MODIFY);
// In our case, we are looking for ENTRY_CREATE, which signifies that a
// file has been created in the directory we are watching.
public static String WATCH_PATH = "test/Locker";
public static void pollEvents(Path dir, WatchKey key,
TestQueuingThread queue) {
Kind<?> kind = null;
for (WatchEvent<?> event : key.pollEvents()) {
kind = event.kind();
if (kind == OVERFLOW) {
continue;
}
Path filename = (Path) event.context();
System.out.println("An event occurred with file name: " + filename);
try {
Path child = dir.resolve(filename);
System.out.println("The new path is " + child);
System.out.println(" File type is "
+ Files.probeContentType(child));
if (!Files.probeContentType(child).equals("text/plain")) {
System.err.format("New file '%s'"
+ " is not a plain text file.%n", filename);
continue;
}
queue.put(child);
System.out.println(" Head of queue: " + queue.peek());
} catch (Exception ex) {
System.out.println("Error attempting to probe file");
System.err.println(ex);
continue;
}
}
}
public static void testForNewFiles() {
Path dir = Paths.get(WATCH_PATH);
WatchService watcher = null;
TestQueuingThread queue = new TestQueuingThread();
queue.start();
try {
watcher = FileSystems.getDefault().newWatchService();
dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
} catch (IOException e) {
// This is fatal, so no point in going on.
e.printStackTrace();
return;
}
WatchKey key2 = null;
// TODO - We need an exit condition.
while (true) {
try {
key2 = watcher.take();
} catch (InterruptedException ex) {
System.out.println("We were interrupted waiting for a watch key");
return;
}
pollEvents(dir, key2, queue);
boolean valid = key2.reset();
if (!valid) {
break;
}
}
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
testForNewFiles();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment