attempt to make restart of a process more reliable in the case where it stopped

responding to the Command server for a while.
This commit is contained in:
Richard Frith-Macdonald 2020-04-04 11:03:26 +01:00
parent fc3dcb37b4
commit 6d73abdd40
5 changed files with 63 additions and 44 deletions

View file

@ -1,3 +1,17 @@
2020-04-02 Richard Frith-Macdonald <rfm@gnu.org>
* EcCommand.m:
* EcLogger.m:
* EcProcess.h:
* EcProcess.m:
Remove obsolete methods for registration/unregistration. Change code
to refrain from registering with Command server if in the process of
shutting down, and to refrain from attempting an unregistration if
not already registered. The hope is that this will prevent a race
condition where loss of connection to the Command server can cause a
shutdown and re-register during the shutdown fooling the Command
server into thinking the process is still running.
2020-03-23 Richard Frith-Macdonald <rfm@gnu.org>
* EcProcess.h:

View file

@ -549,8 +549,6 @@ static NSMutableDictionary *launchInfo = nil;
- (void) quitAll: (NSDate*)by;
- (void) reLaunch: (NSTimer*)t;
- (void) requestConfigFor: (id<CmdConfig>)c;
- (NSData*) registerClient: (id<CmdClient>)c
name: (NSString*)n;
- (NSData*) registerClient: (id<CmdClient>)c
name: (NSString*)n
transient: (BOOL)t;
@ -563,7 +561,6 @@ static NSMutableDictionary *launchInfo = nil;
- (void) _tryLaunch: (NSTimer*)t;
- (void) tryLaunchSoon;
- (void) unregisterByObject: (id)obj;
- (void) unregisterByName: (NSString*)n;
- (void) unregisterClient: (EcClientI*)o gracefully: (BOOL)clean;
- (void) update;
- (void) updateConfig: (NSData*)data;
@ -2947,12 +2944,6 @@ NSLog(@"Problem %@", localException);
}
}
- (NSData*) registerClient: (id<CmdClient>)c
name: (NSString*)n
{
return [self registerClient: c name: n transient: NO];
}
- (NSData*) registerClient: (id<CmdClient>)c
name: (NSString*)n
transient: (BOOL)t
@ -3032,6 +3023,10 @@ NSLog(@"Problem %@", localException);
}
else
{
/* Rejecting means the client is not registered (and therefore should
* not be told to quit when the objct is deallocated.
*/
[obj setUnregistered: YES];
RELEASE(obj);
m = [NSString stringWithFormat:
@"%@ rejected new server with name '%@' on %@\n",
@ -4024,14 +4019,10 @@ NSLog(@"Problem %@", localException);
{
EcClientI *o = [self findIn: clients byObject: obj];
[self unregisterClient: o gracefully: YES];
}
- (void) unregisterByName: (NSString*)n
{
EcClientI *o = [self findIn: clients byName: n];
[self unregisterClient: o gracefully: YES];
if (o != nil)
{
[self unregisterClient: o gracefully: YES];
}
}
- (void) update

View file

@ -147,7 +147,7 @@ static NSArray *modes;
id<CmdLogger> server;
server = (id<CmdLogger>)[EcProc server: name];
[server registerClient: self name: cmdLogName()];
[server registerClient: self name: cmdLogName() transient: NO];
}
/* Should only be called on main thread, but doesn't matter.

View file

@ -157,9 +157,9 @@ typedef enum {
type: (EcLogType)t
for: (id)o;
- (bycopy NSData*) registerClient: (id)c
name: (NSString*)n;
name: (NSString*)n
transient: (BOOL)t;
- (void) unregisterByObject: (id)obj;
- (void) unregisterByName: (NSString*)n;
@end
@protocol Console <NSObject>

View file

@ -241,6 +241,7 @@ static BOOL configInProgress = NO;
static BOOL cmdFlagDaemon = NO;
static BOOL cmdFlagTesting = NO;
static BOOL cmdIsRunning = NO;
static BOOL cmdIsRegistered = NO;
static BOOL cmdKeepStderr = NO;
static BOOL cmdKillDebug = NO;
static NSString *cmdBase = nil;
@ -1966,10 +1967,12 @@ findMode(NSDictionary* d, NSString* s)
[connection invalidate];
}
DESTROY(cmdServer);
cmdIsRegistered = NO;
}
- (void) _connectionRegistered
{
cmdIsRegistered = YES;
[alarmDestination domanage: nil];
}
@ -3411,6 +3414,29 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
rootProxyForConnectionWithRegisteredName: name
host: host
usingNameServer: ns];
[proxy setProtocolForProxy: @protocol(Command)];
if (nil == proxy)
{
NSLog(@"Unable to connect to Command server");
}
else
{
NSConnection *connection;
ASSIGN(cmdServer, proxy);
connection = [cmdServer connectionForProxy];
[connection enableMultipleThreads];
if (nil == alarmDestination)
{
alarmDestination = [EcAlarmDestination new];
}
[[self ecAlarmDestination] setDestination: cmdServer];
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(cmdConnectionBecameInvalid:)
name: NSConnectionDidDieNotification
object: connection];
}
}
NS_HANDLER
{
@ -3420,12 +3446,15 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
}
NS_ENDHANDLER
if (proxy != nil)
/* We only register and fetch new configuration information
* if we are NOT in the process of shutting down: a process
* which is shutting down should only use the Command server
* for logging/alerting purposes.
*/
if (proxy != nil && 0.0 == beganQuitting)
{
NSMutableDictionary *r = nil;
[proxy setProtocolForProxy: @protocol(Command)];
NS_DURING
{
NSData *d;
@ -3466,26 +3495,11 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
}
else if ([r objectForKey: @"back-off"] != nil)
{
NSLog(@"Unable to connect to Command server ..."
NSLog(@"Unable to register with Command server ..."
@" back-off");
}
else
{
NSConnection *connection;
cmdServer = [proxy retain];
connection = [cmdServer connectionForProxy];
[connection enableMultipleThreads];
if (nil == alarmDestination)
{
alarmDestination = [EcAlarmDestination new];
}
[[self ecAlarmDestination] setDestination: cmdServer];
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(cmdConnectionBecameInvalid:)
name: NSConnectionDidDieNotification
object: connection];
[self _update: r];
/* If we just connected to the command server,
@ -3499,10 +3513,6 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
}
}
}
else
{
NSLog(@"Unable to connect to Command server ... not found");
}
}
connecting = NO;
if (nil == cmdLast && nil == cmdServer && YES == [self cmdIsClient])
@ -3532,7 +3542,11 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
{
NS_DURING
{
[cmdServer unregisterByObject: self];
if (cmdIsRegistered)
{
cmdIsRegistered = NO;
[cmdServer unregisterByObject: self];
}
}
NS_HANDLER
{