@feedloop/foundry v0.3.0
FOUNDRY
Provides commonly-used data structures suitable for distributed applications thanks to foundationdb.
Usage
Installation
Before installing the package, you need to install the foundationdb client on your machine. Please follow this guide to install it.
Install foundry with your package manager:
Using npm
npm install --save @feedloop/foundry
Using yarn
yarn add @feedloop/foundry
Initialization
Foundry uses nodejs foundationdb client that looks for configs in several ways.
Set FDB_API_VERSION to your environment variable to select the foundationdb api version, defaults to version 620.
import Foundry from "@feedloop/foundry";
// somewhere in your async scope
const foundry = await Foundry.init("your-database-name");
Usage
import { Set } from "@feedloop/foundry";
// somewhere in your async scope
const hasBar = await foundry.exec(async (factory) => {
const set = factory.open(Set, "my-set");
await set.add("foo", "bar", "baz");
return set.has("bar");
});
// hasBar will be `true`
All foundry's operations must be run within the foundry.exec
scope because they will run in the same transaction. Each transaction will be re-run when a conflict is detected, so keep it simple to reduce client overhead.
Available Data Structures
Foundry provides commonly used data structures suitable for distributed applications by utilizing foundationdb's transaction excellence.
List
import { List } from "@feedloop/foundry";
// somewhere in your async scope
await foundry.exec(async (factory) => {
const list = factory.open<List<string>>(List, "list1");
await list.push("a", "b", "c"); // ["a", "b", "c"]
const secondItem = await list.at(1); // returns "b"
const last = await list.pop(); // returns "c"
const len = await list.length(); // returns 2
});
Set
import { Set } from "@feedloop/foundry";
// somewhere in your async scope
await foundry.exec(async (factory) => {
const set = factory.open(Set, "my-set");
await set.add("foo", "bar", "baz"); // ["foo", "bar", "baz"]
await set.remove("bar"); // ["foo", "baz"]
await set.size(); // 2
});
Map
import { Map } from "@feedloop/foundry";
// somewhere in your async scope
await foundry.exec(async (factory) => {
const map = factory.open(Map, "my-map");
await map.set("foo", 1); // {foo: 1}
await map.set("bar", 2); // {foo: 1, bar: 2}
await map.delete("bar"); // {bar: 2}
await map.size(); // 2
});
PersistentQueue
import { PersistentQueue } from "@feedloop/foundry";
// somewhere in your async scope
await foundry.exec(async (factory) => {
const queue = factory.open(PersistentQueue, "my-queue");
await queue.write("foo"); // ["foo"]
await queue.write("bar"); // ["foo", "bar"]
// reader1 consuming messages
await queue.read("reader1", 1, true); // returns ["foo"]
await queue.readOffset("reader1"); // returns 1
await queue.read("reader1", 1, true); // returns ["bar"]
await queue.read("reader1", 1, true); // returns []
await queue.readOffset("reader1"); // returns 2
// reader2 consuming messages
await queue.read("reader2", 2, true); // returns ["foo", "bar"]
await queue.read("reader2", 2, true); // returns []
await queue.size(); // return 2
});
CronJob
import { CronJob } from "@feedloop/foundry";
// somewhere in your async scope
// set a cron schedule
await foundry.exec(async (factory) => {
const cronjob = factory.open(CronJob, "my-cronjob");
// At every 5th minute (https://crontab.guru/#*/5_*_*_*_*)
await cronjob.schedule("5 * * * *");
});
// setup a polling to check for jobs
setInterval(async () => {
const hasJob = await foundry.exec(async (factory) => {
const cronjob = factory.open(CronJob, "my-cronjob");
return cronjob.take();
});
if (hasJob) {
console.log("I have a job!"); // will run at every 5th minute
}
}, 1000 * 60); // run every 1 minute