[education/rkward] rkward: Discard all running commands also on regular exit

Thomas Friedrichsmeier null at kde.org
Sun May 19 10:35:11 BST 2024


Git commit 15478c8054ddddba1de2d9decdf2fb23b97b79d2 by Thomas Friedrichsmeier.
Committed on 19/05/2024 at 09:35.
Pushed by tfry into branch 'master'.

Discard all running commands also on regular exit

M  +2    -2    rkward/agents/rkquitagent.cpp
M  +1    -1    rkward/autotests/core_test.cpp
M  +1    -1    rkward/rbackend/rkrbackendprotocol_shared.h
M  +8    -5    rkward/rbackend/rkrinterface.cpp
M  +1    -1    rkward/rkward.cpp

https://invent.kde.org/education/rkward/-/commit/15478c8054ddddba1de2d9decdf2fb23b97b79d2

diff --git a/rkward/agents/rkquitagent.cpp b/rkward/agents/rkquitagent.cpp
index 739a3d57f..95100fe4b 100644
--- a/rkward/agents/rkquitagent.cpp
+++ b/rkward/agents/rkquitagent.cpp
@@ -1,6 +1,6 @@
 /*
 rkquitagent - This file is part of RKWard (https://rkward.kde.org). Created: Thu Jan 18 2007
-SPDX-FileCopyrightText: 2007 by Thomas Friedrichsmeier <thomas.friedrichsmeier at kdemail.net>
+SPDX-FileCopyrightText: 2007-2024 by Thomas Friedrichsmeier <thomas.friedrichsmeier at kdemail.net>
 SPDX-FileContributor: The RKWard Team <rkward-devel at kde.org>
 SPDX-License-Identifier: GPL-2.0-or-later
 */
