Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Commit

Permalink
Merge pull request #158 from grey-software/heroku
Browse files Browse the repository at this point in the history
Heroku
  • Loading branch information
Ali Raza authored Feb 8, 2020
2 parents a4742c3 + 15eb714 commit 7deb514
Show file tree
Hide file tree
Showing 12 changed files with 13,232 additions and 866 deletions.
6 changes: 4 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
- run:
name: "Publish Release on GitHub"
command: |
VERSION=0.3.0
VERSION=0.4.0
ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -b "Toonin Chrome extension build. To use, unzip and enable developer tools in chrome -> load unpacked -> select unzipped extension/build folder." -delete ${VERSION} /tmp/workspace/extension.zip
Deploy-App:
docker:
Expand Down Expand Up @@ -109,7 +109,9 @@ workflows:
- Build-App
filters:
branches:
only: master
only:
- master
- heroku
notify:
webhooks:
- url: https://outlook.office.com/webhook/04e18692-6efb-49e9-9028-139bf917ab16@78aac226-2f03-4b4d-9037-b46d56c55210/CircleCI/30437ffdcb3e400baa80214e81552edc/5b046f8c-07ba-4e2f-a006-653143830ede
961 changes: 285 additions & 676 deletions client/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import io from "socket.io-client";
Vue.config.productionTip = false;

// ATTN: Uncomment accordingly for local/remote dev
const ENDPOINT = "https://www.toonin.ml:8443/";
const ENDPOINT = "https://www.toonin.ml:443/";
const socket = io(ENDPOINT, { secure: true });
// var socket = io("http://127.0.0.1:8100");

Expand Down
137 changes: 137 additions & 0 deletions deployment/NetworkTree.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
class Queue {

constructor() { this.list = []; }

isEmpty() { return this.list.length === 0; }
enqueue(elem) { this.list.push(elem); }
dequeue() { if(!this.isEmpty()) { return this.list.shift(); } }
}

class NetworkNode {
constructor(socketID, maxClients) {
this.socketID = socketID;
this.maxClients = maxClients;
}
}

class NetworkTree {

constructor(socketID, maxClients) {
this.node = new NetworkNode(socketID, maxClients);
this.childNodes = [];
this.reconnectingNodes = []; // nodes (& their children) which are in process of reconnecting
}

hasSpace() { return this.childNodes.length < this.node.maxClients; }

/**
* Check if the client is joining the network back from a previous failure or
* if it is a new client. If joining back, return the reference to the saved tree in
* transferring nodes list with same socket id.
*
* @param {String} socketID socket id of the connecting client
* @returns {NetworkTree} the saved tree in transferring nodes list with same socket id at the root node
*/
isReconnecting(socketID) {
var returnNode = this.reconnectingNodes.filter((node) => node.socketID === socketID );
if(returnNode.length > 0) {
return returnNode[0];
}
return null;
}

/**
* Update nodes that their parent node is leaving and they need to reconnect to a new node in network
* The children (and their childNodes) are added to this.transferring nodes until they they
* join the tree again and are availible for new peers to connect
*
* @param {SocketIO.Server} socket Socket to notify children of leaving node about disconnection
* @param {NetworkTree} node Node that has been removed from the tree
* @param {String} room Room in which this node (and its children) exist
*/
notifyChildren(socket, node, room, root) {
var socketIDs = [];
node.childNodes.forEach((childNode) => {
socketIDs.push(childNode.node.socketID);
root.reconnectingNodes.push(childNode);
});

if(socketIDs.length > 0) { socket.to(room).emit("reconnect", { socketIDs }); }
}

/**
*
* @param {SocketIO.Server} socket Socket to notify children of leaving node about disconnection
* @param {String} socketID socketID of node that is leaving the tree
*/
removeNode(socket, socketID, room, root) {
if(this.childNodes.length === 0) { return; }
this.childNodes.forEach((node) => {
if(node.socketID === socketID) {
this.notifyChildren(socket, node, room, root);
} else {
node.removeNode(socket, socketID, room, root);
}
});
}

/**
*
* @param {String} socketID socket ID of the new client
* @param {Number} maxClients max client that this client can hold
* @param {String} hostSocketID socket ID of host to connect to
*
* @returns {Boolean} whether the node was successfully added to the tree or not
*/
addNode(socketID, maxClients, hostSocketID) {
const nodeQueue = new Queue();
nodeQueue.enqueue(this);

var currNode;
while(!nodeQueue.isEmpty()) {
currNode = nodeQueue.dequeue();
if(currNode.node.socketID === hostSocketID) {
// check if this node is trying to reconnect due to fallen host
const reconnectingNode = this.isReconnecting(socketID);
if(reconnectingNode !== null) {
currNode.childNodes.push(reconnectingNode);
this.reconnectingNodes.splice(this.reconnectingNodes.indexOf(reconnectingNode), 1);
return true;
}

// new node joining the tree
currNode.childNodes.push(new NetworkTree(socketID, maxClients));
return true;
}
currNode.childNodes.forEach((childNode) => nodeQueue.enqueue(childNode));
}

return false;
}

/**
* @returns {NetworkNode[]} array of possible hosts in order of preference
*/
getConnectableNodes() {
if(this.childNodes.length === 0) { return [this.node]; }

// list of networkNode that can accept clients in
// order of preference
const hostPool = [];

const nodeQueue = new Queue();
nodeQueue.enqueue(this);

while(!nodeQueue.isEmpty()) {
var currNode = nodeQueue.dequeue();

if(currNode.hasSpace()) { hostPool.push(currNode.node); }

currNode.childNodes.forEach((node) => nodeQueue.enqueue(node) );
}

return hostPool;
}
}

