1 /*
2  * RRestartContext.cpp
3  *
4  * Copyright (C) 2021 by RStudio, PBC
5  *
6  * Unless you have received this program directly from RStudio pursuant
7  * to the terms of a commercial license agreement with RStudio, then
8  * this program is licensed to you under the terms of version 3 of the
9  * GNU Affero General Public License. This program is distributed WITHOUT
10  * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12  * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13  *
14  */
15 
16 #include "RRestartContext.hpp"
17 
18 #include <boost/algorithm/string.hpp>
19 
20 #include <core/Log.hpp>
21 #include <shared_core/Error.hpp>
22 #include <core/FileUtils.hpp>
23 #include <core/system/System.hpp>
24 
25 #include <r/session/RSessionState.hpp>
26 
27 using namespace rstudio::core;
28 
29 namespace rstudio {
30 namespace r {
31 namespace session {
32 
33 namespace {
34 
35 const char * const kContext = "ctx-";
36 
restartContextsPath(const FilePath & scopePath)37 FilePath restartContextsPath(const FilePath& scopePath)
38 {
39    FilePath contextsPath = scopePath.completePath("ctx");
40    Error error = contextsPath.ensureDirectory();
41    if (error)
42       LOG_ERROR(error);
43    return contextsPath;
44 }
45 
46 } // anonymous namespace
47 
48 // singleton
restartContext()49 RestartContext& restartContext()
50 {
51    static RestartContext instance;
52    return instance;
53 }
54 
RestartContext()55 RestartContext::RestartContext()
56 {
57 }
58 
initialize(const FilePath & scopePath,const std::string & contextId)59 void RestartContext::initialize(const FilePath& scopePath,
60                                 const std::string& contextId)
61 {
62    FilePath contextsPath = restartContextsPath(scopePath);
63    FilePath statePath = contextsPath.completePath(kContext + contextId);
64    if (statePath.exists())
65       sessionStatePath_ = statePath;
66 }
67 
hasSessionState() const68 bool RestartContext::hasSessionState() const
69 {
70    return !sessionStatePath().isEmpty();
71 }
72 
rProfileOnRestore() const73 bool RestartContext::rProfileOnRestore() const
74 {
75    // if we don't have any session state then this check shouldn't
76    // trigger loading of the profile (allow other checks like whether
77    // we are coming back from a server suspend to run)
78    if (!hasSessionState())
79       return false;
80 
81    return r::session::state::rProfileOnRestore(sessionStatePath());
82 }
83 
sessionStatePath() const84 FilePath RestartContext::sessionStatePath() const
85 {
86    return sessionStatePath_;
87 }
88 
removeSessionState()89 void RestartContext::removeSessionState()
90 {
91    r::session::state::destroy(sessionStatePath_);
92 }
93 
createSessionStatePath(const FilePath & scopePath,const std::string & contextId)94 FilePath RestartContext::createSessionStatePath(const FilePath& scopePath,
95                                                 const std::string& contextId)
96 {
97    FilePath contextsPath = restartContextsPath(scopePath);
98    FilePath statePath = contextsPath.completePath(kContext + contextId);
99 
100    Error error = statePath.ensureDirectory();
101    if (error)
102       LOG_ERROR(error);
103    return statePath;
104 }
105 
106 } // namespace session
107 } // namespace r
108 } // namespace rstudio
109 
110 
111 
112