Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add iroh-sync and integrate into iroh node #1333

Merged
merged 144 commits into from
Aug 24, 2023
Merged

feat: add iroh-sync and integrate into iroh node #1333

merged 144 commits into from
Aug 24, 2023

Conversation

Frando
Copy link
Member

@Frando Frando commented Aug 4, 2023

Description

This PR adds iroh-sync, a document synchronization protocol, to iroh, and integrates with iroh-net, iroh-gossip and iroh-bytes.

  • At the core is the iroh-sync crate, with a set reconciliation algorithm implemented by @dignifiedquire. See the old iroh-sync repo for the prehistory and [WIP] feat: iroh-sync #1216 for the initial PR (fully included in this PR, and by now outdated)
  • Iroh sync is integrated in the iroh node, with iroh-gossip, in the RPC interface, and the CLI.
    • LiveSync is the handle to an actor that integrates sync with gossip to broadcast and receive document updates from peers. For each open document a gossip swarm is joined with a TopicId derived from the doc namespace.
    • mod download contains the new downloader. It will be improved in feat(iroh): downloader #1344 .
    • mod client is the new high-level RPC client. It currently only has methods for dealing with docs and sync, other things should be added once we merged this. CLI commands for sync are in commands/sync.rs. Will be much better with feat: Iroh console (REPL) and restructured CLI #1356 .
    • examples/sync.rs has a REPL to modify and sync docs. It does a full setup without using the iroh console. Also includes code to sync directories, and a hammer command for load testing.
  • The PR also introduces iroh::client::Iroh, a wrapper around the RPC client, and iroh::client::Doc, a wrapper around RPC client for a single document

Notes & open questions

Should likely happen before merge:

  • Make iroh_sync::Store:::list_authors and list_replicas return iterators iroh-sync *fixed in iroh-sync API cleanup & docs #1366 *
  • Add iroh_sync::Store::close_replica
  • ContentStatus in on_insert callback is reported as Ready if the content is still baomap::PartialEntry (in-process download) fixed in a8e8093

Can happen after merge, but before 0.6 release

  • Implement AuthorImport and AuthorShare RPC & CLI commands
  • sync store list_namespaces and list_authors internally collect, return iterator instead
  • Fix cross-compiles to arm/android. See On arm/android a zero initialized vec is not actually filled with zeros cross-rs/cross#1311
  • Ensure that fingerpring calculation is efficient and/or cached for large documents. Currently calculating the initial fingerprint iterates once over all entries in a document.
  • Make content downloads be more reliable
    • Add some way to download content from peers independent of the first insertion event for a remote entry. The downloader with retries is tracked in Downloader for iroh-bytes #1334 and 1344, but independent of that, we still would currently only ever try to queue a download when the on_insert callback triggers, which is only once. There should be a way, even if manual for now, to try to download missing content in a replica from peers.
    • during iroh-sync sync include info if content is available for each entry
  • Add basic peer management and persistence. Currently live sync will stop to do anything after a node restart.
    • Persist the addressbook of peers for a document, to reconnect when restarting the node
    • Implement PeerAdd and PeerList RPC & CLI commands. The latter needs changes in iroh-net to expose information of currently-connected peers and their peer info.
  • Make read-only replicas possible
  • Improve reliablity of replica sync.
    • sync is triggered on each NeighborUp event from gossip. check that we don't sync too much.
    • maybe include peer info in gossip messages, to queue syncs with those (but not all at once)
    • track and exchange the timestamp of last full sync for peers, to know if you missed gossiped message and react accordingly
    • add more tests with peers coming and leaving

Open questions

  • iroh_sync::EntrySignature should the signatures include a namespace prefix?
  • do we want the 1:1 mapping of NamespaceIdand gossip TopicId, or would the topic id as a hash be better?