module.exports.NetworkTree = NetworkTree;
78 changes: 78 additions & 0 deletions deployment/RoomManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
const NetworkTree = require("./NetworkTree").NetworkTree;
const MAX_CLIENTS_PER_HOST = 3;

const genRoomID = (rooms) => {
for (;;) {
const id =
Math.random()
.toString(36)
.substring(2, 5) +
Math.random()
.toString(36)
.substring(2, 5);
if (!(id in rooms)) { return id; }
}
};

class Room {
constructor(roomID, room) {
this.roomID = roomID;
this.room = room;
}
}

class RoomManager {
constructor() {
this.rooms = [];
}

/**
* @param {SocketIO.Socket} socket
* @param {string} roomName
*/
createRoom(socket, roomName, isDistributed) {
var newRoomID = "";
console.log("Received request to create new room" + roomName);
const hasCustomRoomName = roomName.length > 0;

if (hasCustomRoomName) {

if (this.getRoom(roomName)) { socket.emit("room creation failed", "name already exists"); }
else {
newRoomID = roomName;
if(isDistributed) {
this.rooms.push(new Room(newRoomID, new NetworkTree(socket.id, MAX_CLIENTS_PER_HOST)));
} else { this.rooms.push(new Room(newRoomID, {})); }

socket.join(newRoomID, () => {
socket.emit("room created", newRoomID);
});
}

// if no custom room name, generate a random id
} else {
newRoomID = genRoomID(this.rooms);
if(isDistributed) {
this.rooms.push(new Room(newRoomID, new NetworkTree(socket.id, MAX_CLIENTS_PER_HOST)));
} else { this.rooms.push(new Room(newRoomID, {})); }
socket.join(newRoomID, () => {
socket.emit("room created", newRoomID);
});

}
}

getRoom(roomID) {
var returnRoom = this.rooms.filter((room) => room.roomID === roomID );
if(returnRoom.length > 0){
return returnRoom[0];
}
return null;
}

deleteRoom(roomID) {
this.rooms = this.rooms.filter((room) => room.roomID !== roomID );
}
}

module.exports.RoomManager = RoomManager;
Loading

0 comments on commit 7deb514

Please sign in to comment.