Paxos based consensus framework.
| What | Where |
|---|---|
| Discussion | #1 |
| Documentation | https://bigeasy.github.io/compassion |
| Source | https://github.com/bigeasy/compassion |
| Issues | https://github.com/bigeasy/compassion/issues |
| CI | https://travis-ci.org/bigeasy/compassion |
| Coverage: | https://codecov.io/gh/bigeasy/compassion |
| License: | MIT |
Compassion installs from NPM.
npm install compassion
This README.md is also a unit test using the
Proof unit test framework. We'll use the
Proof okay function to assert out statements in the readme. A Proof unit test
generally looks like this.
require('proof')(4, async okay => {
okay('always okay')
okay(true, 'okay if true')
okay(1, 1, 'okay if equal')
okay({ value: 1 }, { value: 1 }, 'okay if deep strict equal')
})You can run this unit test yourself to see the output from the various code sections of the readme.
git clone git@github.com:bigeasy/compassion.git
cd compassion
npm install --no-package-lock --no-save
node test/readme.t.js
const Compassion = require('compassion')const Destructible = require('destructible')
const { Queue } = require('avenue')class KeyValueStore {
constructor () {
this.ready = new Promise(resolve => this.arrived = resolve)
this.cookie = 0
this.snapshots = {}
this.resolutions = {}
this.compassion = null
this.store = null
}
initialize (compassion) {
this.compassion = compassion
}
async bootstrap ({ self }) {
this.promise = self.arrived
this.store = {}
}
async snapshot ({ promise, queue }) {
queue.push(this.snapshots[promise])
}
async join ({ self, shifter }) {
this.promise = self.arrived
this.store = await shifter.shift()
}
async arrive ({ arrival }) {
this.arrived.call()
this.snapshots[arrival.promise] = JSON.parse(JSON.stringify(this.store))
}
async acclimated ({ promise }) {
this.snapshots[promise]
}
async entry ({ entry }) {
this.store[entry.key] = entry.value
const resolution = this.resolutions[entry.cookie]
if (resolution != null) {
delete this.resolutions[entry.cookie]
resolution.call(null)
}
}
async depart ({ promise }) {
this.snapshots[promise]
}
set (key, value) {
return new Promise(resolve => {
const cookie = `${this.promise}?${this.cookie++}`
this.resolutions[cookie] = resolve
this.compassion.enqueue({ cookie, key, value })
})
}
get (key) {
return this.store[key]
}
}const destructible = new Destructible('compassion')
Construct a census. Usually you'll use Mingle, but we'll create a dummy census and fake the service discovery. We have to be sure to terminate the queue on shutdown, so we register a destruct handler.
const census = new Queue
destructible.destruct(() => census.push(null))
const kv = new KeyValueStore
const { address, port } = await Compassion.listen(destructible, {
census: census.shifter(),
applications: { kv },
bind: { host: '127.0.0.1', port: 0 }
})
census.push([ `http://${address}:${port}` ])
await kv.ready
await kv.set('x', 1)
okay(kv.get('x'), 1, 'set and get')destructible.destroy()
await destructible.promise
What do we need to discuss? Simple outline. Be sure to link to people to Conference. Uh, oh. I also have to document Mingle.