Skip to content

Commit

Permalink
title is swizzled to record the title of images, which is now stored …
Browse files Browse the repository at this point in the history
…in the sessionimage table
  • Loading branch information
mlilback committed Mar 27, 2017
1 parent 03158d3 commit 6fce82e
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 14 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,4 @@ install(CODE "execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/prepareRInside.sh\"
install(TARGETS rserver rsession RUNTIME DESTINATION .)
install(DIRECTORY ${CMAKE_BINARY_DIR}/RInside DESTINATION . ${INSTALL_PATH})
install(DIRECTORY ${CMAKE_SOURCE_DIR}/R/rc2 DESTINATION . ${INSTALL_PATH})
install(DIRECTORY ${CMAKE_SOURCE_DIR}/rsrc DESTINATION . ${INSTALL_PATH})
5 changes: 2 additions & 3 deletions R/rc2/DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
Package: rc2
Type: Package
Title: Assists communication with rc2compute engine
Version: 2.0
Date: 2016-05-23
Version: 3.0
Date: 2017-03-23
Author: Mark Lilback
Maintainer: Mark Lilback <[email protected]>
Description:Assists rc2compute engine
License: BSD
Depends: stringr
LazyLoad: yes
2 changes: 1 addition & 1 deletion R/rc2/NAMESPACE
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export("help", "rc2.defineFunction", "rc2.pngdev", "rc2.pngoff")
export("help", "rc2.defineFunction", "rc2.pngdev", "rc2.pngoff", "rc2.errlog")
20 changes: 17 additions & 3 deletions R/rc2/R/rc2.R
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
helpIndexSearch <- getFromNamespace("index.search", getNamespace("utils"))

utils::suppressForeignCheck("rc2cache")
rc2cache <- new.env(parent = emptyenv())
assign("imgNum", 100, envir=rc2cache)

#called from EnvList.cpp c++ code
rc2.defineFunction <- function(func) {
zz <- textConnection("def", open = "w", local = TRUE)
zz <- textConnection(NULL, open = "w", local = TRUE)
capture.output(print(func), file=zz)
result <- paste(textConnectionValue(zz), sep="\n")
close(zz)
paste(def, sep="\n")
result
}

#override to just return help paths
Expand All @@ -29,11 +34,20 @@ help <- function(topic) {

rc2.pngdev <- function()
{
png("rc2img%03d.png")
imgNum <- as.integer(get("imgNum", envir=rc2:::rc2cache))
assign("imgNum", imgNum + 1, envir=rc2:::rc2cache)
fname <- sprintf("rc2img%03d.png", imgNum, envir=rc2:::rc2cache)
png(fname)
rc2.errlog("rc2.imgstart=%s\n", fname)
}

rc2.pngoff <- function()
{
rc2.errlog("dev off")
if (dev.cur()[1] != 1)
dev.off();
}


rc2.errlog <- function(...) cat(sprintf(...), sep='', file=stderr())

1 change: 1 addition & 0 deletions computeClient/.perl-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5.23.4
1 change: 1 addition & 0 deletions computeClient/query.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"msg": "execScript", "argument": "rnorm(11)"}
51 changes: 51 additions & 0 deletions rsrc/swizzle.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
library(inline)
local( {
myenv <- new.env(parent = emptyenv())
oldtitle <- graphics::title
#assign("oldtitle", graphics::title, envir = myenv)

#oldtitle <- title
mytitle <- function(...) {
args <- list(...)
if (!is.null(args$main)) {
rc2.errlog("rc2.imgtitle=%s\n", args$main)
}
oldtitle(...)
}

inc <- '
/* This is taken from envir.c in the R 2.15.1 source
https://github.com/SurajGupta/r-source/blob/master/src/main/envir.c
*/
#define FRAME_LOCK_MASK (1<<14)
#define FRAME_IS_LOCKED(e) (ENVFLAGS(e) & FRAME_LOCK_MASK)
#define UNLOCK_FRAME(e) SET_ENVFLAGS(e, ENVFLAGS(e) & (~ FRAME_LOCK_MASK))
'

src <- '
if (TYPEOF(env) == NILSXP)
error("use of NULL environment is defunct");
if (TYPEOF(env) != ENVSXP)
error("not an environment");
UNLOCK_FRAME(env);
// Return TRUE if unlocked; FALSE otherwise
SEXP result = PROTECT( Rf_allocVector(LGLSXP, 1) );
LOGICAL(result)[0] = FRAME_IS_LOCKED(env) == 0;
UNPROTECT(1);
return result;
'

unlockEnvironment <- cfunction(signature(env = "environment"),
includes = inc,
body = src)


ns_g <- asNamespace('graphics')
unlockEnvironment(ns_g)
unlockBinding("title", ns_g)
ns_g$title <- mytitle
lockBinding("title", ns_g)
detach(package:graphics)
library(graphics)

})
19 changes: 16 additions & 3 deletions src/FileManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class RC2::FileManager::Impl : public ZeroInitializedClass {
int inotifyFd_;
FSDirectory rootDir_;
boost::regex imgRegex_;
map<string, string> imgNameToTitle_;
bool ignoreFSNotifications_;
bool ignoreDBNotifications_;

Expand Down Expand Up @@ -150,6 +151,10 @@ RC2::FileManager::Impl::connect(std::shared_ptr<PGDBConnection> connection, long
long
RC2::FileManager::Impl::insertImage(string fname, string imgNumStr)
{
string title = "";
if (imgNameToTitle_.count(fname) > 0) {
dbConnection_->escapeLiteral(imgNameToTitle_[fname], title);
}
string filePath = workingDir + "/" + fname;
size_t size;
unique_ptr<char[]> buffer = ReadFileBlob(filePath, size);
Expand All @@ -166,8 +171,11 @@ RC2::FileManager::Impl::insertImage(string fname, string imgNumStr)
sessionImageBatch_ = dbConnection_->longFromQuery(batchq.str().c_str()) + 1;
}
stringstream query;
query << "insert into sessionimage (id,sessionid,batchid,name,imgdata) values (" << imgId
<< "," << sessionRecId_ << "," << sessionImageBatch_ << ",'img" << imgId << ".png',$1::bytea)";
query << "insert into sessionimage (id,sessionid,batchid,name,title,imgdata) values (" << imgId
<< "," << sessionRecId_ << "," << sessionImageBatch_
<< ",'img" << imgId << ".png',"
<< title << ","
<< "$1::bytea)";
int pformats = 1;
int pSizes[] = {(int)size};
const char *params[] = {buffer.get()};
Expand Down Expand Up @@ -527,7 +535,6 @@ RC2::FileManager::resetWatch()
// LOG(INFO) << "fm:resetWatch called: " << _impl->imageIds_.size();
if (_impl->imageIds_.size() > 0) {
_impl->sessionImageBatch_++;
LOG(INFO) << "incrementing batch_id:" << _impl->sessionImageBatch_;
}
_impl->imageIds_.erase(_impl->imageIds_.begin(), _impl->imageIds_.end());
_impl->manuallyAddedFiles_.clear();
Expand All @@ -541,9 +548,15 @@ RC2::FileManager::checkWatch(vector<long> &imageIds, long &batchId)
// _impl->sessionImageBatch_ = 0;
}

void RC2::FileManager::setTitle(std::string title, std::string imageName)
{
_impl->imgNameToTitle_[imageName] = title;
}

void RC2::FileManager::cleanupImageWatch()
{
_impl->cleanupImageWatch();
_impl->imgNameToTitle_.clear();
}

bool
Expand Down
1 change: 1 addition & 0 deletions src/FileManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ namespace RC2 {
virtual void suspendNotifyEvents();
virtual void resumeNotifyEvents();

virtual void setTitle(std::string title, std::string imageName);
//for unit testing
virtual void processDBNotification(std::string message);

Expand Down
30 changes: 27 additions & 3 deletions src/RSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <sys/wait.h>
#include <unistd.h>
#include <boost/log/utility/setup/file.hpp>
#include <boost/algorithm/string.hpp>
#define BOOST_NO_CXX11_SCOPED_ENUMS
#include <boost/filesystem.hpp>
#include <boost/regex.hpp>
Expand Down Expand Up @@ -39,6 +40,10 @@ static string escape_quotes(const string before);
static string formatErrorAsJson(int errorCode, string details, int queryId=0);
static void rc2_log_callback(int severity, const char *msg);

inline bool stringHasPrefix(string str, const char* prefix) {
return strncmp(str.c_str(), prefix, strlen(prefix)) == 0;
}

inline double currentFractionalSeconds() {
struct timeval tv;
gettimeofday(&tv, NULL);
Expand Down Expand Up @@ -75,6 +80,7 @@ struct RC2::RSession::Impl : public ZeroInitializedStruct {
unique_ptr<EnvironmentWatcher> envWatcher;
shared_ptr<string> consoleOutBuffer;
string stdOutCapture;
string currentImageName; //watching to track title of it
double consoleLastWrite;
int wspaceId;
int sessionRecId;
Expand Down Expand Up @@ -235,7 +241,19 @@ RC2::RSession::~RSession()
void
RC2::RSession::consoleCallback(const string &text, bool is_error)
{
// LOG(INFO) << "write cb: " << text << "(ignore=" << _impl->ignoreOutput << ",vis=" << R_Visible << ",sip=" << _impl->sourceInProgress << ")";
if (stringHasPrefix(text, "rc2.imgstart=")) {
auto imgname = text.substr(13);
boost::algorithm::trim(imgname);
_impl->currentImageName = imgname;
return;
} else if (stringHasPrefix(text, "rc2.imgtitle=")) {
auto imgtitle = text.substr(13);
boost::algorithm::trim(imgtitle);
_impl->fileManager->setTitle(imgtitle, _impl->currentImageName);
_impl->currentImageName = "";
return;
}
LOG(INFO) << "write cb: " << text << "(ignore=" << _impl->ignoreOutput << ",vis=" << R_Visible << ",sip=" << _impl->sourceInProgress << ")";
if (_impl->captureStdOut) {
_impl->stdOutCapture += text;
return;
Expand Down Expand Up @@ -450,6 +468,11 @@ RC2::RSession::handleOpenCommand(JsonCommand &cmd)
connectString << "&password=" << dbpass;
LOG(INFO) << connectString.str();

string installLoc = RC2::GetPathForExecutable(getpid());
string::size_type pos = installLoc.rfind('/');
string ourCodePath = installLoc.substr(0, pos) + "/rsrc/swizzle.R";


if (NULL == _impl->eventBase) {
LOG(WARNING) << "handleOpenCommand called before prepareForRunLoop()";
abort();
Expand All @@ -461,7 +484,6 @@ RC2::RSession::handleOpenCommand(JsonCommand &cmd)
}
_impl->tmpDir = std::move(std::unique_ptr<TemporaryDirectory>(new TemporaryDirectory(workDir, false)));
LOG(INFO) << "wd=" << _impl->tmpDir->getPath();
// _impl->fileManager->setWorkingDir(workDir);
auto connection = make_shared<PGDBConnection>();
connection->connect(connectString.str());
_impl->fileManager->initFileManager(workDir, connection, _impl->wspaceId, _impl->sessionRecId);
Expand All @@ -471,11 +493,12 @@ RC2::RSession::handleOpenCommand(JsonCommand &cmd)
setenv("R_DEFAULT_DEVICE", "png", 1);
_impl->R->parseEvalQNT("setwd(\"" + escape_quotes(workDir) + "\")");
_impl->ignoreOutput = true;
_impl->R->parseEvalQNT("library(rc2)");
_impl->R->parseEvalQNT("library(rmarkdown)");
_impl->R->parseEvalQNT("library(tools)");
_impl->R->parseEvalQNT("library(rc2)");
_impl->R->parseEvalQNT("rm(argv)"); //RInside creates this even though we passed NULL
_impl->R->parseEvalQNT("options(device = \"rc2.pngdev\", bitmapType = \"cairo\")");
_impl->R->parseEvalQNT("source(\"" + escape_quotes(ourCodePath) + "\", keep.source=FALSE)");
if (haveRData) {
LOG(INFO) << "loading .RData";
_impl->R->parseEvalQNT("load(\".RData\")");
Expand Down Expand Up @@ -770,6 +793,7 @@ RC2::RSession::clearFileChanges()
{
json2 ignoredJson;
_impl->addImagesToJson(ignoredJson);
_impl->currentImageName = "";
}

//causes R to save any images generated and then sends the output buffer to the client
Expand Down

0 comments on commit 6fce82e

Please sign in to comment.