Create deltas class, mature multiwrite for retries
parent
fc438a55f8
commit
da08be0285
127
nullboard.html
127
nullboard.html
|
|
@ -1106,7 +1106,7 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class=logo>
|
<div class=logo>
|
||||||
<a href=https://nullboard.io>Nullboard</a>
|
<a href=https://nullboard.io>Nullboard <span id="pending"></span></a>
|
||||||
<div class=bulk>
|
<div class=bulk>
|
||||||
<a href=# class=view-about>About</a>
|
<a href=# class=view-about>About</a>
|
||||||
<a href=# class=view-license>License</a>
|
<a href=# class=view-license>License</a>
|
||||||
|
|
@ -1237,6 +1237,38 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Deltas {
|
||||||
|
constructor(database)
|
||||||
|
{
|
||||||
|
this.database = new NamespacedDatabase("deltas", database);
|
||||||
|
}
|
||||||
|
|
||||||
|
length()
|
||||||
|
{
|
||||||
|
var n = 0;
|
||||||
|
this.database.forEach((k) => { n += 1; });
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
push(key)
|
||||||
|
{
|
||||||
|
this.database.set(key, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pop(key)
|
||||||
|
{
|
||||||
|
this.database.del(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
popEach(foo)
|
||||||
|
{
|
||||||
|
this.database.forEach((key) => {
|
||||||
|
foo(key);
|
||||||
|
this.database.del(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class MultiDatabase extends Database {
|
class MultiDatabase extends Database {
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
|
|
@ -1250,24 +1282,97 @@
|
||||||
{
|
{
|
||||||
this.databases.push(arguments[i]);
|
this.databases.push(arguments[i]);
|
||||||
}
|
}
|
||||||
|
this.deltas = new Deltas(this.primary());
|
||||||
|
this.scheduleSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
primary()
|
||||||
|
{
|
||||||
|
return this.databases[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
replicas()
|
||||||
|
{
|
||||||
|
return this.databases.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduleSync()
|
||||||
|
{
|
||||||
|
setInterval(() => { this.sync(); }, 15 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
sync()
|
||||||
|
{
|
||||||
|
console.log("syncing to replicas: " + this.pendingSyncCount());
|
||||||
|
this.deltas.popEach((k) => {
|
||||||
|
console.log("syncing to replicas: " + k);
|
||||||
|
this.replicate(k);
|
||||||
|
});
|
||||||
|
console.log("synced to replicas: " + this.pendingSyncCount());
|
||||||
|
this.writePendingSyncCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingSyncCount()
|
||||||
|
{
|
||||||
|
return this.deltas.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
writePendingSyncCount()
|
||||||
|
{
|
||||||
|
var n = this.pendingSyncCount();
|
||||||
|
var s = "(" + n + ")";
|
||||||
|
if (! n)
|
||||||
|
s = ""
|
||||||
|
document.getElementById("pending").innerHTML = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
replicate(k)
|
||||||
|
{
|
||||||
|
var v = this.primary().get(k);
|
||||||
|
this.replicas().forEach((database) => {
|
||||||
|
if (v)
|
||||||
|
database.set(k, v);
|
||||||
|
else
|
||||||
|
database.del(k, v);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get(key) {
|
get(key) {
|
||||||
return this.databases[0].get(key);
|
return this.primary().get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
set(key, value)
|
set(key, value)
|
||||||
{
|
{
|
||||||
this.databases.forEach((database) => {
|
this.primary().set(key, value);
|
||||||
database.set(key, value);
|
this.deltas.push(key);
|
||||||
});
|
try
|
||||||
|
{
|
||||||
|
this.replicas().forEach((database) => {
|
||||||
|
database.set(key, value);
|
||||||
|
});
|
||||||
|
this.deltas.pop(key);
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
console.log("failed to replicate set: " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
del(key)
|
del(key)
|
||||||
{
|
{
|
||||||
this.databases.forEach((database) => {
|
this.primary().del(key);
|
||||||
database.del(key, value);
|
this.deltas.push(key);
|
||||||
});
|
try
|
||||||
|
{
|
||||||
|
this.replicas().forEach((database) => {
|
||||||
|
database.del(key);
|
||||||
|
});
|
||||||
|
this.deltas.pop(key);
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
console.log("failed to replicate del: " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
forEach(foo)
|
forEach(foo)
|
||||||
|
|
@ -1290,7 +1395,7 @@
|
||||||
{
|
{
|
||||||
if (key.startsWith(this.namespace + "."))
|
if (key.startsWith(this.namespace + "."))
|
||||||
return key.slice(this.namespace.length + 1);
|
return key.slice(this.namespace.length + 1);
|
||||||
return key;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix(key)
|
prefix(key)
|
||||||
|
|
@ -1319,7 +1424,8 @@
|
||||||
{
|
{
|
||||||
this.database.forEach((key) => {
|
this.database.forEach((key) => {
|
||||||
var k = this.deprefix(key);
|
var k = this.deprefix(key);
|
||||||
foo(k);
|
if (k)
|
||||||
|
foo(k);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1367,7 +1473,6 @@
|
||||||
new NamespacedDatabase("A", new Local()),
|
new NamespacedDatabase("A", new Local()),
|
||||||
new NamespacedDatabase("B", new Local()),
|
new NamespacedDatabase("B", new Local()),
|
||||||
);
|
);
|
||||||
globalStorage = new NamespacedDatabase("B", new Local());
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* poor man's error handling -- $fixme
|
* poor man's error handling -- $fixme
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue