update to use alarms

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/ec/trunk@37357 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2013-11-04 07:28:57 +00:00
parent 525c759793
commit e485c10fac
6 changed files with 168 additions and 48 deletions

View file

@ -1,3 +1,12 @@
2013-11-04 Richard Frith-Macdonald <rfm@gnu.org>
* EcProcess.m:
* EcCommand.m:
* EcClientI.h:
* EcClientI.m:
* EcAlarmDestination.h:
Change error/alert logs to use alarm mechanism instead.
2013-08-20 Richard Frith-Macdonald <rfm@gnu.org> 2013-08-20 Richard Frith-Macdonald <rfm@gnu.org>
* EcConsole.m: Ignore exception printing message on shutdown. * EcConsole.m: Ignore exception printing message on shutdown.

View file

@ -194,7 +194,7 @@
@end @end
/** Methods called internally to forward events to the remote target of /** Methods called internally to forward events to the remote target of
* the receiver. These are provided for subclasses to oveerride. * the receiver. These are provided for subclasses to override.
*/ */
@interface EcAlarmDestination (Forwarding) @interface EcAlarmDestination (Forwarding)
/** Forward an alarm event. */ /** Forward an alarm event. */

View file

@ -47,9 +47,9 @@
unsigned revSequence; /* Last gnip sent BY client. */ unsigned revSequence; /* Last gnip sent BY client. */
NSMutableSet *files; /* Want update info for these. */ NSMutableSet *files; /* Want update info for these. */
NSData *config; /* Config info for client. */ NSData *config; /* Config info for client. */
BOOL pingOk; BOOL pingOk; /* Can remote end accept ping? */
BOOL transient; BOOL transient; /* Is this a transient client? */
BOOL unregistered; BOOL unregistered; /* Has client unregistered? */
} }
- (NSComparisonResult) compare: (EcClientI*)other; - (NSComparisonResult) compare: (EcClientI*)other;
- (NSData*) config; - (NSData*) config;

View file

@ -181,12 +181,12 @@
- (void) setTransient: (BOOL)flag - (void) setTransient: (BOOL)flag
{ {
transient = flag; transient = flag ? YES : NO;
} }
- (void) setUnregistered: (BOOL)flag - (void) setUnregistered: (BOOL)flag
{ {
unregistered = flag; unregistered = flag ? YES : NO;
} }
- (BOOL) transient - (BOOL) transient

View file

