Skip to content

Commit

Permalink
'first bits of %notify'
Browse files Browse the repository at this point in the history
  • Loading branch information
Duncan Cragg committed Oct 27, 2010
1 parent f52e232 commit aae3ba5
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 10 deletions.
6 changes: 6 additions & 0 deletions Makefile
Expand Up @@ -9,9 +9,15 @@ set-up-dbs:
cp fjord-tests-saved.db fjord.db
cp fjord-test-saved.db fjord-test.db

remove-dbs:
rm -f fjord.db fjord-test.db

run-tests: set-up-dbs run-test-server
( node language-tests.js; node observer-tests.js; node instrument-tests.js; node persistence-tests.js; node networking-tests.js ) | egrep Pass

run-obs-tests: remove-dbs
node observer-tests.js

run-ins-tests: set-up-dbs run-test-server pause
node instrument-tests.js

Expand Down
31 changes: 31 additions & 0 deletions doc/todo.txt
@@ -1,4 +1,9 @@

----------------------------------------------------------------------------------------------------
- changing %notify shouldn't set modified and increment etag
. needs .cachenotify to be remote notified!
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
- README.md

- 304 / Etag 0 if no client for object
Expand All @@ -20,3 +25,29 @@ use raw buffers.
----------------------------------------------------------------------------------------------------


----------------------------------------------------------------------------------------------------
- Keep string /and/ local link?
- JSON.stringify -vs- o.toString ??
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------
POST .. %unobserved: .. Etag bumped = 200, Etag same = 403
----------------------------------------------------------------
POST to subscribed object: scanned, Etag++ 200 return changed object
scanned, Etag 200 just return Etag
unscanned, Etag++ 200 return changed object
unscanned, Etag 403 just return Etag; not interested
----------------------------------------------------------------
- it's just initial set only, may drop by itself at any point but that is not interesting info
- initial set POSTs state immediately and retries till success
- how do GET and POST return codes get handled in Fjord, anyway?
- GET: 200, 303, 304, 401, 403, 404; POST: 200, 204, 303, 401, 403, 404, 405
- GET 4XX just looks like empty space, but link still stays - retry?
- POST 4XX link(s) stay in notifiables list - retry? not if 404/405, if 403, then only on re-set
---------
- local dependents are always notified
- so need locals and remote-C-N lists, separate from own-notifiables list
- local deps need to be notified to at least cover cache update distribution
- remove POSTed object from cache if 403 / 405 to prevent DoS
----------------------------------------------------------------
../net/forestbucks.txt
----------------------------------------------------------------
27 changes: 23 additions & 4 deletions fjord.js
Expand Up @@ -24,12 +24,17 @@ Cache.notifyRefsChanged = function(o){

Cache.notifyStateChanged = function(o){
var canos = {};
for(var owid in o.notify){
var or = this[owid];
if(!or.cachenotify) this.notifyLocal(owid);
else canos[or.cachenotify]=true;
}
for(var owid in o.refs){
var or = this[owid];
if(!or.cachenotify) this.notifyLocal(owid);
else canos[or.cachenotify]=true;
}
var canol = getTags(canos);
var canol = getTagsFromHash(canos);
if(canol.length) this.notifyStateRemote(o, canol);
}

Expand Down Expand Up @@ -78,7 +83,7 @@ Cache.pollObject = function(owid){
}

Cache.pollAndRefer = function(o){
Networking.get(o.url, o.etag, getTags(o.refs));
Networking.get(o.url, o.etag, getTagsFromHash(o.refs));
}

Cache.refShell = function(owid, url, cano){
Expand Down Expand Up @@ -153,6 +158,7 @@ function WebObject(content, rules){
this.owid = owid();
if(rules) this.rules = rules;
this.refs = {};
this.notify = {};
var isShell = !content;
if(isShell){
this.url=null;
Expand Down Expand Up @@ -214,14 +220,21 @@ WebObject.prototype.ensureRefs = function(refs){
}

WebObject.prototype.applyTo = function(that){

that.content["%owid"]=that.owid;
that.content["%etag"]=that.etag+"";
that.content["%refs"]=getTags(that.refs);
that.content["%refs"]=getTagsFromHash(that.refs);
that.content["%notify"]=getTagsFromHash(that.notify);

var applyjson=new Applier(this.content, that.content, { "%owid": that.owid }, that.newlinks).apply();
if(applyjson!=null && applyjson!==that.content){ that.content = applyjson; that.modified=true; }

that.notify=getHashFromTags(that.content["%notify"]);
delete that.content["%notify"];
delete that.content["%refs"];
delete that.content["%etag"];
delete that.content["%owid"];

return that;
}

Expand Down Expand Up @@ -528,12 +541,18 @@ function removeFrom(arr, item){
}
}

function getTags(o){
function getTagsFromHash(o){
var r=[];
for(var i in o) if(i.constructor===String) r.push(i);
return r;
}

function getHashFromTags(l){
var r={};
for(var i=0; i<l.length; i++) r[l[i]]=true;
return r;
}

function deepEqual(o1, o2){
var ok = false;
try{ assert.deepEqual(o1, o2); ok = true; }catch(e){}
Expand Down
6 changes: 5 additions & 1 deletion networking-tests.js
Expand Up @@ -104,7 +104,7 @@ response.addListener("end", function(){

test.isEqual("Test Server returned expected Javascript content",
body,
"O(\n{\"owid\":\"owid-ca0b-0a35-9289-9f8a\",\"refs\":{},\"outlinks\":{},\"etag\":1,\"content\":{\"tags\":\"one\",\"%refs\":{\"tags\":\"two\",\"state\":\"/number;$n/\"},\"state\":\"/number/fix(1,number($n)+0.1)/\"}}\n);\n"
"O(\n{\"owid\":\"owid-ca0b-0a35-9289-9f8a\",\"refs\":{},\"notify\":{},\"outlinks\":{},\"etag\":1,\"content\":{\"tags\":\"one\",\"%refs\":{\"tags\":\"two\",\"state\":\"/number;$n/\"},\"state\":\"/number/fix(1,number($n)+0.1)/\"}}\n);\n"
);

// -------------------------------------------------------------------
Expand Down Expand Up @@ -150,6 +150,7 @@ process.addListener("exit", function () {
test.jsonEqual("Full o1 is now in place", Cache[o1],
{"owid":o1,
"refs": expectedRefs,
"notify": {},
"url":"http://localhost:24589/fjord/"+o1+".json",
"cachenotify":"http://localhost:24589/fjord/cache-notify",
"etag":52,
Expand All @@ -160,6 +161,7 @@ process.addListener("exit", function () {
{"owid":o2,
"rules": rules2,
"refs": expectedOutlinks,
"notify": {},
"outlinks":expectedOutlinks,
"etag":52,
"content":{ "tags": "two", "state": "done", "o1": o1 },
Expand All @@ -169,6 +171,7 @@ process.addListener("exit", function () {
{"owid":o3,
"rules": rules3,
"refs": expectedOutlinks,
"notify": {},
"outlinks":expectedOutlinks,
"etag":52,
"content":{ "tags": "thr", "state": "10.1", "o1": o1 },
Expand All @@ -178,6 +181,7 @@ process.addListener("exit", function () {
{"owid":o4,
"rules": rules4,
"refs": expectedOutlinks,
"notify": {},
"outlinks":expectedOutlinks,
"etag":52,
"content":{ "tags": "fou", "state": "10.1", "o1": o1 },
Expand Down
29 changes: 24 additions & 5 deletions observer-tests.js
@@ -1,5 +1,5 @@

var sys = require('sys');
var sys = require('sys');
var assert = require('assert');

var test = require('./simple-test');
Expand All @@ -9,9 +9,32 @@ var log = fjord.log;
var WebObject = fjord.WebObject;
var Cache = fjord.Cache;

WebObject.logUpdates=true;


sys.puts('------------------ Fjord Observer Tests ---------------------');

// -------------------------------------------------------------------
/*
r21 = WebObject.create('{ "tags": "two", "state": "/21/22/", "o1": { "%owid": "/$o1/", "state": "11" }, "%notify": "//has($o1)/" }');
r22 = WebObject.create('{ "tags": "two", "state": "/22/23/", "o1": { "state": "12" } }');
r11 = WebObject.create('{ "tags": "one", "state": "/11/12/", "%notified": { "tags": "two", "state": "22" } }');
r12 = WebObject.create('{ "tags": "one", "state": "/12/13/", "%notified": { "tags": "two", "state": "23" } }');
o1 = WebObject.create('{ "tags": "one", "state": "11" }', [ r11, r12 ] );
o2 = WebObject.create('{ "tags": "two", "state": "21", "o1": "'+o1+'" }', [ r21, r22 ] );
test.objectsEqual("Double Observer ping-pong worked on o1",
Cache[o1], new WebObject('{ "tags": "one", "state":"13" }'));
test.objectsEqual("Double Observer ping-pong worked on o2",
Cache[o2], new WebObject('{ "tags": "two", "state":"23", "o1":"'+o1+'" }'));
test.isTrue("Etag of o1 now 3", Cache[o1].etag===3);
test.isTrue("Etag of o2 now 3", Cache[o2].etag===3);
*/
// -------------------------------------------------------------------

r11 = WebObject.create('{ "tags": "one", "state": "/11/12/", "%refs": { "tags": "two", "state": "22" } }');
Expand Down Expand Up @@ -85,8 +108,6 @@ test.isTrue("Etag of o3 now 3", Cache[o3].etag===4);

// -------------------------------------------------------------------

WebObject.logUpdates=true;

r11 = WebObject.create('{ "tags": "one", "state": "/11/12/", "%refs": [ { "state": "22" }, { "state": "32" } ] }');
r12 = WebObject.create('{ "tags": "one", "state": "/12/13/", "%refs": [ { "state": "23" }, { "state": "33" } ] }');
r13 = WebObject.create('{ "tags": "one", "state": "/13/14/", "%refs": [ { "state": "24" }, { "state": "33" } ] }');
Expand Down Expand Up @@ -116,8 +137,6 @@ test.objectsEqual("State of o3 gets to 33",

// -------------------------------------------------------------------

WebObject.logUpdates=true;

r11 = WebObject.create('{ "tags": "one", "state": "/11/12/", "%refs": [ { "state": "22" }, { "state": "32" } ] }');
r12 = WebObject.create('{ "tags": "one", "state": "/12/13/", "%refs": [ { "state": "23" } ] }');
r13 = WebObject.create('{ "tags": "one", "state": "/13/14/", "%refs": [ { "state": "24" } ] }');
Expand Down

0 comments on commit aae3ba5

Please sign in to comment.