Last active
August 15, 2017 08:15
-
-
Save netroy/d4b7195adac3a1a35b4ad988970c96bd to your computer and use it in GitHub Desktop.
Soundcloud's follower-maze challenge in Javascript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This code could use comments, tests, & a million other things.. | |
// but since I did not apply at soundcloud, it doesn't matter | |
const net = require('net') | |
const split = require('split') | |
const PriorityQueue = require('priorityqueuejs') | |
const clients = {} | |
const followers = {} | |
const queue = new PriorityQueue((a, b) => b.sequence - a.sequence) | |
// QUEUE WORKER | |
const process = event => { | |
const { type, from, to, payload } = event | |
switch (type) { | |
case 'F': | |
if (to in clients) { | |
followers[to].add(from) | |
clients[to].write(payload + '\r\n') | |
} | |
break | |
case 'U': | |
if (to in followers) { | |
followers[to].delete(from) | |
} | |
break | |
case 'B': | |
Object.keys(clients).forEach(id => { | |
clients[id].write(payload + '\r\n') | |
}) | |
break | |
case 'P': | |
if (to in clients) { | |
clients[to].write(payload + '\r\n') | |
} | |
break | |
case 'S': | |
if (from in followers) { | |
followers[from].forEach(followerId => { | |
clients[followerId].write(payload + '\r\n') | |
}) | |
} | |
break | |
} | |
} | |
let index = 1 | |
const next = () => { | |
if (!queue.isEmpty()) { | |
const nextInQueue = queue.peek() | |
const nextIndex = nextInQueue.sequence | |
while (nextIndex == index) { | |
process(queue.deq()) | |
index++ | |
} | |
setImmediate(next) | |
} | |
} | |
// EVENTS | |
net.createServer(socket => { | |
socket.setEncoding('utf8') | |
socket.pipe(split()).on('data', payload => { | |
const [sequenceStr, type, from, to] = payload.split('|') | |
const sequence = parseInt(sequenceStr, 10) | |
if (!isNaN(sequence)) { | |
if (queue.isEmpty()) { | |
setImmediate(next) | |
} | |
queue.enq({ sequence, type, from, to, payload }) | |
} | |
}) | |
}).listen(9090) | |
// CLIENTS | |
net.createServer(client => { | |
client.setEncoding('utf8') | |
const stream = client.pipe(split()) | |
stream.once('data', id => { | |
const clientId = id.toString() | |
clients[clientId] = client | |
followers[clientId] = new Set() | |
console.log('registered', clientId) | |
client.once('close', () => { | |
console.log('deregistered', clientId) | |
delete clients[clientId] | |
delete followers[clientId] | |
}) | |
}) | |
}).listen(9099) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment