Skip to content

Commit

Permalink
re-implement restart R command using suspend and resume back-end
Browse files Browse the repository at this point in the history
  • Loading branch information
jjallaire committed Aug 20, 2012
1 parent 045f7d2 commit 8177a17
Show file tree
Hide file tree
Showing 22 changed files with 393 additions and 152 deletions.
9 changes: 8 additions & 1 deletion src/cpp/r/include/r/session/RSession.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,14 @@ void reportAndLogWarning(const std::string& warning);
// suspend/resume
bool isSuspendable(const std::string& prompt);
bool suspend(bool force);
void suspendForRestart();

struct RSuspendOptions
{
RSuspendOptions() : saveMinimal(false), saveWorkspace(false) {}
bool saveMinimal;
bool saveWorkspace;
};
void suspendForRestart(const RSuspendOptions& options);

// set save action
extern const int kSaveActionNoSave;
Expand Down
10 changes: 8 additions & 2 deletions src/cpp/r/session/RSearchPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void reportRestoreError(const std::string& context,
REprintf(report.c_str());
}

Error saveGlobalEnvironment(const FilePath& environmentFile)
Error saveGlobalEnvironmentToFile(const FilePath& environmentFile)
{
std::string envPath =
string_utils::utf8ToSystem(environmentFile.absolutePath());
Expand Down Expand Up @@ -220,7 +220,7 @@ Error save(const FilePath& statePath)
{
// save the global environment
FilePath environmentFile = statePath.complete(kEnvironmentFile);
Error error = saveGlobalEnvironment(environmentFile);
Error error = saveGlobalEnvironmentToFile(environmentFile);
if (error)
return error;

Expand Down Expand Up @@ -284,6 +284,12 @@ Error save(const FilePath& statePath)
}


Error saveGlobalEnvironment(const FilePath& statePath)
{
FilePath environmentFile = statePath.complete(kEnvironmentFile);
return saveGlobalEnvironmentToFile(environmentFile);
}

Error restore(const FilePath& statePath)
{
// restore global environment
Expand Down
1 change: 1 addition & 0 deletions src/cpp/r/session/RSearchPath.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace session {
namespace search_path {

core::Error save(const core::FilePath& statePath);
core::Error saveGlobalEnvironment(const core::FilePath& statePath);
core::Error restore(const core::FilePath& statePath);

} // namespace search_path
Expand Down
38 changes: 29 additions & 9 deletions src/cpp/r/session/RSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ void saveClientState(ClientStateCommitType commitType)



bool saveSessionState(const FilePath& suspendedSessionPath,
bool saveSessionState(const RSuspendOptions& options,
const FilePath& suspendedSessionPath,
bool disableSaveCompression)
{
// notify client of serialization status
Expand All @@ -192,9 +193,19 @@ bool saveSessionState(const FilePath& suspendedSessionPath,
r::exec::IgnoreInterruptsScope ignoreInterrupts;

// save
return r::session::state::save(suspendedSessionPath,
s_options.serverMode,
disableSaveCompression);
if (options.saveMinimal)
{
// save minimal
return r::session::state::saveMinimal(suspendedSessionPath,
options.saveWorkspace);

}
else
{
return r::session::state::save(suspendedSessionPath,
s_options.serverMode,
disableSaveCompression);
}
}

void deferredRestoreSuspendedSession(
Expand Down Expand Up @@ -1257,7 +1268,8 @@ bool isSuspendable(const std::string& currentPrompt)
}


bool suspend(const FilePath& suspendedSessionPath,
bool suspend(const RSuspendOptions& options,
const FilePath& suspendedSessionPath,
bool disableSaveCompression,
bool force)
{
Expand All @@ -1271,9 +1283,16 @@ bool suspend(const FilePath& suspendedSessionPath,
// commit all client state
saveClientState(ClientStateCommitAll);

// if we are saving minimal then clear the graphics device
if (options.saveMinimal)
{
r::session::graphics::display().clear();
}

// save the session state. errors are handled internally and reported
// directly to the end user and written to the server log.
bool suspend = saveSessionState(suspendedSessionPath,
bool suspend = saveSessionState(options,
suspendedSessionPath,
disableSaveCompression);

// if we failed to save the data and are being forced then warn user
Expand Down Expand Up @@ -1308,12 +1327,13 @@ bool suspend(const FilePath& suspendedSessionPath,

bool suspend(bool force)
{
return suspend(s_suspendedSessionPath, false, force);
return suspend(RSuspendOptions(), s_suspendedSessionPath, false, force);
}

void suspendForRestart()
void suspendForRestart(const RSuspendOptions& options)
{
suspend(RestartContext::createSessionStatePath(s_options.scopedScratchPath,
suspend(options,
RestartContext::createSessionStatePath(s_options.scopedScratchPath,
s_options.sessionPort),
true, // disable save compression
true); // force suspend
Expand Down
199 changes: 132 additions & 67 deletions src/cpp/r/session/RSessionState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const char * const kHistoryFile = "history";
const char * const kPlotsFile = "plots";
const char * const kPlotsDir = "plots_dir";
const char * const kSearchPath = "search_path";
const char * const kGlobalEnvironment = "global_environment";

// settings
const char * const kWorkingDirectory = "working_directory";
Expand Down Expand Up @@ -182,36 +183,98 @@ struct ErrorRecorder

std::string* pMessages_ ;
};

} // anonymous namespace


bool save(const FilePath& statePath,
bool serverMode,
bool disableSaveCompression)

void saveDevMode(Settings* pSettings)
{
// flag indicating whether we succeeded saving
bool saved = true;

// ensure the context exists (if we fail this is fatal)
// check if dev-mode is on -- if it is then note this and turn it off
// (so that at restore time we can explicitly re-enable it)
bool devModeOn = false;
Error error = r::exec::RFunction(".rs.devModeOn").call(&devModeOn);
if (error)
LOG_ERROR(error);
if (devModeOn)
{
// set devmode bit in suspended settings
pSettings->set(kDevModeOn, true);

// turn dev mode off -- this is important so that dev mode undoes
// its manipulations of the prompt and libpaths before they are saved
// suppress output to eliminate dev_mode OFF message
// ignore error on purpose -- will happen if devtools isn't intalled
r::session::utils::SuppressOutputInScope suppressOutput;
error = r::exec::RFunction("devtools:::dev_mode", false).call();
}

}

void initSaveContext(const FilePath& statePath,
Settings* pSettings,
bool* pSaved)
{
// ensure the context exists
Error error = statePath.ensureDirectory();
if (error)
{
reportError(kSaving, "creating directory", error, ERROR_LOCATION);
saved = false;
}

// init session settings (used below)
Settings settings ;
error = settings.initialize(statePath.complete(kSettingsFile));
*pSaved = false;
}

// init session settings
error = pSettings->initialize(statePath.complete(kSettingsFile));
if (error)
{
reportError(kSaving, kSettingsFile, error, ERROR_LOCATION);
saved = false;
*pSaved = false;
}
}

void saveWorkingContext(const FilePath& statePath,
Settings* pSettings,
bool* pSaved)
{
// save history
FilePath historyPath = statePath.complete(kHistoryFile);
Error error = consoleHistory().saveToFile(historyPath);
if (error)
{
reportError(kSaving, kHistoryFile, error, ERROR_LOCATION);
*pSaved = false;
}

// save client metrics
client_metrics::save(pSettings);

// save aliased path to current working directory
std::string workingDirectory = FilePath::createAliasedPath(
utils::safeCurrentPath(),
r::session::utils::userHomePath());
pSettings->set(kWorkingDirectory, workingDirectory);

// save console actions
FilePath consoleActionsPath = statePath.complete(kConsoleActionsFile);
error = consoleActions().saveToFile(consoleActionsPath);
if (error)
{
reportError(kSaving, kConsoleActionsFile, error, ERROR_LOCATION);
*pSaved = false;
}
}

} // anonymous namespace



bool save(const FilePath& statePath,
bool serverMode,
bool disableSaveCompression)
{
// initialize context
Settings settings;
bool saved = true;
initSaveContext(statePath, &settings, &saved);

// save environment variables
error = saveEnvironmentVars(statePath.complete(kEnvironmentVars));
Error error = saveEnvironmentVars(statePath.complete(kEnvironmentVars));
if (error)
{
reportError(kSaving, kEnvironmentVars, error, ERROR_LOCATION);
Expand Down Expand Up @@ -239,24 +302,10 @@ bool save(const FilePath& statePath,
}
}

// check if dev-mode is on -- if it is then note this and turn it off
// (so that at restore time we can explicitly re-enable it)
bool devModeOn = false;
error = r::exec::RFunction(".rs.devModeOn").call(&devModeOn);
if (error)
LOG_ERROR(error);
if (devModeOn)
{
// set devmode bit in suspended settings
settings.set(kDevModeOn, true);

// turn dev mode off -- this is important so that dev mode undoes
// its manipulations of the prompt and libpaths before they are saved
// suppress output to eliminate dev_mode OFF message
// ignore error on purpose -- will happen if devtools isn't intalled
r::session::utils::SuppressOutputInScope suppressOutput;
error = r::exec::RFunction("devtools:::dev_mode", false).call();
}
// handle dev mode -- note that this MUST be executed before
// save libpaths and save options because it manipulates them
// (by disabling devmode)
saveDevMode(&settings);

// save libpaths
error = saveLibPaths(statePath.complete(kLibPathsFile));
Expand All @@ -274,32 +323,8 @@ bool save(const FilePath& statePath,
saved = false;
}

// save history
FilePath historyPath = statePath.complete(kHistoryFile);
error = consoleHistory().saveToFile(historyPath);
if (error)
{
reportError(kSaving, kHistoryFile, error, ERROR_LOCATION);
saved = false;
}

// save client metrics
client_metrics::save(&settings);

// save aliased path to current working directory
std::string workingDirectory = FilePath::createAliasedPath(
utils::safeCurrentPath(),
r::session::utils::userHomePath());
settings.set(kWorkingDirectory, workingDirectory);

// save console actions
FilePath consoleActionsPath = statePath.complete(kConsoleActionsFile);
error = consoleActions().saveToFile(consoleActionsPath);
if (error)
{
reportError(kSaving, kConsoleActionsFile, error, ERROR_LOCATION);
saved = false;
}
// save working context
saveWorkingContext(statePath, &settings, &saved);

// save search path (disable save compression if requested)
if (disableSaveCompression)
Expand All @@ -319,6 +344,43 @@ bool save(const FilePath& statePath,
return saved;
}


bool saveMinimal(const core::FilePath& statePath,
bool saveGlobalEnvironment)
{
// initialize context
Settings settings;
bool saved = true;
initSaveContext(statePath, &settings, &saved);

// handle dev mode
saveDevMode(&settings);

// save working context
saveWorkingContext(statePath, &settings, &saved);

// save global environment if requested
if (saveGlobalEnvironment)
{
// disable save compression
Error error = r::exec::RFunction(".rs.disableSaveCompression").call();
if (error)
LOG_ERROR(error);

error = search_path::saveGlobalEnvironment(statePath);
if (error)
{
reportError(kSaving, kGlobalEnvironment, error, ERROR_LOCATION);
saved = false;
}
}



// return status
return saved;
}

Error deferredRestore(const FilePath& statePath, bool serverMode)
{
// search path
Expand Down Expand Up @@ -370,9 +432,13 @@ bool restore(const FilePath& statePath,
reportError(kRestoring, kWorkingDirectory, error, ERROR_LOCATION, er);

// restore options
error = r::options::restoreOptions(statePath.complete(kOptionsFile));
if (error)
reportError(kRestoring, kOptionsFile, error, ERROR_LOCATION, er);
FilePath optionsPath = statePath.complete(kOptionsFile);
if (optionsPath.exists())
{
error = r::options::restoreOptions(optionsPath);
if (error)
reportError(kRestoring, kOptionsFile, error, ERROR_LOCATION, er);
}

// restore libpaths
error = restoreLibPaths(statePath.complete(kLibPathsFile));
Expand All @@ -396,7 +462,6 @@ bool restore(const FilePath& statePath,
if (error)
reportError(kRestoring, kHistoryFile, error, ERROR_LOCATION, er);


// restore environment vars
error = restoreEnvironmentVars(statePath.complete(kEnvironmentVars));
if (error)
Expand Down
Loading

0 comments on commit 8177a17

Please sign in to comment.