diff -r fa8ef84a1780 -r dbcee57de2c6 client/src/sagas/networkSaga.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/src/sagas/networkSaga.js Mon Jun 26 15:21:06 2017 +0200 @@ -0,0 +1,79 @@ +import * as types from '../constants/actionTypes'; +import { all, call, fork, race, take, cancelled, put, select } from 'redux-saga/effects' +import config from '../config'; + +// Utility function to delay effects +function delay(millis) { + const promise = new Promise(resolve => { + setTimeout(() => resolve(true), millis) + }); + return promise; +} + +function pingServer(client, token) { + console.log("PING SERVER", token); + if(token) { + const timeout = new Promise((resolve, reject) => { + setTimeout(reject, config.networkStatusTimeout, 'request timed out'); + }); + return Promise + .race([timeout, client.post('/api/auth/refresh/', { token })]); + } else { + return Promise.reject({ error: 'No token in the store'}) + } +} + +// Fetch data every 20 seconds +function* pollData(context) { + try { + yield call(delay, config.networkStatusInterval); + const token = yield select(state => state.token); + const res = yield pingServer(context.client, token); + yield call(context.callback, true); + yield put({ + type: types.AUTH_STORE_TOKEN_ASYNC, + token: res.token, + }); + } catch (error) { + yield call(context.callback, false); + // if the error is that there is no token, then we know we have to wait for a login + if(error.error && error.error === 'No token in the store') { + yield take(types.AUTH_LOGIN_SUCCESS); + } + } finally { + if (yield cancelled()) { + // pollDate cancelled + // if there is a token : this was a LOGIN, set status to ok + // if there is no token : this was a LOGOUT, set status to ko and wait for login + const token = yield select(state => state.token); + if(token) { + yield call(context.callback, true); + } else { + yield call(context.callback, false); + yield take(types.AUTH_LOGIN_SUCCESS); + } + } + } +} + +// Wait for successful response, then fire another request +// Cancel polling if user logs out or log in +function* watchPollData(context) { + while (true) { + yield race([ + call(pollData, context), + take(types.AUTH_LOGOUT), + take(types.AUTH_LOGIN_SUCCESS) + ]); + } +} + +// Daemonize tasks in parallel +export default function* root(baseContext) { + const actionRes = yield take(types.OFFLINE_CONFIG_INITIALIZED); + const context = {...baseContext, ...actionRes.additionalContext}; + yield all([ + fork(watchPollData, context) + // other watchers here + ]); +}