--- /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
+ ]);
+}