gnustep-Zillion-0.1/000075500000000000000000000000001231046310600144475ustar00rootroot00000000000000gnustep-Zillion-0.1/.cvsignore000064400000000000000000000000511231046310600164430ustar00rootroot00000000000000obj shared_debug_obj shared_obj *.bundle gnustep-Zillion-0.1/CVS/000075500000000000000000000000001231046310600151025ustar00rootroot00000000000000gnustep-Zillion-0.1/CVS/Entries000064400000000000000000000020311231046310600164320ustar00rootroot00000000000000/.cvsignore/1.1.1.1/Wed Jan 22 13:05:02 2003// /GNUmakefile/1.1.1.1/Wed Jan 22 13:05:02 2003// /NSFileManager+directories.h/1.1.1.1/Wed Jan 22 13:05:02 2003// /NSFileManager+directories.m/1.1.1.1/Wed Jan 22 13:05:02 2003// /NSProcessInfo+getopt.h/1.1.1.1/Wed Jan 22 13:05:03 2003// /NSProcessInfo+getopt.m/1.1.1.1/Wed Jan 22 13:05:03 2003// /ZillionClient.h/1.2/Mon Apr 7 11:45:10 2003// /ZillionClient.m/1.2/Mon Apr 7 11:45:10 2003// /ZillionClientServer.h/1.2/Mon Apr 7 11:45:10 2003// /ZillionClientServer.m/1.2/Mon Apr 7 11:45:11 2003// /ZillionServer.h/1.2/Mon Apr 7 11:45:11 2003// /ZillionServer.m/1.3/Mon Apr 7 11:45:12 2003// /killClients.sh/1.1/Mon Apr 7 11:45:12 2003// /printClients.sh/1.1/Mon Apr 7 11:46:05 2003// /simpleZillionJob.h/1.1.1.1/Wed Jan 22 13:05:03 2003// /simpleZillionJob.m/1.3/Mon Apr 7 11:45:15 2003// /simpleZillionJobInfo.plist/1.1.1.1/Wed Jan 22 13:05:03 2003// /zillion.m/1.2/Mon Apr 7 11:45:16 2003// /zillionClient.m/1.1.1.1/Wed Jan 22 13:05:03 2003// /zillionLoader.m/1.2/Mon Apr 7 11:45:17 2003// D gnustep-Zillion-0.1/CVS/Entries.Log000064400000000000000000000000151231046310600171520ustar00rootroot00000000000000A D/docu//// gnustep-Zillion-0.1/CVS/Repository000064400000000000000000000000101231046310600171730ustar00rootroot00000000000000zillion gnustep-Zillion-0.1/CVS/Root000064400000000000000000000000701231046310600157450ustar00rootroot00000000000000:pserver:anonymous@cvs.sourceforge.net:/cvsroot/zillion gnustep-Zillion-0.1/GNUmakefile000064400000000000000000000015001231046310600165150ustar00rootroot00000000000000CC=clang include $(GNUSTEP_MAKEFILES)/common.make ADDITIONAL_OBJCFLAGS = -Wno-protocol BUNDLE_NAME = simpleZillionJob TOOL_NAME = zillion zillionClient zillionLoader zillion_OBJC_FILES = zillion.m ZillionServer.m \ ZillionClientServer.m \ NSFileManager+directories.m \ NSProcessInfo+getopt.m #zillion_C_FILES = linearRegression.c #zillion_TOOL_LIBS += -lnag -lf95 zillionClient_OBJC_FILES = zillionClient.m ZillionClient.m \ ZillionClientServer.m \ NSFileManager+directories.m \ NSProcessInfo+getopt.m zillionLoader_OBJC_FILES = zillionLoader.m NSFileManager+directories.m simpleZillionJob_OBJC_FILES = simpleZillionJob.m simpleZillionJob_PRINCIPAL_CLASS = SimpleZillionJob #simpleZillionJob_BUNDLE_INFO_PLIST_FILE = simpleZillionJob.plist include $(GNUSTEP_MAKEFILES)/tool.make include $(GNUSTEP_MAKEFILES)/bundle.make gnustep-Zillion-0.1/NSFileManager+directories.h000064400000000000000000000006551231046310600215510ustar00rootroot00000000000000/* NSFileManager+directories.h Mon Dec 9 11:30:36 CET 2002 stefan.boehringer@uni-essen.de */ #import @interface NSFileManager(NSFileManagerDirectories) - (NSData *)dataRepresentationAtPath:(NSString *)somePath; - (void)writeDataRepresentation:(NSData *)data toPath:(NSString *)somePath; - (BOOL)createAllDirectoriesComposingPath:(NSString *)path attributes:(NSDictionary *)attributes; @end gnustep-Zillion-0.1/NSFileManager+directories.m000064400000000000000000000055441231046310600215600ustar00rootroot00000000000000/* NSFileManager+directories.m Mon Dec 9 11:34:58 CET 2002 stefan.boehringer@uni-essen.de */ #import "NSFileManager+directories.h" @implementation NSFileManager(NSFileManagerDirectories) - (NSData *)dataRepresentationAtPath:(NSString *)somePath { NSArray *files = [self directoryContentsAtPath:somePath]; NSMutableDictionary *contentRep = [NSMutableDictionary dictionary]; NSDictionary *attributes; NSString *filePath, *file; NSData *contents; int i, max; for (i = 0, max = [files count]; i < max; i++) { file = [files objectAtIndex:i]; filePath = [somePath stringByAppendingPathComponent:file]; attributes = [self fileAttributesAtPath:filePath traverseLink:YES]; // NSLog(@"%@", attributes); if (NSFileTypeDirectory == [attributes fileType]) { // encountered a directory contents = [self dataRepresentationAtPath:filePath]; } else { contents = [self contentsAtPath:filePath]; } [contentRep setObject:[NSDictionary dictionaryWithObjectsAndKeys: attributes, @"attributes", contents, @"contents", nil ] forKey:file ]; } return [NSArchiver archivedDataWithRootObject:contentRep]; } //#define ATTRIB_IS_DIR(a) ([a fileType] == NSFileTypeDirectory) #define ATTRIB_IS_DIR(a) ([[a fileType] isEqualToString:NSFileTypeDirectory]) - (void)writeDataRepresentation:(NSData *)data toPath:(NSString *)somePath { NSDictionary *directory = [NSUnarchiver unarchiveObjectWithData:data]; NSEnumerator *files = [directory keyEnumerator]; NSString *filePath, *file; NSDictionary *attributes; NSData *fileContents; for (; (file = [files nextObject]); ) { attributes = [[directory objectForKey:file] objectForKey:@"attributes"]; filePath = [somePath stringByAppendingPathComponent:file]; fileContents = [[directory objectForKey:file] objectForKey:@"contents"]; if (ATTRIB_IS_DIR(attributes)) { // encountered a directory [self createDirectoryAtPath:filePath attributes:attributes]; [self writeDataRepresentation:fileContents toPath:filePath]; } else { [self createFileAtPath:filePath contents:fileContents attributes:attributes]; } } } - (BOOL)createAllDirectoriesComposingPath:(NSString *)path attributes:(NSDictionary *)attributes { NSArray *components = [path pathComponents]; int i, count; BOOL isDir; for (i = 0, count = [components count]; i < count; i++) { NSString *partialPath = [NSString pathWithComponents: [components subarrayWithRange:NSMakeRange(0, i + 1)]]; if (![self fileExistsAtPath:partialPath isDirectory:&isDir]) { if (![self createDirectoryAtPath:partialPath attributes:attributes]) return NO; } else { if (!isDir) [NSException raise:NSInvalidArgumentException format:@"path of directories is blocked by file [%@]", partialPath]; } } return YES; } @end #if 0 @implementation NSObject(DeallocBlock) - (void)dealloc { /* fputs("didn't dealloc\n", stderr); */} @end #endif gnustep-Zillion-0.1/NSProcessInfo+getopt.h000064400000000000000000000017331231046310600206150ustar00rootroot00000000000000/* NSProcessInfo+getopt.h Tue Dec 10 11:27:37 CET 2002 */ #import @interface NSProcessInfo(Getopt) /* option specifictations are as follows: option[=T] when the '=T' part is optional. With a name alone the option is a switch. T is a type being either i or s, representing integers or strings. To specify an argument the option is written as either: --option optionArgument --option=optionArgument Switches can be written as either: --option --option=YES --option=NO See also the perl documentation for Getopt::Long which is mimicked here in a loose manner. Different options are taken as a string each. A dictionary containing the values for given options is returned. An NSNumber being either 0 or 1 is returned for switches. */ - (NSDictionary *)getOptionsFromSpecification:(NSArray *)optionsSpecification; - (NSDictionary *)getOptionsFromSpecification:(NSArray *)optionsSpecification defaults:(NSDictionary *)defaults; @end gnustep-Zillion-0.1/NSProcessInfo+getopt.m000064400000000000000000000072621231046310600206250ustar00rootroot00000000000000/* NSProcessInfo+getopt.m Tue Dec 10 11:32:58 CET 2002 */ #import "NSProcessInfo+getopt.h" @implementation NSProcessInfo(Getopt) static NSDictionary *optionsDictionaryFromSpecification(NSArray *optionsSpecification) { NSMutableDictionary *options = [NSMutableDictionary dictionary]; int i, count; for (i = 0, count = [optionsSpecification count]; i < count; i++) { NSScanner *optionScanner = [NSScanner scannerWithString: [optionsSpecification objectAtIndex:i]]; NSString *option = nil, *optionValueType = nil; [optionScanner scanUpToString:@"=" intoString:&option]; [optionScanner scanString:@"=" intoString:(id *)nil]; [optionScanner scanUpToCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:&optionValueType]; [options setObject:optionValueType? optionValueType: @"" forKey:option]; } return options; } static NSArray *_remainingArguments; - (void)_setRemainingArguments:(NSArray *)args { [args retain]; [_remainingArguments release]; _remainingArguments = args; } - (NSArray *)remainingArguments { return _remainingArguments; } - (NSDictionary *)getOptionsFromSpecification:(NSArray *)optionsSpecification defaults:(NSDictionary *)defaults { NSDictionary *options = optionsDictionaryFromSpecification(optionsSpecification); NSMutableDictionary *optDict = defaults? [defaults mutableCopy] : [NSMutableDictionary dictionary]; NSMutableArray *remainingArgs = [NSMutableArray array]; NSArray *args = [self arguments]; int i, count; NSCharacterSet *whitespace = [NSCharacterSet whitespaceCharacterSet]; for (i = 0, count = [args count]; i < count; i++) { NSString *arg = [args objectAtIndex:i]; // is arg an option? if ([@"--" isEqualToString:[arg substringWithRange:NSMakeRange(0, 2)]]) { NSString *option = [arg substringWithRange:NSMakeRange(2, [arg length] - 2)]; NSScanner *optionScanner = [NSScanner scannerWithString:option]; NSString *optionName; id optionValue; [optionScanner scanUpToString:@"=" intoString:&optionName]; if (! [options objectForKey:optionName]) { [NSException raise:NSInvalidArgumentException format:@"option %@ not known", optionName]; } if (![[options valueForKey:optionName] isEqualToString:@""]) { // option requires argument if ([optionScanner scanString:@"=" intoString:(id *)nil]) { // the option value is given by a "=" [optionScanner scanUpToCharactersFromSet:whitespace intoString:&optionValue]; } else { // the next argument is the option value if (i == count - 1) [NSException raise:NSInvalidArgumentException format:@"option %@ requires an argument", optionName]; optionValue = [args objectAtIndex:++i]; // type checking } } else { // encountered a switch if ([optionScanner scanString:@"=" intoString:(id *)nil]) { // we expect either YES or NO [optionScanner scanUpToCharactersFromSet:whitespace intoString:&optionValue]; if ([optionValue isEqualToString:@"YES"]) optionValue = [NSNumber numberWithInt:1]; else if ([optionValue isEqualToString:@"NO"]) optionValue = [NSNumber numberWithInt:0]; else [NSException raise:NSInvalidArgumentException format:@"argument for switch must be either 'YES' or 'NO' " @"for option %@", optionName]; } else optionValue = [NSNumber numberWithInt:1]; } [optDict setObject:optionValue forKey:optionName]; } else { [remainingArgs addObject:arg]; } } [self _setRemainingArguments:[[remainingArgs copy] autorelease]]; return [[optDict copy] autorelease]; } - (NSDictionary *)getOptionsFromSpecification:(NSArray *)optionsSpecification { return [self getOptionsFromSpecification:optionsSpecification defaults:nil]; } @end gnustep-Zillion-0.1/ZillionClient.h000064400000000000000000000026731231046310600174070ustar00rootroot00000000000000/* ZillionClient.h Mon Dec 9 16:14:54 CET 2002 */ #import #import "ZillionClientServer.h" @protocol ZillionClientProtocol - initWithRespawnStatus:(BOOL)respawnStatus andMasterServer:(id )masterServer; - (id )masterClient; - (void)setMasterClient:(id )masterClient; - (NSDictionary *)attributes; - (NSString *)clientId; // the number of Jobs executed currently - (int)currentLoad; - (void)decreaseLoad; - (void)increaseLoad; /* someJob is a bundle collected to a data object a process is to be forked to separate the objc namespaces since unloading of classes is not supported as yet */ - (void)forkThreadForJobId:(NSString *)jobId withSeed:seed; - (void)dispatchUnitFromSeed:(NSData *)seed forJobId:(NSString *)jobId; - (void)stopUnitsForJobId:(NSString *)jobId; - (void)submitOutcome:(NSData *)outcome ofJob:(NSString *)jobId forSeed:seed storeHints:(NSDictionary *)someStoreHint; - (void)jobUnitDidEndForJobId:(NSString *)jobId seed:seed; - (oneway void)terminate; @end @protocol ZillionServerProtocol; @interface ZillionClient : ZillionClientServer { BOOL _clientToGoDown; BOOL _respawnStatus; NSLock *clientAdminLock; NSMutableDictionary *jobClientDictionary; NSMutableDictionary *threads; NSDictionary *_attributes; int load; id _masterClient; } - (BOOL)clientToGoDown; @end gnustep-Zillion-0.1/ZillionClient.m000064400000000000000000000134611231046310600174110ustar00rootroot00000000000000/* ZillionClient.m Mon Dec 9 17:17:22 CET 2002 */ #import "ZillionClient.h" #import "ZillionServer.h" #define IS_MASTER_CLIENT (![self masterClient]) @implementation ZillionClient /* The idea for respawning a new client is similar to why a server should be respawned. Look at ZillionServer.m for more elaboration on this topic. */ #define ZILLION_CLIENT_NAME @"zillionClient" - (NSString *)DOname { # if 0 // this may not be a unique identifier NSArray *ips = [[NSHost currentHost] addresses]; int i, count; NSLog(@"%@", [[NSHost currentHost] addresses]); for (i = 0, count = [ips count]; i < count; i++) { if (![[ips objectAtIndex:i] isEqualToString:@"127.0.0.1"]) return [ips objectAtIndex:i]; } return @""; # endif /* we try to use the hostname as unique identifier (in the DO namespace) if that fails we try for the PID which is probable but not garuanteed to be unique */ NSArray *hostnames = [[NSHost currentHost] names]; int i, count; for (i = 0, count = [hostnames count]; i < count; i++) if (![[hostnames objectAtIndex:i] hasPrefix:@"localhost"]) break; return [NSString stringWithFormat:@"%@_%@", ZILLION_CLIENT_NAME, i < count ? [hostnames objectAtIndex:i] : [NSNumber numberWithInt:[[NSProcessInfo processInfo] processIdentifier]] ]; } - (NSArray *)respawningArgumentsWithId:(NSString *)doNameId { return [NSArray arrayWithObjects:@"--DOname", [self respawningDOnameWithId:doNameId], @"--doRespawn=NO", nil]; } - (Protocol *)respawningProtocol { return @protocol(ZillionClientProtocol); } - (NSString *)respawningDOnameWithId:(NSString *)doNameId { NSString *name = [NSString stringWithFormat:@"%@_%@", [self clientId], doNameId]; return name; } #define DEFAULT_LOAD 3 - initWithRespawnStatus:(BOOL)respawnStatus andMasterServer:(id )masterServer { if (!(self = [super init])) return self; jobClientDictionary = [[NSMutableDictionary alloc] init]; _respawnStatus = respawnStatus; _attributes = [[NSDictionary alloc] initWithObjectsAndKeys: [NSNumber numberWithInt:DEFAULT_LOAD], @"load", nil]; threads = [[NSMutableDictionary alloc] init]; clientAdminLock = [[NSLock alloc] init]; [self setMasterServer:masterServer]; return self; } - init { return [self initWithRespawnStatus:NO andMasterServer:nil]; } - (void)dealloc { [clientAdminLock release]; [jobClientDictionary release]; [_attributes release]; [threads release]; [super dealloc]; } - (id )masterClient { return _masterClient; } - (void)setMasterClient:(id )masterClient { [masterClient retain]; [_masterClient release]; _masterClient = masterClient; } - (NSString *)clientId { return [self DOname]; } - (BOOL)clientToGoDown { return _clientToGoDown; } - (void)terminate { NSEnumerator *clientEnum; id client; for (clientEnum = [jobClientDictionary objectEnumerator]; (client = [clientEnum nextObject]); ) if (client != self) [client terminate]; _clientToGoDown = YES; } - (NSDictionary *)attributes { return _attributes; } - (id )clientForJob:(NSString *)jobId { id client; client = [jobClientDictionary objectForKey:jobId]; if (client) { return client; } if (!_respawnStatus) { [jobClientDictionary setObject:self forKey:jobId]; return self; } NSLog(@"Respawning client for job: %@", jobId); client = [self respawnedObjectWithId:jobId]; [client setMasterClient:self]; [jobClientDictionary setObject:client forKey:jobId]; return client; } - (void)forkedJobWithSpecification:(NSDictionary *)spec { NSAutoreleasePool *threadPool = [[NSAutoreleasePool alloc] init]; id job = [spec objectForKey:ZillionJobKey]; id seed = [[job class] seedObjectFromDataRepresentation:[spec objectForKey:ZillionSeedKey]]; NSLog(@"got forked"); [job startJobUnitWithSeed:seed andClient:self]; [threadPool release]; [NSThread exit]; } - (void)forkThreadForJobId:(NSString *)jobId withSeed:(NSData *)seed { id job = [self instantiateJobWithId:jobId]; NSDictionary *jobSpecification = [NSDictionary dictionaryWithObjectsAndKeys: seed, ZillionSeedKey, self, ZillionClientKey, job, ZillionJobKey, nil]; NSLog(@"Forking job thread [%@]...", jobId); NS_DURING [NSThread detachNewThreadSelector:@selector(forkedJobWithSpecification:) toTarget:self withObject:jobSpecification ]; NS_HANDLER NSLog (@"Exception while executing job[%@]: %@", jobId, localException); NS_ENDHANDLER } - (void)dispatchUnitFromSeed:(NSData *)seed forJobId:(NSString *)jobId { id client = [self clientForJob:jobId]; NSLog(@"About to dispatch unit for job: %@ client being:%@", jobId, client); [client forkThreadForJobId:jobId withSeed:seed]; [self increaseLoad]; NSLog(@"job did start [%d]", load); } - (int)currentLoad { return load; } - (void)decreaseLoad { load--; } - (void)increaseLoad { load++; } - (void)submitOutcome:(NSData *)outcome ofJob:(NSString *)jobId forSeed:seed storeHints:(NSDictionary *)someStoreHints { NSData *seedId = [[self jobClassForJobId:jobId] dataRepresentationOfSeed:seed]; NS_DURING NSLog(@"storing outcome"); [[self masterServer] submitOutcome:outcome ofJob:jobId forSeedId:seedId storeHints:someStoreHints]; NS_HANDLER NSLog (@"Exception while storing results[%@]: %@", jobId, localException); NS_ENDHANDLER } - (void)jobUnitDidEndForJobId:(NSString *)jobId seed:seed { NSData *seedId = [[self jobClassForJobId:jobId] dataRepresentationOfSeed:seed]; // we do not yet know how to determine time consumption of the thread [[self masterServer] jobUnitDidEndForJobId:jobId seedId:seedId timePenalty:1]; [[self masterClient] decreaseLoad]; } - (void)stopUnitsForJobId:(NSString *)jobId { // stop threads or stop the client being forked which handles the jobs with jobId } @end gnustep-Zillion-0.1/ZillionClientServer.h000064400000000000000000000035621231046310600205740ustar00rootroot00000000000000/* ZillionClientServer.h Wed Dec 11 17:45:24 CET 2002 copyright: Stefan Böhringer (stefan.boehringer@uni-essen.de) (2002, 2003) This code is governed by a BSD license as expounded in the LICENSE file */ #import /* this class is to factor out code needed, both, by the classes ZillionServer and ZillionClient */ #define SETJOBA(jobSpec, v, attribute) [jobSpec setObject:v forKey:attribute] #define JOBA(jobSpec, attribute) [jobSpec objectForKey:attribute] #define JOBBUNDLE(jobSpec) JOBA(jobSpec, @"bundle") #define SETJOBBUNDLE(jobSpec, bundle) SETJOBA(jobSpec, bundle, @"bundle") @protocol ZillionServerProtocol; @protocol ZillionJobProtocol; @interface ZillionClientServer : NSObject { int bundleSeq; id _masterServer; NSMutableDictionary *_jobs; //store the jobs involved } // abstract - (NSString *)DOname; // abstract - (NSArray *)respawningArgumentsWithId:(NSString *)doNameId; // abstract - (Protocol *)respawningProtocol; // concrete - (NSString *)respawningDOnameWithId:(NSString *)doNameId; // concrete - respawnedObject; - respawnedObjectWithId:(NSString *)doNameId; - respawnedObjectWithId:(NSString *)doNameId doObserveConnection:(BOOL)doObserve; /* methods concerned with job creation */ - (NSBundle *)bundleForPackedBundle:(NSData *)packedBundle; // creates an empty specification if needed - (NSMutableDictionary *)jobSpecificationForJobId:(NSString *)jobId; - (void)setJobSpecification:(NSDictionary *)jobSpec forId:(NSString *)joId; - (NSArray *)jobIds; - (id )instantiateJobFromBundle:(NSBundle *)jobBundle; - (id )instantiateJobWithId:(NSString *)jobId; - (Class)jobClassForJobId:(NSString *)jobId; /* common administrative methods */ - (void)setMasterServer:(id )masterServer; - (id )masterServer; @end gnustep-Zillion-0.1/ZillionClientServer.m000064400000000000000000000143671231046310600206060ustar00rootroot00000000000000/* ZillionClientServer.m Wed Dec 11 17:47:57 CET 2002 copyright: Stefan Böhringer (stefan.boehringer@uni-essen.de) (2002, 2003) This code is governed by a BSD license as expounded in the LICENSE file */ #import "ZillionClientServer.h" #import "ZillionServer.h" #import "NSFileManager+directories.h" @implementation ZillionClientServer - init { if (!(self = [super init])) return self; _jobs = [[NSMutableDictionary alloc] init]; return self; } - (void)dealloc { [_jobs release]; [_masterServer release]; [super dealloc]; } /* methods to respawn new processes */ - (NSString *)DOname { [NSException raise:NSInternalInconsistencyException format:@"method is abstract"]; return nil; } - (NSArray *)respawningArgumentsWithId:(NSString *)doNameId { [NSException raise:NSInternalInconsistencyException format:@"method is abstract"]; return nil; } - (Protocol *)respawningProtocol { [NSException raise:NSInternalInconsistencyException format:@"method is abstract"]; return 0; } - (NSString *)respawningDOnameWithId:(NSString *)doNameId { // NSProcessInfo *pInfo = [NSProcessInfo processInfo]; return [NSString stringWithFormat:@"%@_%d", [self DOname], doNameId]; } #define RETRY_COUNT 2 // how many seconds are to be waited until a connection is to be established #define INITIAL_DELAY 1 #define RETRY_DELAY 2.5 - respawnedObjectWithId:(NSString *)doNameId doObserveConnection:(BOOL)doObserve { NSProcessInfo *pInfo = [NSProcessInfo processInfo]; NSString *respawnedDOName = [self respawningDOnameWithId:doNameId]; Protocol *myProtocol = [self respawningProtocol]; NSArray *arguments = [self respawningArgumentsWithId:doNameId]; id newObject = nil; int retries; NSLog(@"RespawningName:%@", respawnedDOName); [NSTask launchedTaskWithLaunchPath:[[pInfo arguments] objectAtIndex:0] arguments:arguments]; [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:INITIAL_DELAY]]; for (retries = RETRY_COUNT; ! (newObject = [NSConnection rootProxyForConnectionWithRegisteredName: respawnedDOName host:nil]) && retries; retries--) [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:RETRY_DELAY]]; if (newObject) { //[newObject retain]; // avoid exception raising [newObject setProtocolForProxy:myProtocol]; if (doObserve) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respawnedConnectionDidDie:) name:NSConnectionDidDieNotification object:[newObject connectionForProxy]]; } } else { NSLog(@"Couldn't respawn process %@", respawnedDOName); } return newObject; } - respawnedObject { return [self respawnedObjectWithId:nil]; } - respawnedObjectWithId:(NSString *)doNameId { return [self respawnedObjectWithId:doNameId doObserveConnection:NO]; } /* <§> Jobs */ - (NSBundle *)bundleForPackedBundle:(NSData *)packedBundle { NSString *tempDir = NSTemporaryDirectory(); int pid = [[NSProcessInfo processInfo] processIdentifier]; NSFileManager *fileManager = [NSFileManager defaultManager]; NSBundle *jobBundle; Class jobClass; // uncommenting the next two lines causes a crash // if ([masterServer isKindOfClass:[NSDistantObject class]]) // [(NSDistantObject *)masterServer setProtocolForProxy:@protocol(ZillionServerProtocol)]; tempDir = [NSString stringWithFormat:@"%@/%d/%d", tempDir, pid, bundleSeq++]; [fileManager createAllDirectoriesComposingPath:tempDir attributes:nil]; NSLog(@"Deserializing incoming job [placed @ %@]...", tempDir); [fileManager writeDataRepresentation:packedBundle toPath:tempDir]; jobBundle = [NSBundle bundleWithPath:tempDir]; jobClass = [jobBundle principalClass]; if (![jobClass conformsToProtocol:@protocol(ZillionJobProtocol)]) { NSLog(@"Didn't find appropriate code in bundle to submit as job [principleClass %@]", NSStringFromClass(jobClass)); return nil; } NSLog(@"...done"); return jobBundle; } - (NSArray *)jobIds { return [_jobs allKeys]; } - (NSMutableDictionary *)jobSpecificationForJobId:(NSString *)jobId { NSMutableDictionary *specification = [_jobs objectForKey:jobId]; if (!specification) { specification = [NSMutableDictionary dictionary]; [_jobs setObject:specification forKey:jobId]; } return specification; } - (void)setJobSpecification:(NSDictionary *)jobSpec forId:(NSString *)jobId { [_jobs setObject:[jobSpec mutableCopy] forKey:jobId]; } - (Class)jobClassForJobId:(NSString *)jobId { NSMutableDictionary *jobSpec = [self jobSpecificationForJobId:jobId]; NSBundle *jobBundle = JOBBUNDLE(jobSpec); return [jobBundle principalClass]; } - (id )instantiateJobFromBundle:(NSBundle *)jobBundle { Class jobClass = [jobBundle principalClass]; NSString *jobId = [jobClass jobId]; NSMutableDictionary *jobSpec; id job; NSLog(@"%@", jobClass); if (! jobId) [NSException raise:NSInvalidArgumentException format: @"Couldn't retrieve jobId from bundle"]; jobSpec = [self jobSpecificationForJobId:jobId]; job = [[jobClass alloc] initWithBundle:jobBundle]; NSLog(@"Instantiating job %@ %@", jobId, jobBundle); if (!jobSpec) jobSpec = [NSMutableDictionary dictionary]; [jobSpec setObject:jobBundle forKey:@"bundle"]; NSLog(@"did instantiate %@ %@", jobId, jobBundle); return job; } - (id )instantiateJobWithId:(NSString *)jobId { NSMutableDictionary *jobSpec = [self jobSpecificationForJobId:jobId]; NSBundle *jobBundle = JOBBUNDLE(jobSpec); if (!jobBundle) { // no instance exists now jobBundle = [self bundleForPackedBundle: [[self masterServer] packedJobBundleForJobId:jobId]]; SETJOBBUNDLE(jobSpec, jobBundle); } return [self instantiateJobFromBundle:jobBundle]; } /* the masterServer is expected to exist for the longest time of all processes and is therefore not retained */ // <%> - (void)setMasterServer:(id )masterServer { # ifndef _DO_TEST_CASE return; # else [masterServer retain]; [_masterServer release]; _masterServer = masterServer; # endif } - (id )masterServer { # ifndef _DO_TEST_CASE _masterServer = [[NSConnection rootProxyForConnectionWithRegisteredName:ZILLION_SERVER_NAME host:nil] retain]; if (!_masterServer) { NSLog(@"Failed to establish connection "); } [_masterServer setProtocolForProxy:@protocol(ZillionServerProtocol)]; # endif return _masterServer; } @end gnustep-Zillion-0.1/ZillionServer.h000064400000000000000000000061721231046310600174350ustar00rootroot00000000000000/* ZillionServer.h Tue Aug 27 17:00:11 CEST 2002 */ #import #import "ZillionClientServer.h" #import "ZillionClient.h" #define ZILLION_SERVER_NAME @"zillion" @protocol ZillionClientProtocol; @protocol ZillionServerProtocol; @protocol ZillionJobProtocol; @protocol ZillionServerProtocol /* managing masters */ - (void)setMasterServer:(id )masterServer; - (id )masterServer; - (void)terminate; /* managing clients */ - (void)registerClient:(id )someClient; - (void)deregisterClient:(id )someClient; /* managing jobs */ - (NSString *)dispatchJob:(bycopy NSData *)bundle; - (bycopy NSString *)loadAndRegisterJob:(NSData *)bundle; - (void)registerJob:(NSData *)jobBundle withId:(NSString *)jobId; - (NSData *)packedJobBundleForJobId:(NSString *)jobId; /* forward outcome to the client to let it store relevant stuff if outcome cannot be submitted as a linge chunk at the end of the job unit someStoreHint can be used to */ - (void)submitOutcome:(NSData *)outcome ofJob:(NSString *)jobId forSeedId:(NSData *)seedId storeHints:(NSDictionary *)someStoreHint; - (void)jobUnitDidEndForJobId:(NSString *)jobId seedId:(NSData *)seedId timePenalty:(NSTimeInterval)penalty; /* bringing the jobs into action */ // sender is a dummy argument to make it amenable to performSelector: - (void)scheduleJobs:sender; - (NSData *)nextSeedIdForJobId:(NSString *)jobId; /* storing results */ - (void)setOutcome:(bycopy NSData *)outcome forSeedId:(bycopy NSData *)seedId andJobId:(bycopy NSString *)jobId; - (NSMutableDictionary *)outcomeDictionaryForJobId:(bycopy NSString *)jobId; @end #define ZillionClientKey @"client" #define ZillionSeedKey @"seed" #define ZillionJobKey @"job" @protocol ZillionJobProtocol + (NSString *)jobId; + (NSData *)dataRepresentationOfSeed:seed; + seedObjectFromDataRepresentation:(NSData *)seed; - initWithBundle:(NSBundle *)someBundle; - (NSEnumerator *)seedEnumeratorWithSeed:(NSData *)seed; /* The specification of the jobs entails the following keys (with ovious meanings) ZillionClientKey ZillionSeedKey */ - (void)startJobUnitWithSeed:aSeed andClient:(id )aClient; /* The job class must not store any information in global variables since the class may be deallocated at any time. Instead the information can be stored in the server via -setOutcome:forSeedId:andJobId: */ + (void)saveOutcome:(NSData *)outcome forSeedId:(NSData *)seedId storeHints:(NSDictionary *)someStoreHint usingServer:(id )aServer; + (void)sealJobOutcomesUsingServer:(id )aServer; @end @interface ZillionServer : ZillionClientServer { NSMutableDictionary *proxyServers; unsigned proxyServerIdCounter; NSMutableDictionary *clients; NSMutableDictionary *dispatchedSeeds; NSMutableDictionary *outcomes; BOOL _serverToGoDown; BOOL _respawnStatus; BOOL _reschedulingIsMarked; } - initWithRespawnStatus:(BOOL)respawnStatus; - (BOOL)serverToGoDown; - (id )jobInstance:(NSString *)jobId; @end gnustep-Zillion-0.1/ZillionServer.m000064400000000000000000000344461231046310600174470ustar00rootroot00000000000000/* ZillionServer.m Tue Aug 27 17:02:16 CEST 2002 */ #import "ZillionServer.h" #import "NSProcessInfo+getopt.h" /* Outline of the protocol: The server starts up and offers up his services under the name ZILLION_SERVER. A client can register via DO with the server to offer calculation power. (-registerClient:) - the client has properties: - load: how many jobs are submitted in parallel - memory: how much memory is available - ... to be extended A Job is then initiated as follows: - The server receives a -dispatchJob: method. This takes a NSData object representing a bundle which encodes the job. A job Id is returned. - The job is then initiated by choosing from the clients and sending a -loadJob: method forwarding the bundle from the server - The server then asks the job for a seedEnumerator and for a seed - This seed is transferred to the client via -dispatchUnitFromSeed:forJobId: - which in turn detaches a new thread and asks the job to -startJobWithClient:andSeed: - results are returned */ #define PROXYSERVER_FOR_JOBID(jobId) (!_respawnStatus? self: [self serverForJobId:jobId]) #define RESCHEDULE() [self reschedule] #define SEALJOBWITHID(jobId) do { \ [[NSRunLoop currentRunLoop] performSelector:@selector(sealJobWithId:) \ target:self \ argument:[jobId copy] order:1 \ modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]]; \ NSLog(@"scheduled sealing of job:%@", jobId);\ } while (0) #define JobSeedStatus(j) \ (!![[self jobSpecificationForJobId:j] objectForKey:@"seedsAreExhausted"]) #define SetJobSeedsExhausted(j) \ [[self jobSpecificationForJobId:j] setObject:@"YES" forKey:@"seedsAreExhausted"] @implementation ZillionServer /* The idea for respawning a new server is that classes cannot be unloaded in objc currently due to reentrance problems which would occur otherwise. The new server is started and */ - (NSString *)DOname { return ZILLION_SERVER_NAME; } - (NSArray *)respawningArgumentsWithId:(NSString *)doNameId { return [NSArray arrayWithObjects:@"--serverName", [self respawningDOnameWithId:doNameId], @"--doRespawn=NO", nil]; } - (Protocol *)respawningProtocol { return @protocol(ZillionServerProtocol); } - initWithRespawnStatus:(BOOL)respawnStatus { if (!(self = [super init])) return self; clients = [[NSMutableDictionary alloc] init]; _respawnStatus = respawnStatus; proxyServers = [[NSMutableDictionary alloc] init]; outcomes = [[NSMutableDictionary alloc] init]; dispatchedSeeds = [[NSMutableDictionary alloc] init]; return self; } - init { return [self initWithRespawnStatus:NO]; } - (void)dealloc { NSLog(@"about to dealloc ZillionServer object"); [dispatchedSeeds release]; [outcomes release]; [clients release]; [proxyServers release]; [super dealloc]; } - (void)reschedule { if (_reschedulingIsMarked) return; _reschedulingIsMarked = YES; [[NSRunLoop currentRunLoop] performSelector:@selector(scheduleJobs:) target:self argument:nil order:0 modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]]; } - (void)clientConnectionDidDie:(NSNotification *)notification { // presume this is the client [self deregisterClient:[[notification object] rootObject]]; } - (void)registerClient:(id )someClient { NSDictionary *newClient = [NSDictionary dictionaryWithObjectsAndKeys: someClient, @"object", [someClient attributes], @"attributes", nil]; [clients setObject:newClient forKey:[someClient clientId]]; // see doc for possible drawbacks; we might not notice invalidation // unless we ping the client [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clientConnectionDidDie:) name:NSConnectionDidDieNotification object:[(NSDistantObject *)someClient connectionForProxy]]; NSLog(@"Registered client:%@", someClient); RESCHEDULE(); } - (void)deregisterClient:(id )someClient { [clients removeObjectForKey:[someClient clientId]]; RESCHEDULE(); } - (id )serverForJobId:(NSString *)jobId { return [proxyServers objectForKey:jobId]; } - (void)respawnedConnectionDidDie:(NSNotification *)notification { NSLog(@"Some proxy went away"); } - (NSString *)dispatchJob:(NSData *)bundle { id proxyServer = self; NSString *jobId; // we respawn a server to loadd the job if (_respawnStatus) { proxyServer = [self respawnedObjectWithId: [[NSNumber numberWithInt:proxyServerIdCounter] stringValue] doObserveConnection:YES]; [proxyServer setMasterServer:self]; proxyServerIdCounter++; } jobId = [proxyServer loadAndRegisterJob:bundle]; if (_respawnStatus) { [proxyServers setObject:proxyServer forKey:jobId]; } RESCHEDULE(); return jobId; } - (NSString *)description { NSLog(@"description forthcoming"); return [super description]; } // called in the proxyServer - (void)sealJobWithId:(NSString *)jobId { NSLog(@"Welcome to the finished job [%d]:%@", _respawnStatus, jobId); if (_respawnStatus) { id proxy = PROXYSERVER_FOR_JOBID(jobId); [proxy sealJobWithId:jobId]; NSLog(@"did seal job in proxy for job:%@, now terminating", jobId); [proxy terminate]; [proxyServers removeObjectForKey:jobId]; } else { [[[self jobInstance:jobId] class] sealJobOutcomesUsingServer:[self masterServer]]; NSLog(@"Sealing job:%@", jobId); } } - (BOOL)serverToGoDown { return _serverToGoDown; } - (void)terminate { NSLog(@"Server is about to terminate"); if (_respawnStatus) { NSEnumerator *proxies = [proxyServers objectEnumerator]; id proxyServer; while ( (proxyServer = [proxies nextObject]) ) [proxyServer terminate]; } _serverToGoDown = YES; } - (void)registerJob:(NSData *)jobBundle withId:(NSString *)jobId { NSMutableDictionary *jobSpec = [self jobSpecificationForJobId:jobId]; NSLog(@"Registering %@.", jobId); [jobSpec setObject:jobBundle forKey:@"packedBundle"]; [jobSpec setObject:[NSNumber numberWithDouble:0] forKey:@"timePenalty"]; } - (NSData *)packedJobBundleForJobId:(NSString *)jobId { return [[self jobSpecificationForJobId:jobId] objectForKey:@"packedBundle"]; } - (NSString *)loadAndRegisterJob:(NSData *)packedBundle { NSBundle *jobBundle = [self bundleForPackedBundle:packedBundle]; Class jobClass = [jobBundle principalClass]; NSLog(@"...about to register %lx.", [self masterServer]); [[self masterServer] registerJob:packedBundle withId:[jobClass jobId]]; [self instantiateJobFromBundle:jobBundle]; NSLog(@"...loaded the code for job %@.", [jobClass jobId]); return [jobClass jobId]; } /* this returns a unique jobInstance */ - (id )jobInstance:(NSString *)jobId { NSMutableDictionary *jobSpec = [self jobSpecificationForJobId:jobId]; id job = [jobSpec objectForKey:@"instance"]; /* we must be aware that any instances might have gone before sind on reloading the proxy server is done away with to free the class hierarchy of ObjC */ if (!job) { job = [self instantiateJobWithId:jobId]; [jobSpec setObject:job forKey:@"instance"]; } return job; } - (NSData *)nextSeedIdForJobId:(NSString *)jobId { // trigger job instantiation id job = [self jobInstance:jobId]; NSMutableDictionary *jobSpec = [self jobSpecificationForJobId:jobId]; NSEnumerator *seedEnum = [jobSpec objectForKey:@"enumerator"]; if (!seedEnum) { NSLog(@"new seed enum"); seedEnum = [job seedEnumeratorWithSeed:nil]; [jobSpec setObject:seedEnum forKey:@"enumerator"]; } return [[job class] dataRepresentationOfSeed:[seedEnum nextObject]]; } #define JOBPenalty(j) \ [[[self jobSpecificationForJobId:j] objectForKey:@"timePenalty"] doubleValue] #define JOBNextSeed(j) \ [[[self jobSpecificationForJobId:j] objectForKey:@"seedEnumerator"] nextObject] #define JOBIncPenatly(j, p) \ do { \ NSMutableDictionary *jDict = [self jobSpecificationForJobId:j]; \ [jDict setObject:[NSNumber numberWithDouble:(p) + \ [[jDict objectForKey:@"timePenalty"] doubleValue]] \ forKey:@"timePenalty"]; \ } while(0) #define ZillionOutcomesKey @"outcomes" - (NSMutableDictionary *)jobOutcomesForJobId:(NSString *)jobId { NSMutableDictionary *jobOutcomes = [outcomes objectForKey:jobId]; if (!jobOutcomes) { jobOutcomes = [NSMutableDictionary dictionary]; [outcomes setObject:jobOutcomes forKey:jobId]; [jobOutcomes setObject:[NSMutableArray array] forKey:@"finishedSeeds"]; [jobOutcomes setObject:[NSMutableDictionary dictionary] forKey:ZillionOutcomesKey]; } return jobOutcomes; } - (void)submitOutcome:(NSData *)outcome ofJob:(NSString *)jobId forSeedId:(NSData *)seedId storeHints:(NSDictionary *)someStoreHints { if (_respawnStatus) { id proxyServer = PROXYSERVER_FOR_JOBID(jobId); [proxyServer submitOutcome:outcome ofJob:jobId forSeedId:seedId storeHints:someStoreHints]; } else { id job = [self jobInstance:jobId]; [[job class] saveOutcome:outcome forSeedId:seedId storeHints:someStoreHints usingServer:[self masterServer]]; } } /* we'll store outcomes if we are asked to do so */ - (void)setOutcome:(bycopy NSData *)outcome forSeedId:(bycopy NSData *)seedId andJobId:(bycopy NSString *)jobId { NSMutableDictionary *jobOutcomes = [self jobOutcomesForJobId:jobId]; [[jobOutcomes objectForKey:ZillionOutcomesKey] setObject:outcome forKey:seedId]; } - (NSMutableDictionary *)outcomeDictionaryForJobId:(NSString *)jobId { return [[self jobOutcomesForJobId:jobId] objectForKey:ZillionOutcomesKey]; } - (void)jobUnitDidEndForJobId:(NSString *)jobId seedId:(NSData *)seedId timePenalty:(NSTimeInterval)penalty { NSMutableDictionary *jobOutcomes = [self jobOutcomesForJobId:jobId]; NSMutableSet *seeds = [dispatchedSeeds objectForKey:jobId]; NSLog(@"about to Register finished seed %@", seedId); [[jobOutcomes objectForKey:@"finishedSeeds"] addObject:seedId]; JOBIncPenatly(jobId, penalty); if (![seeds containsObject:seedId]) { [NSException raise:NSInternalInconsistencyException format:@"Finished Seed was not registered [%@]", seedId]; } else { [seeds removeObject:seedId]; } // are we ready to seal the job? if (![seeds count] && JobSeedStatus(jobId)) SEALJOBWITHID(jobId); RESCHEDULE(); } - (void)registerSeed:(NSData *)seedForJob forJob:(NSString *)jobId { NSMutableSet *seeds = [dispatchedSeeds objectForKey:jobId]; if (!seeds) { seeds = [NSMutableSet set]; [dispatchedSeeds setObject:seeds forKey:jobId]; } [seeds addObject:[[seedForJob copy] autorelease]]; } #if 0 - (double)cumulatedPenalty { NSEnumerator *jobEnum = [outcomes keyEnumerator]; NSDictionary *job; double penalty = 0; while (job = [jobEnum nextObject]) { penalty += JOBPenalty(job); } return penalty; } #endif // this is a biggest residual seat distribution scheme where // dividend is the count of seats // relative is an array of (relative) votes // arrayLength is the number of parties and // result holds the number of seats after the distribution of seats typedef struct { int index; double residual; } Residual; int cmpResidual(Residual *r1, Residual *r2) { return r1->residual == r2->residual? 0 : (r1->residual < r2->residual? -1: 1); } typedef int (*QSortComparator)(const void*, const void*); static void scaleSetTo(double *relative, unsigned arrayLength, unsigned dividend, unsigned *result) { unsigned i, cSum, cRest; double rSum; Residual residuals[arrayLength]; for (i = 0, rSum = 0; i < arrayLength; i++) rSum += relative[i], result[i] = 0; if (!rSum) return; for (i = 0; i < arrayLength; i++) result[i] = (int)(relative[i] / rSum * arrayLength); do { for (i = 0; i < arrayLength; i++) { residuals[i] = ((Residual){i, result[i] / rSum * arrayLength - result[i]}); } qsort(residuals, arrayLength, sizeof(Residual), (QSortComparator)cmpResidual); for (i = cSum = 0; i < arrayLength; i++) cSum += result[i]; for (i = 0, cRest = dividend - cSum; i < arrayLength && cRest; i++, cRest--) result[residuals[i].index]++; } while (cRest); } // reprioritize when a new job is started or an old one ends #define CLIENT_MAX_LOAD(c) [[[c objectForKey:@"attributes"] objectForKey:@"load"] intValue] - (void)scheduleJobs:sender { NSEnumerator *clientEnum; NSString *clientId; NSMutableArray *freeClients = [NSMutableArray array]; NSLog(@"Scheduling jobs..."); // clear flag _reschedulingIsMarked = NO; // determine which clients to run on for (clientEnum = [clients keyEnumerator]; (clientId = [clientEnum nextObject]); ) { NSDictionary *clientSpec = [clients objectForKey:clientId]; id client = [clientSpec objectForKey:@"object"]; int i, count; int currentLoad = [client currentLoad]; for (i = 0, count = CLIENT_MAX_LOAD(clientSpec) - currentLoad ; i < count; i++) [freeClients addObject:client]; } NSLog(@"Free client count %d", [freeClients count]); if (![freeClients count]) return; NS_DURING // determine which jobs to run // the inverse relative time penatly is proportional to the share in clients for each job { NSArray *jobIds = [self jobIds]; int jobCount = [jobIds count]; double penalties[jobCount], penalty; NSString *jobId; int i, j, k, count, slots[jobCount]; id proxyServer; for (i = 0, count = [jobIds count]; i < count; i++) { jobId = [jobIds objectAtIndex:i]; penalty = JOBPenalty(jobId); // rather than setting to 1, set to priority of the job in the instance penalties[i] = penalty? 1/penalty: 1; } scaleSetTo(penalties, jobCount, [freeClients count], slots); for (i = k = 0, count = [jobIds count]; i < count; i++) { jobId = [jobIds objectAtIndex:i]; for (j = 0; j < slots[i]; j++) { NSData *seedForJob; proxyServer = PROXYSERVER_FOR_JOBID(jobId); seedForJob = [proxyServer nextSeedIdForJobId:jobId]; if (!seedForJob) { NSLog(@"Exhausted all seed for job %@", jobId); // we cannot now seal the job since we have to wait for all jobs to be finished // we therefore have to track which seeds were submitted and recognize // submission of results // we flag that we can now seal the job if all remaining seeds are done SetJobSeedsExhausted(jobId); break; } [self registerSeed:seedForJob forJob:jobId]; NSLog(@"Dispatching unit for job %@", jobId); [[freeClients objectAtIndex:k++] dispatchUnitFromSeed:seedForJob forJobId:jobId]; } } } NS_HANDLER NSLog(@"Exception raised during job dispatch with reason: %@", [localException reason]); NS_ENDHANDLER NSLog(@"did schedule..."); } @end gnustep-Zillion-0.1/docu/000075500000000000000000000000001231046310600154015ustar00rootroot00000000000000gnustep-Zillion-0.1/docu/CVS/000075500000000000000000000000001231046310600160345ustar00rootroot00000000000000gnustep-Zillion-0.1/docu/CVS/Entries000064400000000000000000000000021231046310600173600ustar00rootroot00000000000000D gnustep-Zillion-0.1/docu/CVS/Repository000064400000000000000000000000151231046310600201320ustar00rootroot00000000000000zillion/docu gnustep-Zillion-0.1/docu/CVS/Root000064400000000000000000000000701231046310600166770ustar00rootroot00000000000000:pserver:anonymous@cvs.sourceforge.net:/cvsroot/zillion gnustep-Zillion-0.1/killClients.sh000075500000000000000000000002761231046310600172700ustar00rootroot00000000000000gdomap -N | perl -ne 'system "gdomap -U $_" if (/zillion[_C]/)' ps auxww | egrep "zillion" | perl -ne '($pid) = (/.*?(\d+).*--(DOn|serverN)ame/); system("kill -1 $pid") if (defined($pid));' gnustep-Zillion-0.1/printClients.sh000075500000000000000000000001671231046310600174700ustar00rootroot00000000000000ps auxww | egrep "zillion" | perl -ne '($pid) = (/.*?(\d+).*--(DOn|serverN)ame/); print("$pid\n") if (defined($pid));' gnustep-Zillion-0.1/simpleZillionJob.h000064400000000000000000000002301231046310600201000ustar00rootroot00000000000000/* simpleZillionJob.h Mon Dec 9 19:01:31 CET 2002 */ #import "ZillionServer.h" @interface SimpleZillionJob : NSObject @end gnustep-Zillion-0.1/simpleZillionJob.m000064400000000000000000000043041231046310600201130ustar00rootroot00000000000000/* simpleZillionJob.m Mon Dec 9 18:55:08 CET 2002 */ #import "simpleZillionJob.h" #define SIMPLE_JOBS_COUNT 10 @interface SimpleJobEnumerator : NSEnumerator { int number; } @end @implementation SimpleJobEnumerator - initWithSeed:seed { if (!(self = [super init])) return self; number = seed? [(NSNumber *)seed intValue]: 0; return self; } - nextObject { NSLog(@"Enum number %d", number); return number < SIMPLE_JOBS_COUNT? [NSNumber numberWithInt:number++]: nil; } @end @implementation SimpleZillionJob + (NSString *)jobId { return @"simpleJob"; } - initWithBundle:(NSBundle *)someBundle { return [self init]; } - (NSEnumerator *)seedEnumeratorWithSeed:(NSData *)dataSeed { id seed = !dataSeed? nil: [NSUnarchiver unarchiveObjectWithData:dataSeed]; return [[[SimpleJobEnumerator alloc] initWithSeed:seed] autorelease]; } - (void)startJobUnitWithSeed:seed andClient:(id )client { # if 0 NSLog(@"sleeping"); [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]]; # else // do some real "numbercrunching" # define ITERATIONS 100000ULL unsigned long long i; double outcome = 1; NSLog(@"lots of iterations"); for (i = 0; i < ITERATIONS; i++) { outcome *= exp(i) * log(i) * sin(i) * cos(i); } # endif [client submitOutcome:[NSArchiver archivedDataWithRootObject: [NSNumber numberWithInt:[(NSNumber *)seed intValue]*2]] ofJob:[[self class] jobId] forSeed:seed storeHints:nil]; [client jobUnitDidEndForJobId:[[self class] jobId] seed:seed]; } + (NSData *)dataRepresentationOfSeed:seed { return seed? [NSArchiver archivedDataWithRootObject:seed]: nil; } + seedObjectFromDataRepresentation:(NSData *)seed { return seed? [NSUnarchiver unarchiveObjectWithData:seed]: nil; } + (void)saveOutcome:(NSData *)outcome forSeedId:(NSData *)seedId storeHints:(NSDictionary *)someStoreHint usingServer:(id )aServer { NSLog(@"about to save outcome:%@", outcome); [aServer setOutcome:outcome forSeedId:seedId andJobId:[[self class] jobId]]; } + (void)sealJobOutcomesUsingServer:(id )aServer { //NSLog(@"Sealing job to: %@", [aServer outcomeDictionaryForJobId:[[self class] jobId]]); NSLog(@"Did seal %@", [[self class] jobId]); } @end gnustep-Zillion-0.1/simpleZillionJobInfo.plist000064400000000000000000000000521231046310600216220ustar00rootroot00000000000000{ NSPrincipalClass = SimpleZillionJob; } gnustep-Zillion-0.1/zillion.m000064400000000000000000000034011231046310600163030ustar00rootroot00000000000000/* zillion.m Tue Aug 27 09:32:29 CEST 2002 Zillion is a Server application for scheduling tasks on slave machines. Due to the virtues of GNUstep it is capable of servicing, both, real time and number crunching applications. */ #import #import "ZillionServer.h" #import "NSProcessInfo+getopt.h" int main(int argc, const char **argv) { NSAutoreleasePool *mainPool = [[NSAutoreleasePool alloc] init]; ZillionServer *serverObject; NSConnection *theConnection; NSDate *distantFuture = [NSDate distantFuture]; NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop]; NSProcessInfo *proc = [NSProcessInfo processInfo]; NSDictionary *options = [proc getOptionsFromSpecification:[NSArray arrayWithObjects: @"serverName=s", @"doRespawn", nil] defaults:[NSDictionary dictionaryWithObjectsAndKeys: ZILLION_SERVER_NAME, @"serverName", [NSNumber numberWithInt:1], @"doRespawn", nil]]; NSString *serverName = [options objectForKey:@"serverName"]; BOOL doRespawn = [[options objectForKey:@"doRespawn"] intValue]; NSLog(@"Starting server [%@, respawning:%@]...", serverName, doRespawn? @"YES": @"NO"); serverObject = [[ZillionServer alloc] initWithRespawnStatus:doRespawn]; theConnection = [NSConnection defaultConnection]; [theConnection setRootObject:serverObject]; if ([theConnection registerName:serverName] == NO) { /* Handle error. */ NSLog(@"Could not register name with PortName server"); } while (![serverObject serverToGoDown]) { [currentRunLoop acceptInputForMode:NSDefaultRunLoopMode beforeDate:distantFuture]; if (!doRespawn) { NSLog(@"abc"); NSLog(@"server object:%@ [%d]", serverObject, [serverObject retainCount]); } } NSLog(@"...exiting server.", 1); [serverObject release]; [mainPool release]; return 0; } gnustep-Zillion-0.1/zillionClient.m000064400000000000000000000045071231046310600174520ustar00rootroot00000000000000/* zillionClient.m Mon Dec 9 16:13:27 CET 2002 */ #import "ZillionClient.h" #import "ZillionServer.h" #import "NSProcessInfo+getopt.h" #define CONNECTION_RETRIES 10 #define SLEEP_INTERVAL 60 int main(int argc, const char **argv) { NSAutoreleasePool *mainPool = [[NSAutoreleasePool alloc] init]; NSConnection *theConnection; id server; ZillionClient *client; NSDate *distantFuture = [NSDate distantFuture]; NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop]; NSProcessInfo *proc = [NSProcessInfo processInfo]; NSDictionary *options = [proc getOptionsFromSpecification: [NSArray arrayWithObjects:@"DOname=s", @"doRespawn", nil] defaults:[NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:1], @"doRespawn", nil] ]; BOOL doRespawn = [[options objectForKey:@"doRespawn"] intValue]; NSString *DOname = [options objectForKey:@"DOname"]; int i; NSLog(@"Starting client [respawning:%@]...", doRespawn? @"YES": @"NO"); for (i = 0; i < CONNECTION_RETRIES; i++) { if (i) { NSLog(@"Sleeping..."); [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:SLEEP_INTERVAL]]; NSLog(@"Retrying..."); } server = [[NSConnection rootProxyForConnectionWithRegisteredName:ZILLION_SERVER_NAME host:nil] retain]; if (server) break; NSLog(@"Couldn't connect to server..."); } if (!server) { NSLog(@"Failed to establish connection after %d retries. Exiting.", CONNECTION_RETRIES); [mainPool release]; return 1; } [server setProtocolForProxy:@protocol(ZillionServerProtocol)]; client = [[ZillionClient alloc] initWithRespawnStatus:doRespawn andMasterServer:server]; // if DOname is set we register with that name to await // contacts from outside if (DOname) { NSLog(@"Registering proxy client with DO name: %@", DOname); theConnection = [NSConnection defaultConnection]; [theConnection setRootObject:client]; if ([theConnection registerName:DOname] == NO) { NSLog(@"Could not register name with PortName server"); } } else { [server registerClient:client]; NSLog(@"registered client..."); } while (![client clientToGoDown]) { [currentRunLoop acceptInputForMode:NSDefaultRunLoopMode beforeDate:distantFuture]; } NSLog(@"going down on client..."); [server deregisterClient:client]; [client release]; [server release]; [mainPool release]; return 0; } gnustep-Zillion-0.1/zillionLoader.m000064400000000000000000000023311231046310600174330ustar00rootroot00000000000000/* zillionLoader.m Mon Dec 9 18:35:36 CET 2002 */ #import "ZillionClient.h" #import "ZillionServer.h" #import "NSFileManager+directories.h" int main(int argc, const char **argv) { NSAutoreleasePool *mainPool = [[NSAutoreleasePool alloc] init]; id server; NSProcessInfo *pInfo = [NSProcessInfo processInfo]; NSLog(@"Loading job into Zillion..."); server = [[NSConnection rootProxyForConnectionWithRegisteredName:ZILLION_SERVER_NAME host:nil] retain]; [server setProtocolForProxy:@protocol(ZillionServerProtocol)]; if ([[pInfo arguments] count] < 2) { NSLog(@"USAGE: %@ bundlePath1 [bundlePath2]+", [pInfo processName]); } else { int i, count; NSFileManager *fileManager = [NSFileManager defaultManager]; NSData *bundle; for (i = 1, count = [[pInfo arguments] count]; i < count; i++) { NSString *thisJob = [[pInfo arguments] objectAtIndex:i]; NSLog(@"...identified %@", thisJob); NSLog(@"loading..."); bundle = [fileManager dataRepresentationAtPath:thisJob]; NSLog(@"dispatching..."); [server dispatchJob:bundle]; NSLog(@"..now %@ is running.", thisJob); } } [server release]; [mainPool release]; return 0; } // [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];