Skip to content

Instantly share code, notes, and snippets.

@graphnode
Forked from fxsjy/gist:3244607
Created August 3, 2012 13:25
Show Gist options
  • Save graphnode/3247695 to your computer and use it in GitHub Desktop.
Save graphnode/3247695 to your computer and use it in GitHub Desktop.
Simple Memcached server in Javascript with 100 lines of code
/* Simple Memcached in Javascript
* @Author: Sun, Junyi
* @Email: ccnusjy@gmail.com
* @Date: 2012-8-3
*/
var net = require('net');
var store = {}
function handle_header(header, crlf_len){
var tup = header.split(" ")
var expect_body_len = 0
switch(tup[0]) {
case 'get':
case 'delete':
expect_body_len = 0
break
case 'set':
expect_body_len = parseInt(tup[4]) + crlf_len
break
}
return expect_body_len
}
function handle_body(state, call_back){
var response
var tup = state.header.split(" ")
switch(tup[0]){
case 'get':
var key = tup[1]
var obj = store[key]
if(obj){
response = "VALUE "+ obj.key+" " + obj.flag+" " + obj.data.length + "\r\n" +
obj.data + "\r\n" +
"END\r\n"
}
else
response = "NOT_FOUND\r\n"
break;
case 'delete':
var key = tup[1]
delete store[key]
response = "DELETED\r\n"
break;
case 'set':
var obj = {key: tup[1], flag: tup[2], data: state.body}
store[obj.key] = obj
response = "STORED\r\n"
break;
default:
response = "ERROR\r\n"
break;
}
socket.write(response,"binary",call_back)
}
function processState(state) {
switch(state.id){
case "reading_header":
var pos = -1
if((pos = state.buf.indexOf('\r\n')) != -1){
state.header = state.buf.slice(0, pos)
state.buf = state.buf.slice(pos+2)
state.CRLF_LEN = 2
}
else if((pos = state.buf.indexOf('\n')) != -1){
state.header = state.buf.slice(0, pos)
state.buf = state.buf.slice(pos+1)
CRLF_LEN = 1
}
if(pos != -1){
state.id = 'reading_body'
state.expect_body_len = handle_header(state.header, CRLF_LEN)
processState(state)
}
break
case "reading_body":
if(state.expect_body_len <= state.buf.length){
state.body = state.buf.slice(0, state.expect_body_len - state.CRLF_LEN)
state.buf = state.buf.slice(state.expect_body_len)
handle_body(state, function(){
state.id = 'reading_header'
if(buf.length > 0)
processState(state)
})
}
break
}
}
var server = net.createServer(function (socket) {
console.log("client: ",socket.remoteAddress)
socket.setEncoding("binary")
var state = { id: 'reading_header', socket: socket, buf: "", header: "", body: "", expect_body_len: 0, CRLF_LEN: 2 }
socket.on('data',function(data){
buf += data
processState(state);
})
});
var port = 11211
console.log("listening at "+ port)
server.listen(port, '0.0.0.0')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment