diff --git a/client/src/templates/Challenges/classic/Show.js b/client/src/templates/Challenges/classic/Show.js index 18620dd494..259b192bef 100644 --- a/client/src/templates/Challenges/classic/Show.js +++ b/client/src/templates/Challenges/classic/Show.js @@ -34,7 +34,8 @@ import { updateChallengeMeta, challengeMounted, consoleOutputSelector, - executeChallenge + executeChallenge, + cancelTests } from '../redux'; import './classic.css'; @@ -54,12 +55,14 @@ const mapDispatchToProps = dispatch => initTests, updateChallengeMeta, challengeMounted, - executeChallenge + executeChallenge, + cancelTests }, dispatch ); const propTypes = { + cancelTests: PropTypes.func.isRequired, challengeMounted: PropTypes.func.isRequired, createFiles: PropTypes.func.isRequired, data: PropTypes.shape({ @@ -164,8 +167,9 @@ class ShowClassic extends Component { } componentWillUnmount() { - const { createFiles } = this.props; + const { createFiles, cancelTests } = this.props; createFiles({}); + cancelTests(); } getChallenge = () => this.props.data.challengeNode; diff --git a/client/src/templates/Challenges/redux/execute-challenge-saga.js b/client/src/templates/Challenges/redux/execute-challenge-saga.js index 54970ee726..b5048181f1 100644 --- a/client/src/templates/Challenges/redux/execute-challenge-saga.js +++ b/client/src/templates/Challenges/redux/execute-challenge-saga.js @@ -6,7 +6,9 @@ import { takeLatest, takeEvery, fork, - getContext + getContext, + take, + cancel } from 'redux-saga/effects'; import { channel } from 'redux-saga'; import escape from 'lodash/escape'; @@ -21,7 +23,8 @@ import { logsToConsole, updateTests, isBuildEnabledSelector, - disableBuildOnError + disableBuildOnError, + types } from './'; import { @@ -36,6 +39,13 @@ import { // How long before bailing out of a preview. const previewTimeout = 2500; +export function* executeCancellableChallengeSaga() { + const task = yield fork(executeChallengeSaga); + + yield take(types.cancelTests); + yield cancel(task); +} + export function* executeChallengeSaga() { const isBuildEnabled = yield select(isBuildEnabledSelector); if (!isBuildEnabled) { @@ -181,7 +191,7 @@ function* previewChallengeSaga() { export function createExecuteChallengeSaga(types) { return [ - takeLatest(types.executeChallenge, executeChallengeSaga), + takeLatest(types.executeChallenge, executeCancellableChallengeSaga), takeLatest( [ types.updateFile, diff --git a/client/src/templates/Challenges/redux/index.js b/client/src/templates/Challenges/redux/index.js index 00d7381dbc..e8b1ff0444 100644 --- a/client/src/templates/Challenges/redux/index.js +++ b/client/src/templates/Challenges/redux/index.js @@ -60,6 +60,7 @@ export const types = createTypes( 'updateSuccessMessage', 'updateTests', 'updateLogs', + 'cancelTests', 'logsToConsole', @@ -121,6 +122,7 @@ export const createFiles = createAction(types.createFiles, challengeFiles => export const createQuestion = createAction(types.createQuestion); export const initTests = createAction(types.initTests); export const updateTests = createAction(types.updateTests); +export const cancelTests = createAction(types.cancelTests); export const initConsole = createAction(types.initConsole); export const initLogs = createAction(types.initLogs);