Integrating Xgrid into Cocoa Applications, Part 2
Pages: 1, 2, 3, 4, 5
We can now finish off the applyFilters:toFilesWithPaths:forOutputDirectoryPath:
method.
// Copy PIL for the input directory
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *pilPath = [bundle pathForResource:@"PIL" ofType:nil];
NSAssert( nil != pilPath, @"PIL path was nil." );
[fm copyPath:pilPath toDirectoryAtPath:inputDirPath];
// Add subtask to task
NSString *scriptPath =
[bundle pathForResource:@"agentrunscript" ofType:@"py"];
[task addSubTaskWithIdentifier:[NSNumber numberWithInt:subTaskIndex]
launchPath:scriptPath
workingDirectoryPath:inputDirPath
outputDirectoryPath:taskOutputDirPath
standardInputPath:siPath
standardOutputPath:nil];
}
[task launch];
}
Still inside the loop over subtasks, we copy the directory containing PIL
to the input directory of the subtask. The subtask is then added to the distributed
task, using the method discussed earlier, setting the launch path, input and
output directories of the subtask, and the standard input file. We don't need
the standard output, so nil is passed for that. Finally, when all
subtasks have been added to the distributed task, the task is launched.
The progress of the DistributedTask is monitored using its delegate
methods. The PIController was set as the delegate to the task,
so it can implement the methods, and act upon them as required. We will take
a look at the method called when the DistributedTask has finished
running all its subtasks on Xgrid: distributedTaskDidFinishSubTasks:.
The method first checks that the output directory that the user requested
exists. If not, it creates it. If it does exist, and is not a directory, an
NSAssert ensures an exception is raised. In a more robust app,
you would want to handle this better, by informing the user of the problem.
-(void)distributedTaskDidFinishSubTasks:(DistributedTask *)distributedTask {
NSFileManager *fm = [NSFileManager defaultManager];
// Ensure output directory exists, and that it is a directory.
BOOL isDir;
if ( [fm fileExistsAtPath:[self outputDirectoryPath] isDirectory:&isDir] ) {
NSAssert( isDir, @"Output directory path supplied was not a directory." );
}
else {
[fm createDirectoryAtPath:[self outputDirectoryPath] attributes:nil];
}
Next, the filtered photos, which should be in the output directory of the
DistributedTask, are moved to the user's chosen output destination.
// Move task output files to the output directory
NSString *taskOutputDirPath =
[taskTempDirPath stringByAppendingPathComponent:@"output"];
[fm changeCurrentDirectoryPath:taskOutputDirPath];
NSDirectoryEnumerator *en = [fm enumeratorAtPath:taskOutputDirPath];
NSString *relativePath; // Path relative to taskOutputDirPath
while ( relativePath = [en nextObject] ) {
if ( NSOrderedSame !=
[[relativePath pathExtension] caseInsensitiveCompare:@"jpg"] &&
NSOrderedSame !=
[[relativePath pathExtension] caseInsensitiveCompare:@"jpeg"] )
continue;
NSString *fileOutputPath =
[[self outputDirectoryPath] stringByAppendingPathComponent:
[relativePath lastPathComponent]];
if ( [fm fileExistsAtPath:fileOutputPath] )
[fm removeFileAtPath:fileOutputPath handler:nil];
[fm linkPath:relativePath toPath:fileOutputPath handler:nil];
}
An NSDirectoryEnumerator is employed for this operation. An NSDirectoryEnumerator
traverses the contents of a directory, including subdirectories. For each file
found, we check if it is a JPEG, and, if so, link it to the output directory.
Yes, in this case we do use link, instead of copy, because the operation doesn't
pose any threat to the original photos, and is faster.
Finally, we clean up, by removing the entire task temporary directory, which includes all of the files and directories used by the subtasks.
// Remove temporary directory
[fm removeFileAtPath:taskTempDirPath handler:nil];
...
}
Odds and Ends
We have now covered the parts of Photo Industry that relate directly to Xgrid. If you download the source, you will see there is a lot of other stuff in the application, which could also be useful in your own apps. Photo Industry makes use of drag and drop, for example, and the new Cocoa bindings layer. A good intro to the drag-and-drop techniques can be found on CocoaDevCentral. Bindings are also covered by CocoaDevCentral here, and don't forget that old stalwart Mike Beam, who has recently written on the topic here.
I hope this two-part article has demonstrated the potential of Xgrid in
non-scientific Cocoa applications. We have had to do a lot of work in order
to leverage that potential, using the command-line xgrid tool,
but in all likelihood WWDC will alleviate that in the near future. Hopefully,
this article will be irrelevant after June 28, 2004, when SJ finally unveils
Apple's vision for Xgrid and the future of distributed computation. To be continued
...
Drew McCormack works at the Free University in Amsterdam, and develops the Cocoa shareware Trade Strategist.
Return to the Mac DevCenter
- Trackback from http://www.nomorestars.com/B60819807/C1409791567/E180688253/index.html
Xgrid and Cocoa Applications
2004-06-07 09:10:48 [View]
-
xgrid command hanging?
2004-05-26 13:37:36 jamesreynolds [View]
-
xgrid command hanging?
2004-05-26 22:36:28 drewmccormack [View]
-
Node List
2004-05-21 08:22:02 cyberassassin [View]
-
Node List
2004-05-25 11:32:55 drewmccormack [View]
-
Bobby Andersen's web site
2004-05-19 22:34:04 drewmccormack [View]