@ -159,11 +159,11 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
- (NSArray*) findAll: (NSArray*)a - (NSArray*) findAll: (NSArray*)a
byAbbreviation: (NSString*)s; byAbbreviation: (NSString*)s;
- (EcClientI*) findIn: (NSArray*)a - (EcClientI*) findIn: (NSArray*)a
byAbbreviation: (NSString*)s; byAbbreviation: (NSString*)s;
- (EcClientI*) findIn: (NSArray*)a - (EcClientI*) findIn: (NSArray*)a
byName: (NSString*)s; byName: (NSString*)s;
- (EcClientI*) findIn: (NSArray*)a - (EcClientI*) findIn: (NSArray*)a
byObject: (id)s; byObject: (id)s;
- (void) information: (NSString*)inf - (void) information: (NSString*)inf
from: (NSString*)s from: (NSString*)s
type: (EcLogType)t; type: (EcLogType)t;
@ -312,24 +312,66 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
{ {
NSMutableDictionary *m; NSMutableDictionary *m;
NSString *k; NSString *k;
NSString *err; NSString *err = nil;
m = [[d mutableCopy] autorelease]; m = [[d mutableCopy] autorelease];
d = m; d = m;
NS_DURING NS_DURING
[self cmdUpdate: m]; [self cmdUpdate: m];
NS_HANDLER NS_HANDLER
[self cmdError: @"Problem before updating config: %@", NSLog(@"Problem before updating config (in cmdUpdate:) %@",
localException]; localException);
NS_ENDHANDLER err = @"the -cmdUpdate: method raised an exception";
NS_DURING
err = [self cmdUpdated];
NS_HANDLER
err = [localException description];
NS_ENDHANDLER NS_ENDHANDLER
if (nil == err)
{
NS_DURING
err = [self cmdUpdated];
NS_HANDLER
NSLog(@"Problem after updating config (in cmdUpdated) %@",
localException);
err = @"the -cmdUpdated method raised an exception";
NS_ENDHANDLER
}
if ([err length] > 0) if ([err length] > 0)
{ {
[self cmdError: @"Problem after updating config: %@", err]; EcAlarm *a;
/* Truncate additional text to fit if necessary.
*/
err = [err stringByTrimmingSpaces];
if ([err length] > 255)
{
err = [err substringToIndex: 255];
while (255 < strlen([err UTF8String]))
{
err = [err substringToIndex: [err length] - 1];
}
}
a = [EcAlarm alarmForManagedObject: nil
at: nil
withEventType: EcAlarmEventTypeProcessingError
probableCause: EcAlarmConfigurationOrCustomizationError
specificProblem: @"configuration error"
perceivedSeverity: EcAlarmSeverityMajor
proposedRepairAction:
_(@"Correct config or software (check log for details).")
additionalText: err];
[self alarm: a];
}
else
{
EcAlarm *a;
a = [EcAlarm alarmForManagedObject: nil
at: nil
withEventType: EcAlarmEventTypeProcessingError
probableCause: EcAlarmConfigurationOrCustomizationError
specificProblem: @"configuration error"
perceivedSeverity: EcAlarmSeverityCleared
proposedRepairAction: nil
additionalText: nil];
[self alarm: a];
} }
launchInfo = [d objectForKey: @"Launch"]; launchInfo = [d objectForKey: @"Launch"];
@ -557,8 +599,7 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
sequence: (unsigned)num sequence: (unsigned)num
extra: (NSData*)data extra: (NSData*)data
{ {
/* /* Send back a response to let the other party know we are alive.
* Just send back a response to let the other party know we are alive.
*/ */
[from cmdGnip: self sequence: num extra: nil]; [from cmdGnip: self sequence: num extra: nil];
} }
@ -1400,7 +1441,7 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
} }
- (EcClientI*) findIn: (NSArray*)a - (EcClientI*) findIn: (NSArray*)a
byAbbreviation: (NSString*)s byAbbreviation: (NSString*)s
{ {
EcClientI *o; EcClientI *o;
int i; int i;
@ -1458,7 +1499,7 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
} }
- (EcClientI*) findIn: (NSArray*)a - (EcClientI*) findIn: (NSArray*)a
byObject: (id)s byObject: (id)s
{ {
EcClientI *o; EcClientI *o;
int i; int i;
@ -2471,11 +2512,11 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
{ {
NSString *m; NSString *m;
m = [NSString stringWithFormat: cmdLogFormat(LT_ALERT, m = [NSString stringWithFormat: cmdLogFormat(LT_AUDIT,
@"Client '%@' failed to respond for over %d seconds"), @"Client '%@' failed to respond for over %d seconds"),
[r name], (int)pingDelay]; [r name], (int)pingDelay];
[[[[r obj] connectionForProxy] sendPort] invalidate]; [[[[r obj] connectionForProxy] sendPort] invalidate];
[self information: m from: nil to: nil type: LT_ALERT]; [self information: m from: nil to: nil type: LT_AUDIT];
lost = YES; lost = YES;
} }
} }
@ -2484,11 +2525,11 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
{ {
NSString *m; NSString *m;
m = [NSString stringWithFormat: cmdLogFormat(LT_ALERT, m = [NSString stringWithFormat: cmdLogFormat(LT_AUDIT,
@"Control server failed to respond for over %d seconds"), @"Control server failed to respond for over %d seconds"),
(int)pingDelay]; (int)pingDelay];
[[(NSDistantObject*)control connectionForProxy] invalidate]; [[(NSDistantObject*)control connectionForProxy] invalidate];
[self information: m from: nil to: nil type: LT_ALERT]; [self information: m from: nil to: nil type: LT_AUDIT];
lost = YES; lost = YES;
} }
if (lost == YES) if (lost == YES)
@ -2501,13 +2542,14 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
* than one per 4 timeouts. * than one per 4 timeouts.
*/ */
count = [clients count]; count = [clients count];
pingPosition++;
if (pingPosition >= 4 && pingPosition >= count) if (pingPosition >= 4 && pingPosition >= count)
{ {
pingPosition = 0; pingPosition = 0;
} }
if (pingPosition < count) if (pingPosition < count)
{ {
[[clients objectAtIndex: pingPosition++] ping]; [[clients objectAtIndex: pingPosition] ping];
} }
// Ping the control server too - once every four times. // Ping the control server too - once every four times.
pingControlCount++; pingControlCount++;

