Skip to content

Commit

Permalink
Better handling of connections
Browse files Browse the repository at this point in the history
  • Loading branch information
zalmoxisus committed Sep 8, 2016
1 parent d9fc507 commit 4975d5c
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 71 deletions.
1 change: 1 addition & 0 deletions src/app/constants/actionTypes.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const UPDATE_STATE = 'devTools/UPDATE_STATE';
export const SELECT_INSTANCE = 'devTools/SELECT_INSTANCE';
export const REMOVE_INSTANCE = 'devTools/REMOVE_INSTANCE';
export const LIFTED_ACTION = 'devTools/LIFTED_ACTION';
1 change: 1 addition & 0 deletions src/app/constants/socketActionTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export const DEAUTHENTICATE = 'socket/DEAUTHENTICATE';
export const SUBSCRIBE_REQUEST = 'socket/SUBSCRIBE_REQUEST';
export const SUBSCRIBE_SUCCESS = 'socket/SUBSCRIBE_SUCCESS';
export const SUBSCRIBE_ERROR = 'socket/SUBSCRIBE_ERROR';
export const UNSUBSCRIBE = 'socket/UNSUBSCRIBE';
export const EMIT = 'socket/EMIT';
5 changes: 4 additions & 1 deletion src/app/constants/socketOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ const socketOptions = {
hostname: 'remotedev.io',
port: 80,
autoReconnect: true,
secure: false
secure: false,
autoReconnectOptions: {
randomness: 30000
}
};

export default socketOptions;
61 changes: 37 additions & 24 deletions src/app/middleware/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { stringify } from 'jsan';
import socketCluster from 'socketcluster-client';
import * as actions from '../constants/socketActionTypes';
import {
UPDATE_STATE, LIFTED_ACTION
UPDATE_STATE, REMOVE_INSTANCE, LIFTED_ACTION
} from '../constants/actionTypes';

let socket;
Expand All @@ -24,6 +24,19 @@ function dispatchLiftedAction({ action }) {
}

