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>
EcProcess.h: Improve comments.
EcProcess.m: Avoid warning about unknown connection on shutdown.
Rewrite config update code to catch exceptions, ensure that methods
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;
/** 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
* receiver was initialised).
*/

View file

@ -1104,6 +1104,7 @@ findMode(NSDictionary* d, NSString* s)
@interface EcProcess (Private)
- (void) cmdMesgrelease: (NSArray*)msg;
- (void) cmdMesgrestart: (NSArray*)msg;
- (void) cmdMesgtesting: (NSArray*)msg;
- (void) _memCheck;
- (NSString*) _moveLog: (NSString*)name to: (NSDate*)when;
@ -1916,7 +1917,7 @@ static BOOL ecDidAwaken = NO;
return ecIsQuitting();
}
- (oneway void) ecQuitFor: (NSString*) reason with: (NSInteger)status
- (oneway void) ecQuitFor: (NSString*)reason with: (NSInteger)status
{
[self ecWillQuit: reason];
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
{
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
{
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,
* 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 (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;
}