mirror of
https://github.com/gnustep/libs-ec.git
synced 2025-02-16 00:21:01 +00:00
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:
parent
fc3dcb37b4
commit
6d73abdd40
5 changed files with 63 additions and 44 deletions
14
ChangeLog
14
ChangeLog
|
@ -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:
|
||||
|
|
25
EcCommand.m
25
EcCommand.m
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
62
EcProcess.m
62
EcProcess.m
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue