From d46d6fdd4b578f4b0bac7d557d598178013756bc Mon Sep 17 00:00:00 2001 From: mcmlxxix <> Date: Fri, 13 Apr 2012 16:04:33 +0000 Subject: [PATCH] fix release() method bug, remove invalid requests from queue (should never occur, really), add array slice() method --- exec/load/json-client.js | 17 +++++++- exec/load/json-db.js | 92 +++++++++++++++++++++++++++------------- 2 files changed, 79 insertions(+), 30 deletions(-) diff --git a/exec/load/json-client.js b/exec/load/json-client.js index 2f0a7826fb..fb17236a0d 100644 --- a/exec/load/json-client.js +++ b/exec/load/json-client.js @@ -74,7 +74,7 @@ function JSONClient(serverAddr,serverPort) { throw("no port specified"); this.settings={ - CONNECTION_TIMEOUT: 5, + CONNECTION_TIMEOUT: 10, PING_INTERVAL: 60*1000, PING_TIMEOUT: 10*1000, SOCK_TIMEOUT: 10*1000, @@ -151,6 +151,21 @@ function JSONClient(serverAddr,serverPort) { }); return this.wait(); } + + /* array slice method */ + this.slice=function(scope,location,start,end,lock) { + this.send(scope,"QUERY",{ + oper:"SLICE", + location:location, + data:{ + start:start, + end:end + }, + lock:lock, + timeout:this.settings.TIMEOUT + }); + return this.wait(); + } /* read multiple object data (lock for reading or writing, blocking) */ /* readmulti([['tw2','sector.1',undefined,'sector'],['tw2','planets.1',undefined,'planet']]); */ diff --git a/exec/load/json-db.js b/exec/load/json-db.js index ed0b22ffbc..3f294acb80 100644 --- a/exec/load/json-db.js +++ b/exec/load/json-db.js @@ -52,7 +52,10 @@ function JSONdb (fileName) { this.queue={}; /* general list of db subscribers (for quick release if no subscriptions) */ - this.subscriptions=[]; + this.subscriptions={}; + + /* list of disconnected clients */ + this.disconnected={}; /* database settings */ this.settings={ @@ -89,7 +92,8 @@ function JSONdb (fileName) { UNSUBSCRIBE:9, WHO:10, STATUS:11, - KEYS:12 + KEYS:12, + SLICE:13 } /* error constants */ @@ -117,10 +121,15 @@ function JSONdb (fileName) { } if(!this.subscriptions[client.id][record.location]) { record.shadow[record.child_name]._subscribers[client.id]=client; - this.subscriptions[client.id][record.location] = record; + this.subscriptions[client.id][record.location]=record; + record.subtime = Date.now(); send_subscriber_updates(client,record,"SUBSCRIBE"); } else { + log(LOG_WARNING, + client.id + "@" + + this.subscriptions[client.id][record.location].subtime + ": " + + record.location); this.error(client,errors.DUPLICATE_SUB); } return true; @@ -353,6 +362,31 @@ function JSONdb (fileName) { } } + /* shift a record off the end of an array */ + this.slice = function(request,record) { + var client = request.client; + /* if the requested data does not exist, result is undefined */ + if(record.data === undefined) { + send_packet(client,undefined,"RESPONSE"); + return true; + } + /* if this client has this record locked */ + else if(record.info.lock[client.id]) { + if(record.data[record.child_name] instanceof Array) { + var d = record.data[record.child_name].slice(request.data.start,request.data.end); + send_packet(client,d,"RESPONSE"); + } + else { + this.error(client,errors.NON_ARRAY); + } + return true; + } + /* if there is no lock for this client, error */ + else { + return false; + } + } + /* server's data submission method (not directly called by client) */ this.write = function(request,record) { var client = request.client; @@ -600,24 +634,9 @@ function JSONdb (fileName) { /* schedule client for subscription and lock release */ this.release = function(client) { - if(!this.queue[client.id]) - this.queue[client.id] = []; - this.queue[client.id].push(new Request(client,"CLOSE")); + this.disconnected[client.id] = client; } - /* release any locks or subscriptions held by a disconnected client */ - this.close = function(client) { - /* release any locks the client holds */ - free_prisoners(client,this.shadow); - - /* release any subscriptions the client holds */ - cancel_subscriptions(client,this.subscriptions[client.id]); - - /* remove any remaining client queries */ - fuh_queue(client,this.queue); - return true; - }; - /* main "loop" called by server */ this.cycle = function() { /* process request queue, removing successful operations */ @@ -630,17 +649,9 @@ function JSONdb (fileName) { var request=this.queue[c][r]; var result=false; - /* if we have been asked to clear a client's locks, DEW IT */ - if(request.oper.toUpperCase() == "CLOSE") { - this.queue[c].splice(r--,1); - this.close(request.client); - break; - } - /* locate the requested record within the database */ var record=identify_remains.call( - this,request.client,request.parent_name,request.child_name, - request.oper.toUpperCase() == "WRITE" + this,request.client,request.parent_name,request.child_name ); /* if there was an error parsing object location, delete request */ @@ -673,6 +684,9 @@ function JSONdb (fileName) { case "UNSHIFT": result=this.unshift(request,record); break; + case "SLICE": + result=this.slice(request,record); + break; case "DELETE": result=this.remove(request,record); break; @@ -691,6 +705,10 @@ function JSONdb (fileName) { case "WHO": result=this.who(request,record); break; + default: + this.error(client,errors.INVALID_REQUEST); + this.queue[c].splice(r--,1); + break; } /* if the request did not succeed, move to the next user queue */ @@ -699,6 +717,22 @@ function JSONdb (fileName) { this.queue[c].splice(r--,1); } } + + /* terminate any disconnected clients after processing queue */ + for each(var c in this.disconnected) { + /* release any locks the client holds */ + free_prisoners(client,this.shadow); + + /* release any subscriptions the client holds */ + cancel_subscriptions(client,this.subscriptions[client.id]); + + /* remove any remaining client queries */ + fuh_queue(client,this.queue); + } + + /* reset disconnected client object */ + this.disconnected={}; + if(!this.settings.UPDATES) return; if(!this.settings.SAVE_INTERVAL > 0) @@ -779,7 +813,7 @@ function JSONdb (fileName) { /* parse an object location name and return the object (ex: dicewarz2.games.1.players.1.tiles.0) an object containing the corresponding data and its shadow object */ - function identify_remains(client,parent_name,child_name,create_new) { + function identify_remains(client,parent_name,child_name) { var data=this.data; var shadow=this.shadow; -- GitLab