Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37569059
en ru br
Репозитории ALT

Группа :: Графические оболочки/GNUstep
Пакет: gnustep-Zillion

 Главная   Изменения   Спек   Патчи   Исходники   Загрузить   Gear   Bugs and FR  Repocop 

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 <Foundation/Foundation.h>

@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 <Foundation/Foundation.h>

@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];
// <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 <Foundation/Foundation.h>
#import "ZillionClientServer.h"

@protocol ZillionClientProtocol <NSObject>

- initWithRespawnStatus:(BOOL)respawnStatus andMasterServer:(id <ZillionServerProtocol>)masterServer;
- (id <ZillionClientProtocol>)masterClient;
- (void)setMasterClient:(id <ZillionClientProtocol>)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 <ZillionClientProtocol>
{
BOOL _clientToGoDown;
BOOL _respawnStatus;

NSLock *clientAdminLock;
NSMutableDictionary *jobClientDictionary;
NSMutableDictionary *threads;
NSDictionary *_attributes;
int load;

id <ZillionClientProtocol> _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 <ZillionServerProtocol>)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 <ZillionClientProtocol>)masterClient { return _masterClient; }
- (void)setMasterClient:(id <ZillionClientProtocol>)masterClient {
[masterClient retain];
[_masterClient release];
_masterClient = masterClient;
}

- (NSString *)clientId { return [self DOname]; }
- (BOOL)clientToGoDown { return _clientToGoDown; }
- (void)terminate {
NSEnumerator *clientEnum;
id <ZillionClientProtocol> client;

for (clientEnum = [jobClientDictionary objectEnumerator]; (client = [clientEnum nextObject]); )
if (client != self) [client terminate];

_clientToGoDown = YES;
}

- (NSDictionary *)attributes {
return _attributes;
}


- (id <ZillionClientProtocol>)clientForJob:(NSString *)jobId
{
id <ZillionClientProtocol> 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 <ZillionJobProtocol> 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 <ZillionJobProtocol> 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 <ZillionClientProtocol> 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];

// <i> 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
{
//<i> 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 <Foundation/Foundation.h>

/*
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 <ZillionServerProtocol> _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 <ZillionJobProtocol>)instantiateJobFromBundle:(NSBundle *)jobBundle;
- (id <ZillionJobProtocol>)instantiateJobWithId:(NSString *)jobId;
- (Class)jobClassForJobId:(NSString *)jobId;

/*
common administrative methods
*/
- (void)setMasterServer:(id <ZillionServerProtocol>)masterServer;
- (id <ZillionServerProtocol>)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 <ZillionJobProtocol>)instantiateJobFromBundle:(NSBundle *)jobBundle
{
Class jobClass = [jobBundle principalClass];
NSString *jobId = [jobClass jobId];
NSMutableDictionary *jobSpec;
id <ZillionJobProtocol> 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 <ZillionJobProtocol>)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 <ZillionServerProtocol>)masterServer {
# ifndef _DO_TEST_CASE
return;
# else
[masterServer retain];
[_masterServer release];
_masterServer = masterServer;
# endif
}

- (id <ZillionServerProtocol>)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 <Foundation/Foundation.h>
#import "ZillionClientServer.h"
#import "ZillionClient.h"

#define ZILLION_SERVER_NAME @"zillion"

@protocol ZillionClientProtocol;
@protocol ZillionServerProtocol;
@protocol ZillionJobProtocol;

@protocol ZillionServerProtocol <NSObject>

/*
managing masters
*/
- (void)setMasterServer:(id <ZillionServerProtocol>)masterServer;
- (id <ZillionServerProtocol>)masterServer;
- (void)terminate;

/*
managing clients
*/
- (void)registerClient:(id <ZillionClientProtocol>)someClient;
- (void)deregisterClient:(id <ZillionClientProtocol>)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 <NSObject>

+ (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 <ZillionClientProtocol>)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 <ZillionServerProtocol>)aServer;
+ (void)sealJobOutcomesUsingServer:(id <ZillionServerProtocol>)aServer;

@end

@interface ZillionServer : ZillionClientServer <ZillionServerProtocol>
{

NSMutableDictionary *proxyServers;
unsigned proxyServerIdCounter;

NSMutableDictionary *clients;
NSMutableDictionary *dispatchedSeeds;
NSMutableDictionary *outcomes;

BOOL _serverToGoDown;
BOOL _respawnStatus;
BOOL _reschedulingIsMarked;
}

- initWithRespawnStatus:(BOOL)respawnStatus;
- (BOOL)serverToGoDown;

- (id <ZillionJobProtocol>)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 <t>
[self deregisterClient:[[notification object] rootObject]];
}

- (void)registerClient:(id <ZillionClientProtocol>)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 <i>
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(clientConnectionDidDie:)
name:NSConnectionDidDieNotification
object:[(NSDistantObject *)someClient connectionForProxy]];

NSLog(@"Registered client:%@", someClient);
RESCHEDULE();
}

- (void)deregisterClient:(id <ZillionClientProtocol>)someClient
{
[clients removeObjectForKey:[someClient clientId]];
RESCHEDULE();
}

- (id <ZillionServerProtocol>)serverForJobId:(NSString *)jobId {
return [proxyServers objectForKey:jobId];
}


- (void)respawnedConnectionDidDie:(NSNotification *)notification
{
NSLog(@"Some proxy went away");
}

- (NSString *)dispatchJob:(NSData *)bundle
{
id <ZillionServerProtocol> 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 <ZillionServerProtocol> 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 <ZillionServerProtocol> 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 <ZillionJobProtocol>)jobInstance:(NSString *)jobId
{
NSMutableDictionary *jobSpec = [self jobSpecificationForJobId:jobId];
id <ZillionJobProtocol> 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 <ZillionJobProtocol> 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 <ZillionServerProtocol> proxyServer = PROXYSERVER_FOR_JOBID(jobId);
[proxyServer submitOutcome:outcome ofJob:jobId forSeedId:seedId storeHints:someStoreHints];
} else {
id <ZillionJobProtocol> 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);
}

// <i> 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 <ZillionClientProtocol> 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 <ZillionServerProtocol> proxyServer;

for (i = 0, count = [jobIds count]; i < count; i++) {
jobId = [jobIds objectAtIndex:i];
penalty = JOBPenalty(jobId);
//<i> 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 <ZillionJobProtocol>

@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 <ZillionClientProtocol>)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 <ZillionServerProtocol>)aServer
{
NSLog(@"about to save outcome:%@", outcome);
[aServer setOutcome:outcome forSeedId:seedId andJobId:[[self class] jobId]];
}
+ (void)sealJobOutcomesUsingServer:(id <ZillionServerProtocol>)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 <Foundation/Foundation.h>
#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]];
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin