Add restart functionality

This commit is contained in:
Richard Frith-Macdonald 2018-01-05 09:47:26 +00:00
parent fd43457c20
commit 7c54120ae0
3 changed files with 69 additions and 4 deletions

View file

@ -1,5 +1,15 @@
2018-01-05 Richard Frith-Macdonald <rfm@gnu.org>
EcProcess.h:
EcProcess.m: New -ecRestart: method called when we pass the maximum
memory usage limit or when a restart command is issued. The default
implementation calls the -ecQuitFor:status: method using a status of
minus one so that the Command server will restart the program after
it shuts down.
2018-01-04 Richard Frith-Macdonald <rfm@gnu.org> 2018-01-04 Richard Frith-Macdonald <rfm@gnu.org>
EcProcess.h: Improve comments.
EcProcess.m: Avoid warning about unknown connection on shutdown. EcProcess.m: Avoid warning about unknown connection on shutdown.
Rewrite config update code to catch exceptions, ensure that methods Rewrite config update code to catch exceptions, ensure that methods
are called in the correct order so that -cmdUpdated is always last, are called in the correct order so that -cmdUpdated is always last,

View file

@ -540,6 +540,17 @@ extern NSString* cmdVersion(NSString *ver);
*/ */
- (oneway void) ecQuitFor: (NSString*)reason with: (NSInteger)status; - (oneway void) ecQuitFor: (NSString*)reason with: (NSInteger)status;
/** This method is designed for handling an orderly restart.<br />
* The default implementation calls -ecQuitFor:status: with minus one as
* the status code so that the Command server will start the process
* again.<br />
* The method is called automatically when the MemoryMaximum limit is
* exceeded (to gracefully handle memory leaks by restarting).<br />
* Subclasses may override this method to allow the shutdown process to be
* handled differently.
*/
- (oneway void) ecRestart: (NSString*)reason;
/** Return the timestamp at which this process started up (when the /** Return the timestamp at which this process started up (when the
* receiver was initialised). * receiver was initialised).
*/ */

View file

@ -1104,6 +1104,7 @@ findMode(NSDictionary* d, NSString* s)
@interface EcProcess (Private) @interface EcProcess (Private)
- (void) cmdMesgrelease: (NSArray*)msg; - (void) cmdMesgrelease: (NSArray*)msg;
- (void) cmdMesgrestart: (NSArray*)msg;
- (void) cmdMesgtesting: (NSArray*)msg; - (void) cmdMesgtesting: (NSArray*)msg;
- (void) _memCheck; - (void) _memCheck;
- (NSString*) _moveLog: (NSString*)name to: (NSDate*)when; - (NSString*) _moveLog: (NSString*)name to: (NSDate*)when;
@ -1916,7 +1917,7 @@ static BOOL ecDidAwaken = NO;
return ecIsQuitting(); return ecIsQuitting();
} }
- (oneway void) ecQuitFor: (NSString*) reason with: (NSInteger)status - (oneway void) ecQuitFor: (NSString*)reason with: (NSInteger)status
{ {
[self ecWillQuit: reason]; [self ecWillQuit: reason];
if (class_getMethodImplementation([EcProcess class], @selector(cmdQuit:)) if (class_getMethodImplementation([EcProcess class], @selector(cmdQuit:))
@ -1936,6 +1937,18 @@ static BOOL ecDidAwaken = NO;
} }
} }
- (oneway void) ecRestart: (NSString*)reason
{
if (NO == [NSThread isMainThread])
{
[self performSelectorOnMainThread: _cmd
withObject: reason
waitUntilDone: NO];
return;
}
[self ecQuitFor: reason with: -1];
}
- (void) ecLoggersChanged: (NSNotification*)n - (void) ecLoggersChanged: (NSNotification*)n
{ {
DESTROY(alertLogger); DESTROY(alertLogger);
@ -4789,6 +4802,34 @@ With two parameters ('maximum' and a number),\n\
} }
} }
- (void) cmdMesgrestart: (NSArray*)msg
{
if ([msg count] == 0)
{
[self cmdPrintf: @"requests a restart"];
}
else
{
if ([[msg objectAtIndex: 0] caseInsensitiveCompare: @"help"]
== NSOrderedSame)
{
[self cmdPrintf: @"\nThe restart command is used to request a"];
[self cmdPrintf: @" restart of the process.\n"];
[self cmdPrintf: @"This is like quitting the process but with"];
[self cmdPrintf: @" a new process started by the Command\n"];
[self cmdPrintf: @" server and potentially different shutdown"];
[self cmdPrintf: @" behavior.\n"];
}
else
{
[self performSelectorOnMainThread: @selector(ecRestart:)
withObject: @"Console restart command"
waitUntilDone: NO];
[self cmdPrintf: @"A restart is being requested.\n"];
}
}
}
- (void) cmdMesgtesting: (NSArray*)msg - (void) cmdMesgtesting: (NSArray*)msg
{ {
if ([msg count] == 0) if ([msg count] == 0)
@ -4968,13 +5009,16 @@ With two parameters ('maximum' and a number),\n\
} }
/* If we have a defined maximum memory usage for the process, /* If we have a defined maximum memory usage for the process,
* we should shut down with a non-zero status to get a restart. * we should perform a restart once that limit is passed.
*/ */
if (memMaximum > 0 && memPeak > (memMaximum * 1024 * 1024)) if (memMaximum > 0 && memPeak > (memMaximum * 1024 * 1024))
{ {
if (NO == ecIsQuitting()) static BOOL memRestart = NO;
if (NO == memRestart)
{ {
[self ecQuitFor: @"memory usage limit reached" with: -1]; memRestart = YES;
[self ecRestart: @"memory usage limit reached"];
} }
return; return;
} }