Project Name | Stars | Downloads | Repos Using This | Packages Using This | Most Recent Commit | Total Releases | Latest Release | Open Issues | License | Language |
---|---|---|---|---|---|---|---|---|---|---|
Sheetjs | 33,584 | 4,379 | 3,816 | 2 months ago | 170 | March 24, 2022 | 129 | apache-2.0 | JavaScript | |
📗 SheetJS Spreadsheet Data Toolkit -- New home https://git.sheetjs.com/SheetJS/sheetjs | ||||||||||
Faust | 6,501 | 14 | 16 | 7 months ago | 46 | February 25, 2020 | 280 | other | Python | |
Python Stream Processing | ||||||||||
Pg_shard | 1,065 | 7 years ago | 39 | lgpl-3.0 | C | |||||
ATTENTION: pg_shard is superseded by Citus, its more powerful replacement | ||||||||||
Risingstack Bootcamp | 701 | 5 years ago | 2 | JavaScript | ||||||
This is the Node.js Bootcamp we ask new recruits at RisingStack to finish in their first weeks. It helps to get the basics right, and prepare you to work on enterprise projects. | ||||||||||
Dht | 658 | 6 months ago | 6 | mit | C | |||||
BitTorrent DHT library | ||||||||||
Notablog | 604 | 1 | 3 days ago | 30 | June 22, 2022 | 20 | mit | TypeScript | ||
Tell stories of your work with Notion | ||||||||||
Cli Table3 | 433 | 25,935 | 1,027 | 6 months ago | 7 | September 15, 2022 | 34 | mit | JavaScript | |
Pretty unicode tables for the command line | ||||||||||
Nodejs Bigquery | 431 | 298 | 176 | a day ago | 78 | September 08, 2022 | 23 | apache-2.0 | TypeScript | |
Node.js client for Google Cloud BigQuery: A fast, economical and fully-managed enterprise data warehouse for large-scale data analytics. | ||||||||||
Ttf.js | 397 | 4 years ago | 3 | JavaScript | ||||||
JavaScript font library for Node.js and browser. | ||||||||||
Sheetdown | 310 | 8 years ago | 8 | July 27, 2015 | 3 | other | JavaScript | |||
:page_with_curl: :arrow_down: Convert a Google Spreadsheet into a Table in Markdown |
Subotai is a Kademlia based distributed hash table. It's designed to be easy to use, safe and quick. Here are some of the ideas that differentiate it from other DHTs:
Externally synchronous, internally concurrent: All public methods are blocking and return a sane result or an explicit timeout. Internally however, subotai is fully concurrent, and parallel operations will often help each other complete.
Introduce nodes first, resolve conflicts later: Subotai differs to the original Kademlia
implementation in that it gives temporary priority to newer contacts for full buckets. This
makes the network more dynamic and capable to adapt quickly, while still providing protection
against basic DDoS
attacks in the form of a defensive state.
Flexible storage: Every key in the key space can hold any number of different entries with independent expiration times.
Impatient: Subotai is "impatient", in that it will attempt to never wait for responses from an unresponsive node. Queries are sent in parallel where possible, and processes continue when a subset of nodes have responded.
Subotai supports automatic key republishing, providing a good guarantee that an entry will remain in the network until a configurable expiration date. Manually storing the entry in the network again will refresh the expiration date.
Subotai also supports caching to balance intense traffic around a given key.
Let's say we have this code running on a machine:
fn main() {
let node = node::Node::new().unwrap();
// We join the network through the address of any live node.
let seed = net::SocketAddr::from_str("192.168.1.100:50000").unwrap();
node.bootstrap(&seed);
// We store a key->data pair.
let my_key = hash::SubotaiHash::sha1("example_key");
let my_data = vec![0u8,1,2,3,4,5];
node.store(my_key, node::StorageEntry::Blob(my_data));
}
As long as there is a minimum amount of nodes in the network (a configurable amount, deemed sufficient for the network to be considered alive), we have successfully stored data in the table.
Now, on a machine very, very far away...
fn main() {
let node = node::Node::new().unwrap();
// We join the same network (can be on a different node).
let seed = net::SocketAddr::from_str("192.168.1.230:40000").unwrap();
node.bootstrap(&seed);
// We retrieve all entries for the same key.
let my_key = hash::SubotaiHash::sha1("example_key");
let retrieved_entries = node.retrieve(&my_key).unwrap();
// We get what we stored. In O(log n) number of steps, of course!
assert_eq!(retrieved_entries.len(), 1);
let expected_data = vec![0u8,1,2,3,4,5];
assert_eq!(*retrieved_entries.first().unwrap(), node::StorageEntry::Blob(expected_data));
}
Subotai is feature complete, but in early stages of testing. I focused on making the API as stable as possible (partly by handling all configuration through a factory, to prevent new configuration options from becoming breaking changes) and providing a baseline of features for practical applications to be built on top of it.
Even though every feature is unit tested, the network hasn't yet been tested in real world conditions. I'd really appreciate any experiments! Just make sure not to use it for anything critical just yet :).
Subotai's unit test suite is somewhat fiddly, since the library uses timeouts pervasively in order to make
decisions. This means that, unless you're running a very powerful machine, you should run cargo test
with
RUST_TEST_THREADS=1
. Otherwise, an excessive number of tests in parallel may create timeouts all over the
place, causing the network to mistake nodes as dead.