const watch = subscription => request => {
if (subscription === UPDATE_STATE) {
if (request.type === 'DISCONNECTED') {
store.dispatch({
type: REMOVE_INSTANCE,
id: request.id
});
return;
}
if (request.type === 'START') {
store.dispatch({ type: actions.EMIT, message: 'START', id: request.id });
return;
}
}
store.dispatch({
type: subscription,
request: request.data ? { ...request.data, id: request.id } : request
Expand All @@ -32,32 +45,10 @@ const watch = subscription => request => {

function subscribe(channelName, subscription) {
const channel = socket.subscribe(channelName);
socket.on('subscribeFail', error => {
store.dispatch({ type: actions.SUBSCRIBE_ERROR, error, status: 'subscribeFail' });
});
socket.on('unsubscribe', error => {
store.dispatch({ type: actions.SUBSCRIBE_ERROR, error, status: 'unsubscribe' });
});
socket.on('dropOut', error => {
store.dispatch({ type: actions.SUBSCRIBE_ERROR, error, status: 'dropOut' });
});
socket.on('subscribe', () => {
channel.watch(watch(subscription));
store.dispatch({ type: actions.SUBSCRIBE_SUCCESS, channel });
});
channel.watch(watch(subscription));
}

function handleConnection() {
socket.on('error', error => {
store.dispatch({ type: actions.CONNECT_ERROR, error });
});
socket.on('disconnect', () => {
store.dispatch({ type: actions.DISCONNECT });
});
socket.on('connectAbort', () => {
store.dispatch({ type: actions.DISCONNECT });
});

socket.on('connect', status => {
store.dispatch({
type: actions.CONNECT_SUCCESS,
Expand All @@ -72,6 +63,28 @@ function handleConnection() {
store.dispatch({ type: actions.AUTH_REQUEST });
}
});
socket.on('disconnect', code => {
store.dispatch({ type: actions.DISCONNECT, code });
});

socket.on('subscribe', channelName => {
store.dispatch({ type: actions.SUBSCRIBE_SUCCESS, channelName });
});
socket.on('unsubscribe', channelName => {
socket.unsubscribe(channelName);
socket.unwatch(channelName);
store.dispatch({ type: actions.UNSUBSCRIBE, channelName });
});
socket.on('subscribeFail', error => {
store.dispatch({ type: actions.SUBSCRIBE_ERROR, error, status: 'subscribeFail' });
});
socket.on('dropOut', error => {
store.dispatch({ type: actions.SUBSCRIBE_ERROR, error, status: 'dropOut' });
});

socket.on('error', error => {
store.dispatch({ type: actions.CONNECT_ERROR, error });
});
}

function connect() {
Expand Down
11 changes: 6 additions & 5 deletions src/app/reducers/channels.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import * as actions from '../constants/socketActionTypes';

export default function channels(state = {}, action) {
export default function channels(state = [], action) {
switch (action.type) {
case actions.SUBSCRIBE_SUCCESS:
return {
...state,
[action.channel.name]: action.channel
};
return [...state, action.channelName];
case actions.UNSUBSCRIBE:
return state.filter(channel =>
channel !== action.channelName
);
default:
return state;
}
Expand Down
62 changes: 31 additions & 31 deletions src/app/reducers/instances.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { UPDATE_STATE, SELECT_INSTANCE } from '../constants/actionTypes';
import { UPDATE_STATE, SELECT_INSTANCE, REMOVE_INSTANCE } from '../constants/actionTypes';
import { DISCONNECT } from '../constants/socketActionTypes';

const initialState = {
selected: null,
names: {},
connections: {}
};

function disconnected(state, connectionId) {
function removeState(state, connectionId) {
const instanceIds = state.connections[connectionId];
if (!instanceIds) return state;
const names = { ...state.names };
Expand All @@ -24,34 +25,33 @@ function disconnected(state, connectionId) {
}

export default function instances(state = initialState, action) {
if (action.type === SELECT_INSTANCE) {
return { ...state, selected: action.selected };
switch (action.type) {
case UPDATE_STATE:
const { request } = action;
const connectionId = request.id;
const instanceId = request.instanceId || connectionId;
if (typeof state.names[instanceId] !== 'undefined') return state;

const instanceIds = state.connections[connectionId] || [];
instanceIds.push(instanceId);
return {
...state,
connections: {
...state.connections,
[connectionId]: instanceIds
},
names: {
...state.names,
[instanceId]: request.name || instanceId
}
};
case SELECT_INSTANCE:
return { ...state, selected: action.selected };
case REMOVE_INSTANCE:
return removeState(state, action.id);
case DISCONNECT:
return initialState;
default:
return state;
}
if (action.type !== UPDATE_STATE) return state;

const { request } = action;
const connectionId = request.id;

if (request.type === 'DISCONNECTED') {
return disconnected(state, connectionId);
}

const instanceId = request.instanceId || connectionId;
if (/* request.type === 'START' || */ !state.names[instanceId]) {
const instanceIds = state.connections[connectionId] || [];
instanceIds.push(instanceId);
return {
...state,
connections: {
...state.connections,
[connectionId]: instanceIds
},
names: {
...state.names,
[instanceId]: request.name || instanceId
}
};
}

return state;
}
21 changes: 12 additions & 9 deletions src/app/reducers/lifted.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import omit from 'lodash/omit';
import { UPDATE_STATE, LIFTED_ACTION, SELECT_INSTANCE } from '../constants/actionTypes';
import { UPDATE_STATE, LIFTED_ACTION, SELECT_INSTANCE, REMOVE_INSTANCE } from '../constants/actionTypes';
import { DISCONNECT } from '../constants/socketActionTypes';
import parseJSON from '../utils/parseJSON';
import { recompute } from '../store/updateState';

Expand Down Expand Up @@ -70,8 +71,8 @@ function dispatchAction(state, { action }) {
return state;
}

function disconnected(state, { request }) {
const states = omit(state.states, request.id);
function removeState(state, id) {
const states = omit(state.states, id);
let selected = state.selected;
let current = state.current;
if (!states[selected]) {
Expand All @@ -95,22 +96,24 @@ function init({ type, action }) {
export default function lifted(state = initialState, action) {
switch (action.type) {
case UPDATE_STATE:
if (action.request.type === 'DISCONNECTED') {
return disconnected(state, action);
}
const current = action.request.id;
const request = action.request;
const current = request.id;
let rest;
if (!state.states[current]) {
rest = init(action.request);
rest = init(request);
}
return {
...state,
...rest,
current,
states: updateState(state.states, action.request)
states: updateState(state.states, request)
};
case REMOVE_INSTANCE:
return removeState(state, action.id);
case LIFTED_ACTION:
return dispatchAction(state, action);
case DISCONNECT:
return initialState;
case SELECT_INSTANCE:
return { ...state, selected: action.selected };
default:
Expand Down
2 changes: 1 addition & 1 deletion src/app/store/configureStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function configureStore(initialState) {
if (module.hot) {
// Enable Webpack hot module replacement for reducers
module.hot.accept('../reducers', () => {
const nextReducer = require('../reducers').default;
const nextReducer = require('../reducers');
store.replaceReducer(nextReducer);
});
}
Expand Down

0 comments on commit 4975d5c

Please sign in to comment.