View file

@ -1002,6 +1002,41 @@ findMode(NSDictionary* d, NSString* s)
} }
} }
- (void) _commandRemove
{
id connection = [cmdServer connectionForProxy];
if (nil != connection)
{
[connection setDelegate: nil];
[[NSNotificationCenter defaultCenter]
removeObserver: self
name: NSConnectionDidDieNotification
object: connection];
[connection invalidate];
}
DESTROY(cmdServer);
}
- (void) _connectionRegistered
{
EcAlarm *a;
a = [EcAlarm alarmForManagedObject: nil
at: nil
withEventType: EcAlarmEventTypeProcessingError
probableCause: EcAlarmSoftwareProgramAbnormallyTerminated
specificProblem: @"unable to register"
perceivedSeverity: EcAlarmSeverityCleared
proposedRepairAction: nil
additionalText: nil];
/* This alarm will usually have been raised by another process,
* so we can't clear it as we have no alarm to match.
* To work around this, we forward the clear directly.
*/
[alarmDestination alarmFwd: a];
}
static NSString *noFiles = @"No log files to archive"; static NSString *noFiles = @"No log files to archive";
- (id) cmdConfig: (NSString*)key - (id) cmdConfig: (NSString*)key
@ -1629,6 +1664,7 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
id connection; id connection;
connection = [notification object]; connection = [notification object];
[connection setDelegate: nil];
[[NSNotificationCenter defaultCenter] [[NSNotificationCenter defaultCenter]
removeObserver: self removeObserver: self
name: NSConnectionDidDieNotification name: NSConnectionDidDieNotification
@ -1655,7 +1691,7 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
} }
else else
{ {
NSLog(@"unknown-Connection sent invalidation\n"); NSLog(@"unknown connection sent invalidation\n");
} }
return self; return self;
} }
@ -1970,6 +2006,16 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
name: NSConnectionDidDieNotification name: NSConnectionDidDieNotification
object: connection]; object: connection];
[self _update: r]; [self _update: r];
/* If we just connected to the command server,
* and we have a registered connection, then we
* can tell it that any alarm for failure to
* register must be cleared.
*/
if (nil != cmdServer && [EcProcConnection isValid])
{
[self _connectionRegistered];
}
} }
} }
} }
@ -1994,12 +2040,12 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
} }
NS_HANDLER NS_HANDLER
{ {
DESTROY(cmdServer); [self _commandRemove];
NSLog(@"Caught exception unregistering from Command: %@", NSLog(@"Caught exception unregistering from Command: %@",
localException); localException);
} }
NS_ENDHANDLER NS_ENDHANDLER
DESTROY(cmdServer); [self _commandRemove];
} }
} }
@ -2239,8 +2285,23 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
if ([c registerName: [self cmdName] if ([c registerName: [self cmdName]
withNameServer: [NSSocketPortNameServer sharedInstance]] == NO) withNameServer: [NSSocketPortNameServer sharedInstance]] == NO)
{ {
EcAlarm *a;
DESTROY(c); DESTROY(c);
[self cmdError: @"Unable to register with name server."]; NSLog(@"Unable to register with name server. Perhaps a copy of this process is already running (or is hung or blocked waiting for a database query etc), or perhaps an old version was killed and is still registered. Check the state of any running process and and check the process registration with gdomap.");
a = [EcAlarm alarmForManagedObject: nil
at: nil
withEventType: EcAlarmEventTypeProcessingError
probableCause: EcAlarmSoftwareProgramAbnormallyTerminated
specificProblem: @"unable to register"
perceivedSeverity: EcAlarmSeverityMajor
proposedRepairAction:
_(@"Check for running copy of process and/or registration in gdomap.")
additionalText: _(@"Process probably already running (possibly hung/delayed) or problem in name registration with distributed objects system (gdomap)")];
[self alarm: a];
[alarmDestination shutdown];
cmdIsQuitting = YES;
[self cmdFlushLogs]; [self cmdFlushLogs];
[arp release]; [arp release];
return 2; return 2;
@ -2254,6 +2315,8 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
object: c]; object: c];
EcProcConnection = c; EcProcConnection = c;
[self _connectionRegistered];
[self cmdAudit: @"Started `%@'", [self cmdName]]; [self cmdAudit: @"Started `%@'", [self cmdName]];
loop = [NSRunLoop currentRunLoop]; loop = [NSRunLoop currentRunLoop];
@ -2503,7 +2566,7 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
} }
NS_HANDLER NS_HANDLER
{ {
cmdServer = nil; [self _commandRemove];
NSLog(@"Caught exception sending client reply to Command: %@ %@", NSLog(@"Caught exception sending client reply to Command: %@ %@",
name, localException); name, localException);
} }
@ -3628,14 +3691,6 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
[[NSProcessInfo processInfo] setProcessName: cmdName]; [[NSProcessInfo processInfo] setProcessName: cmdName];
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(cmdDefaultsChanged:)
name: NSUserDefaultsDidChangeNotification
object: [NSUserDefaults standardUserDefaults]];
[self cmdDefaultsChanged: nil];
/* Archive any existing debug log left over by a crash. /* Archive any existing debug log left over by a crash.
*/ */
str = [cmdName stringByAppendingPathExtension: @"debug"]; str = [cmdName stringByAppendingPathExtension: @"debug"];
@ -3657,8 +3712,16 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
} }
} }
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(cmdDefaultsChanged:)
name: NSUserDefaultsDidChangeNotification
object: [NSUserDefaults standardUserDefaults]];
[self cmdMesgCache]; [self cmdMesgCache];
[self cmdDefaultsChanged: nil];
cmdIsTransient = [cmdDefs boolForKey: @"Transient"]; cmdIsTransient = [cmdDefs boolForKey: @"Transient"];
if ([cmdDefs objectForKey: @"CmdInterval"] != nil) if ([cmdDefs objectForKey: @"CmdInterval"] != nil)
@ -4151,19 +4214,25 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
if (nil == cmdConf || [cmdConf isEqual: newConfig] == NO) if (nil == cmdConf || [cmdConf isEqual: newConfig] == NO)
{ {
NSString *err; NSString *err = nil;
NS_DURING NS_DURING
[self cmdUpdate: newConfig]; [self cmdUpdate: newConfig];
NS_HANDLER NS_HANDLER
[self cmdError: @"Problem before updating config: %@", localException]; NSLog(@"Problem before updating config (in cmdUpdate:) %@",
NS_ENDHANDLER localException);
NS_DURING err = @"the -cmdUpdate: method raised an exception";
err = [self cmdUpdated];
NS_HANDLER
err = nil;
[self cmdError: @"Problem after updating config: %@", localException];
NS_ENDHANDLER NS_ENDHANDLER
if (nil == err)
{
NS_DURING
err = [self cmdUpdated];
NS_HANDLER
NSLog(@"Problem after updating config (in cmdUpdated) %@",
localException);
err = @"the -cmdUpdated method raised an exception";
NS_ENDHANDLER
}
if ([err length] > 0) if ([err length] > 0)
{ {
EcAlarm *a; EcAlarm *a;