Last active
August 29, 2015 14:03
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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