Skip to content

Commit

Permalink
Support multiple instances in one connection
Browse files Browse the repository at this point in the history
  • Loading branch information
zalmoxisus committed Aug 25, 2016
1 parent 31005f5 commit 77916c6
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 20 deletions.
25 changes: 14 additions & 11 deletions src/app/containers/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
createRemoteStore, updateStoreInstance, enableSync,
startMonitoring, importState, exportState
} from '../store/createRemoteStore';
import { addInstance, deleteInstance } from '../services/messaging';
import ButtonBar from '../components/ButtonBar';
import Instances from '../components/Instances';
import MonitorSelector from '../components/MonitorSelector';
Expand Down Expand Up @@ -66,19 +67,21 @@ export default class App extends Component {
);
}

handleInstancesChanged = (instance, name, toRemove) => {
handleInstancesChanged = ({ id, instanceId }, name, toRemove) => {
const instances = this.state.instances;
if (toRemove) {
delete instances[instance];
this.store.liftedStore.deleteInstance(instance);
if (this.state.instance === instance) {
updateStoreInstance(null);
this.setState({ instance: null, shouldSync: false, instances });
return;
}
deleteInstance(id, (instance) => {
delete instances[instance];
this.store.liftedStore.deleteInstance(instance);
if (this.state.instance === instance) {
updateStoreInstance(null);
this.setState({ instance: null, shouldSync: false });
}
});
} else {
instances[instance] = name || instance;
startMonitoring(instance);
addInstance(id, instanceId);
instances[instanceId] = name || instanceId;
startMonitoring(instanceId);
}
this.setState({ instances });
};
Expand Down Expand Up @@ -154,7 +157,7 @@ export default class App extends Component {
<SyncToggle
on={this.state.shouldSync}
onClick={this.handleSyncToggle}
style={!this.state.instance && { display: 'none' }}
style={!this.state.instance ? { display: 'none' } : undefined}
/>
</div>
<DevTools
Expand Down
26 changes: 23 additions & 3 deletions src/app/services/messaging.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,38 @@ import socketOptions from '../constants/socketOptions';

let socket;
let channel;
const instancesConn = {};

export function addInstance(id, instanceId) {
if (!instancesConn[instanceId]) instancesConn[instanceId] = id;
}

export function deleteInstance(id, cb) {
Object.keys(instancesConn).some(instance => {
if (instancesConn[instance] === id) {
delete instancesConn[instance];
cb(instance);
return true;
}
});
}

export function dispatchRemotely(type, action, id, state) {
socket.emit(
id ? 'sc-' + id : 'respond',
id ? 'sc-' + instancesConn[id] : 'respond',
{ type, action, state }
);
}

export function dispatchSync(state, id) {
socket.emit(
'respond',
{ type: 'SYNC', id, state: stringify(state) }
{
type: 'SYNC',
id: instancesConn[id],
instanceId: id,
state: stringify(state)
}
);
}

Expand All @@ -40,7 +60,7 @@ export function subscribe(subscriber, options = socketOptions, onInstancesChange
} else data = req;

if (data.type === 'DISCONNECTED') {
onInstancesChanged(req.id, undefined, true);
onInstancesChanged({ id: req.id }, undefined, true);
return;
}
subscriber(data);
Expand Down
23 changes: 17 additions & 6 deletions src/app/store/updateState.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ function recompute(previousLiftedState, storeState, action, nextActionId = 1, is
}

export default function updateState(store, request, onInstancesChanged, instance, sync) {
if (request.type === 'START' && onInstancesChanged) onInstancesChanged(request.id, request.name);
let instanceId = request.instanceId || request.id;
if (request.type === 'START' && onInstancesChanged) {
onInstancesChanged(
{ id: request.id, instanceId },
request.name
);
}

const payload = parseJSON(request.payload);
if (typeof payload === 'undefined') return null;
Expand All @@ -34,7 +40,7 @@ export default function updateState(store, request, onInstancesChanged, instance
let action = {};
if (request.action) action = parseJSON(request.action) || {};

if (!instance) store.liftedStore.setInstance(request.id);
if (!instance) store.liftedStore.setInstance(instanceId);

switch (request.type) {
case 'INIT':
Expand All @@ -45,7 +51,7 @@ export default function updateState(store, request, onInstancesChanged, instance
);
break;
case 'ACTION':
const liftedState = store.liftedStore.getState(request.id);
const liftedState = store.liftedStore.getState(instanceId);
newState = recompute(
liftedState,
payload,
Expand All @@ -61,12 +67,17 @@ export default function updateState(store, request, onInstancesChanged, instance
return null;
}

store.liftedStore.setState(newState, request.id, () => {
store.liftedStore.setState(newState, instanceId, () => {
store.init(request);
if (onInstancesChanged) onInstancesChanged(request.id, request.name);
if (onInstancesChanged) {
onInstancesChanged(
{ id: request.id, instanceId },
request.name
);
}
});

if (sync && request.id === instance) sync(newState, instance);
if (sync && instanceId === instance) sync(newState, instance);

return newState;
}

0 comments on commit 77916c6

Please sign in to comment.