Other TODOs collected from the code

  • Port hammer and fs commands from REPL example to iroh cli
  • docs/naming: settle terminology about keypairs, private/secret/signing keys, public keys/identifiers and make docs and symbols consistent
  • Make bytes_get streaming in the RPC interface
  • Allow to unset the subscription on a replica
  • iroh-sync shouldn't depend on iroh-bytes only for Hash type -> Iroh-common base library #1354
  • * [ ] Move sync::live::PeerSource to iroh-net or even better -> Iroh-common base library #1354
  • StoreInstance::put propagate error and verify timestamp is reasonable.
  • StoreInstance::get_range implement inverted range
  • iroh_sync: Remove some items only used in tests (marked with #[cfg(test)])
  • iroh_sync fs store: verify get method fetches all keys with this namespace
  • ranger::SimpleStore::get_range: optimize
  • ranger::Peer avoid allocs?
  • fs::StoreInstance::get_fingerprint optimize
  • SyncEngine::doc_subscribe remove unwrap, handle error

Change checklist

  • Self-review.
  • Documentation updates if relevant.
  • Tests if relevant.

@Frando Frando changed the base branch from main to sync-gossip-bytes August 4, 2023 17:03
@Frando Frando changed the base branch from sync-gossip-bytes to sync-db August 4, 2023 17:03
@Frando Frando changed the base branch from sync-db to sync-gossip-bytes August 8, 2023 09:03
@Frando Frando changed the base branch from sync-gossip-bytes to main August 10, 2023 11:19
@Frando Frando changed the title [WIP] Sync integration feat: add iroh-sync and integrate into iroh node Aug 10, 2023
Frando and others added 18 commits August 14, 2023 12:33
* removes content support from iroh-sync
* adds a quick-and-dirty writable database to iroh-bytes (will be
  replaced with a better generic writable database soon)
* adds a `Downloader` to queue get requests for individual hashes from
  individual peers
* adds a `BlobStore` that combines the writable db with the downloader
* adds a `Doc` abstraction that combines an iroh-sync `Replica` with a
  `BlobStore` to download content from peers on-demand
* updates the sync repl example to plug it all together
* also adds very basic persistence to `Replica` (encode to byte string)
  and uses this in the repl example
* make the REPL in the sync example work properly with rustyline for
  editing and reading input, shell-style argument parsing and clap for
  parsing commands
* add a docs store for opening and closing docs
* add author to doc struct
uses flume channels to allow for combined sync and async usage
Frando and others added 10 commits August 24, 2023 10:21
## Description

So far in #1333, if a RPC or in-memory client called `doc.subscribe()`
the event callback would never be dropped, even if the client did drop
the event stream. This PR fixes this, by having the event callbacks
return whether the callback should stay active or not. We can't use the
removal token here, because calling `LiveSync::unsubscribe` from within
the event callback would deadlock the actor.

Also adds a a `LiveStatus` to the doc info RPC call. For now only
contains the number of subscribers. More info, e.g. on peers, can come
later.

## Notes & open questions

* As of #1333 and unchanged by this PR: `doc.subscribe` will fail for
documents that are not in the `LiveSync` (they are added via
`doc.import` or `doc.start_sync`). This is unfortunate, because you'd
often want to setup a subscription before starting sync, to catch all
events.

## Change checklist

- [x] Self-review.
- [x] Documentation updates if relevant.
- [x] Tests if relevant.
switches to also use tokio::codec under the hood now.

Also introduces a max message length of 1GiB for now.
Copy link
Contributor

@dignifiedquire dignifiedquire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a long time coming, and finally a big PR that is not from me <3

@Frando Frando enabled auto-merge August 24, 2023 17:02
@b5
Copy link
Member

b5 commented Aug 24, 2023

Screenshot 2023-08-24 at 1 07 10 PM

@Frando Frando added this pull request to the merge queue Aug 24, 2023
Merged via the queue into main with commit 3f141be Aug 24, 2023
15 checks passed
@Frando Frando mentioned this pull request Sep 18, 2023
29 tasks
@dignifiedquire dignifiedquire deleted the sync-integration branch November 1, 2023 14:26
matheus23 pushed a commit that referenced this pull request Nov 14, 2024
## Description

This PR adds `iroh-sync`, a document synchronization protocol, to iroh,
and integrates with `iroh-net`, `iroh-gossip` and `iroh-bytes`.

* At the core is the `iroh-sync` crate, with a set reconciliation
algorithm implemented by @dignifiedquire. See [the old iroh-sync
repo](https://github.com/n0-computer/iroh-sync/) for the prehistory and
#1216 for the initial PR (fully included in this PR, and by now
outdated)
* Iroh sync is integrated in the iroh node, with iroh-gossip, in the RPC
interface, and the CLI.
* `LiveSync` is the handle to an actor that integrates sync with
[gossip](#1149 ) to broadcast and receive document updates from peers.
For each open document a gossip swarm is joined with a `TopicId` derived
from the doc namespace.
* mod `download` contains the new downloader. It will be improved in
#1344 .
* mod `client` is the new high-level RPC client. It currently only has
methods for dealing with docs and sync, other things should be added
once we merged this. CLI commands for sync are in `commands/sync.rs`.
Will be much better with #1356 .
* `examples/sync.rs` has a REPL to modify and sync docs. It does a full
setup without using the iroh console. Also includes code to sync
directories, and a hammer command for load testing.
* The PR also introduces `iroh::client::Iroh`, a wrapper around the RPC
client, and `iroh::client::Doc`, a wrapper around RPC client for a
single document

## Notes & open questions

#### Should likely happen before merge:

* [x] Make `iroh_sync::Store:::list_authors` and `list_replicas` return
iterators `iroh-sync` *fixed in #1366 *
* [ ] Add `iroh_sync::Store::close_replica`
* [x] `ContentStatus` in `on_insert` callback is reported as `Ready` if
the content is still `baomap::PartialEntry` (in-process download) *fixed
in a8e8093*


#### Can happen after merge, but  before `0.6` release

* [ ] Implement `AuthorImport` and `AuthorShare` RPC & CLI commands
* [ ] sync store `list_namespaces` and `list_authors` internally
collect, return iterator instead
* [ ] Fix cross-compiles to arm/android. See
cross-rs/cross#1311
* [ ] Ensure that fingerpring calculation is efficient and/or cached for
large documents. Currently calculating the initial fingerprint iterates
once over all entries in a document.
* [ ] Make content downloads be more reliable
* [ ] Add some way to download content from peers independent of the
first insertion event for a remote entry. The downloader with retries is
tracked in #1334 and 1344, but independent of that, we still would
currently only ever try to queue a download when the `on_insert`
callback triggers, which is only once. There should be a way, even if
manual for now, to try to download missing content in a replica from
peers.
* [ ] during `iroh-sync` sync include info if content is available for
each entry
* [ ] Add basic peer management and persistence. Currently live sync
will stop to do anything after a node restart.
* [ ] Persist the addressbook of peers for a document, to reconnect when
restarting the node
* [ ] Implement `PeerAdd` and `PeerList` RPC & CLI commands. The latter
needs changes in `iroh-net` to expose information of currently-connected
peers and their peer info.
* [ ] Make read-only replicas possible
* [ ] Improve reliablity of replica sync. 
* sync is triggered on each `NeighborUp` event from gossip. check that
we don't sync too much.
* maybe include peer info in gossip messages, to queue syncs with those
(but not all at once)
* track and exchange the timestamp of last full sync for peers, to know
if you missed gossiped message and react accordingly
     * add more tests with peers coming and leaving

#### Open questions

* [ ] `iroh_sync::EntrySignature` should the signatures include a
namespace prefix?
* [ ] do we want the 1:1 mapping of `NamespaceId`and gossip `TopicId`,
or would the topic id as a hash be better?

#### Other TODOs collected from the code

* [ ] Port `hammer` and `fs` commands from REPL example to iroh cli
* [ ] docs/naming: settle terminology about keypairs,
private/secret/signing keys, public keys/identifiers and make docs and
symbols consistent
* [ ] Make `bytes_get` streaming in the RPC interface
* [ ] Allow to unset the subscription on a replica
* [ ] `iroh-sync` shouldn't depend on `iroh-bytes` only for `Hash` type
-> #1354
* [ ] * [ ] Move `sync::live::PeerSource` to iroh-net or even better ->
#1354
* [ ] `StoreInstance::put` propagate error and verify timestamp is
reasonable.
* [ ] `StoreInstance::get_range` implement inverted range
* [ ] `iroh_sync`: Remove some items only used in tests (marked with
#[cfg(test)])
* [ ] `iroh_sync` fs store: verify get method fetches all keys with this
namespace
* [ ] `ranger::SimpleStore::get_range`: optimize
* [ ] `ranger::Peer` avoid allocs?
* [ ] `fs::StoreInstance::get_fingerprint` optimize
* [ ] `SyncEngine::doc_subscribe` remove unwrap, handle error


## Change checklist

- [x] Self-review.
- [x] Documentation updates if relevant.
- [ ] Tests if relevant.

---------

Co-authored-by: dignifiedquire <[email protected]>
Co-authored-by: Asmir Avdicevic <[email protected]>
Co-authored-by: Kasey <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

7 participants