client/src/sagas/networkSaga.js
author ymh <ymh.work@gmail.com>
Mon, 26 Jun 2017 15:21:06 +0200
changeset 87 dbcee57de2c6
child 88 2a861fed6bde
permissions -rw-r--r--
Add first implementation of network monitor
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
87
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
import * as types from '../constants/actionTypes';
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
import { all, call, fork, race, take, cancelled, put, select } from 'redux-saga/effects'
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
import config from '../config';
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
// Utility function to delay effects
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
function delay(millis) {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
    const promise = new Promise(resolve => {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
        setTimeout(() => resolve(true), millis)
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
    });
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
    return promise;
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
}
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
function pingServer(client, token) {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
  console.log("PING SERVER", token);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
  if(token) {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
    const timeout = new Promise((resolve, reject) => {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
      setTimeout(reject, config.networkStatusTimeout, 'request timed out');
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
    });
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
    return Promise
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
      .race([timeout, client.post('/api/auth/refresh/', { token })]);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
  } else {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
    return Promise.reject({ error: 'No token in the store'})
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
  }
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
}
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
// Fetch data every 20 seconds
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
function* pollData(context) {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
  try {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
    yield call(delay, config.networkStatusInterval);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
    const token = yield select(state => state.token);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
    const res = yield pingServer(context.client, token);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
    yield call(context.callback, true);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
    yield put({
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
      type: types.AUTH_STORE_TOKEN_ASYNC,
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
      token: res.token,
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
    });
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
  } catch (error) {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
    yield call(context.callback, false);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
    // if the error is that there is no token, then we know we have to wait for a login
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
    if(error.error && error.error === 'No token in the store') {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
      yield take(types.AUTH_LOGIN_SUCCESS);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
    }
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
  } finally {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
    if (yield cancelled()) {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
      // pollDate cancelled
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
      // if there is a token : this was a LOGIN, set status to ok
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
      // if there is no token : this was a LOGOUT, set status to ko and wait for login
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
      const token = yield select(state => state.token);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
      if(token) {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
        yield call(context.callback, true);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
      } else {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
        yield call(context.callback, false);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
        yield take(types.AUTH_LOGIN_SUCCESS);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
      }
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
    }
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
  }
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
}
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
// Wait for successful response, then fire another request
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
// Cancel polling if user logs out or log in
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
function* watchPollData(context) {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
  while (true) {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
    yield race([
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
      call(pollData, context),
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
      take(types.AUTH_LOGOUT),
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
      take(types.AUTH_LOGIN_SUCCESS)
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
    ]);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
  }
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
}
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
// Daemonize tasks in parallel
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
export default function* root(baseContext) {
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
  const actionRes = yield take(types.OFFLINE_CONFIG_INITIALIZED);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
  const context = {...baseContext, ...actionRes.additionalContext};
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
  yield all([
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
    fork(watchPollData, context)
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
    // other watchers here
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
  ]);
dbcee57de2c6 Add first implementation of network monitor
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
}