@@ -24,7 +24,7 @@ RKQuitAgent::RKQuitAgent (QObject *parent) : QObject (parent) {
 	RK_TRACE (APP);
 
 	quitting = true;
-	RCommand *command = new RCommand (QString (), RCommand::EmptyCommand | RCommand::QuitCommand);
+	RCommand *command = new RCommand(QString("# Quit"), RCommand::EmptyCommand | RCommand::QuitCommand);
 
 	RKWardMainWindow::getMain ()->hide ();
 	cancel_dialog = new RKProgressControl (this, i18n ("Waiting for remaining R commands to finish. To quit immediately, press Cancel (WARNING: This may result in loss of data)"), i18n ("Waiting for R to finish"), RKProgressControl::AllowCancel | RKProgressControl::ShowAtOnce);
diff --git a/rkward/autotests/core_test.cpp b/rkward/autotests/core_test.cpp
index e9502ea6f..0cb86d6eb 100644
--- a/rkward/autotests/core_test.cpp
+++ b/rkward/autotests/core_test.cpp
@@ -431,7 +431,7 @@ private Q_SLOTS:
 	void cleanupTestCase()
 	{
 		// at least the backend should exit properly, to avoid creating emergency save files
-		RInterface::issueCommand(new RCommand(QString(), RCommand::QuitCommand));
+		RInterface::issueCommand(new RCommand(QString("# Quit (test cleanup)"), RCommand::QuitCommand));
 		RKWardMainWindow::getMain()->slotCloseAllWindows();
 		while (!(RInterface::instance()->backendIsDead())) {
 			qApp->processEvents();
diff --git a/rkward/rbackend/rkrbackendprotocol_shared.h b/rkward/rbackend/rkrbackendprotocol_shared.h
index 5556129d9..f9db15c05 100644
--- a/rkward/rbackend/rkrbackendprotocol_shared.h
+++ b/rkward/rbackend/rkrbackendprotocol_shared.h
@@ -39,7 +39,7 @@ public:
 		SetParamsFromBackend,
 		Debugger,
 		CommandLineIn,	/**< The next line of the current user command has been submitted in the backend. */
-		Output,		/**< A piece of output. Note: If the backend runs in a single process, output is handled in a pull fashion, instead of using requests. */  //15
+		Output,		/**< A piece of output. Note: If the backend runs in a single process, output is handled in a pull fashion, instead of using requests. */  //11
 		Interrupt,	/**< Interrupt evaluation. This request type originates in the frontend, not the backend. */
 		PriorityCommand, /**< Send a command to be run during R's event processing. This request type originates in the frontend, not the backend. */
 		OutputStartedNotification, /**< Only used in the frontend: Notification that a new bit of output has arrived. Used to trigger flushing after a timeout. */
diff --git a/rkward/rbackend/rkrinterface.cpp b/rkward/rbackend/rkrinterface.cpp
index bc1ca6249..942fe2db2 100644
--- a/rkward/rbackend/rkrinterface.cpp
+++ b/rkward/rbackend/rkrinterface.cpp
@@ -178,6 +178,7 @@ void RInterface::closeSubcommandChain (RCommand* parent_command) {
 
 void RInterface::tryNextCommand () {
 	RK_TRACE (RBACKEND);
+
 	RCommand *command = RCommandStack::currentCommand ();
 	if (command_requests.isEmpty ()) {
 		// if the backend is not requesting anything, only priority commands will be pushed
@@ -332,6 +333,7 @@ void RInterface::handleRequest (RBackendRequest* request) {
 
 	flushOutput (true);
 	if (request->type == RBackendRequest::CommandOut) {
+		if (backend_dead) return; // Backend may or may not be able to transmit finished commands after exit, and therefore we've already discarded all active commands
 		RCommandProxy *cproxy = request->takeCommand ();
 		if (cproxy) {
 			RK_DEBUG (RBACKEND, DL_DEBUG, "Command out \"%s\", id %d", qPrintable (cproxy->command), cproxy->id);
@@ -878,14 +880,15 @@ void RInterface::processRBackendRequest (RBackendRequest *request) {
 			na_real = request->params["na_real"].toDouble ();
 			na_int = request->params["na_int"].toInt ();
 	} else if (type == RBackendRequest::BackendExit) {
-		if (request->params.value ("regular", QVariant (false)).toBool ()) backend_dead = true;		// regular exit via QuitCommand
 		if (!backend_dead) {
 			backend_dead = true;
-			QString message = request->params["message"].toString ();
-			RK_DEBUG(RBACKEND, DL_ERROR, "Backend exit: %s", qPrintable(message));
-			message += i18n ("\nThe R backend will be shut down immediately. This means, you can not use any more functions that rely on it. I.e. you can do hardly anything at all, not even save the workspace (but if you're lucky, R already did that). What you can do, however, is save any open command-files, the output, or copy data out of open data editors. Quit RKWard after that. Sorry!");
-			RKErrorDialog::reportableErrorMessage(nullptr, message, QString(), i18n("R engine has died"), "r_engine_has_died");
 			Q_EMIT backendStatusChanged(Dead);
+			if (!(request->params.value("regular", QVariant(false)).toBool())) { // irregular exit
+				QString message = request->params["message"].toString ();
+				RK_DEBUG(RBACKEND, DL_ERROR, "Backend exit: %s", qPrintable(message));
+				message += i18n ("\nThe R backend will be shut down immediately. This means, you can not use any more functions that rely on it. I.e. you can do hardly anything at all, not even save the workspace (but if you're lucky, R already did that). What you can do, however, is save any open command-files, the output, or copy data out of open data editors. Quit RKWard after that. Sorry!");
+				RKErrorDialog::reportableErrorMessage(nullptr, message, QString(), i18n("R engine has died"), "r_engine_has_died");
+			}
 			while (!all_current_commands.isEmpty()) {
 				auto c = all_current_commands.takeLast();
 				c->status |= RCommand::Failed;
diff --git a/rkward/rkward.cpp b/rkward/rkward.cpp
index 62d2159a0..877bc2038 100644
--- a/rkward/rkward.cpp
+++ b/rkward/rkward.cpp
@@ -654,7 +654,7 @@ void RKWardMainWindow::initActions() {
 				RKConsole::mainConsole()->resetConsole();
 				restart_now();
 			} else {
-				RCommand *c = new RCommand(QString(), RCommand::QuitCommand);
+				RCommand *c = new RCommand(QString("# Quit (restarting)"), RCommand::QuitCommand);
 				c->whenFinished(this, [this, restart_now]() { QTimer::singleShot(0, this, restart_now); });
 				RInterface::issueCommand(c);
 			}


More information about the rkward-tracker mailing list