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

RequestManager for partial replication #5

Merged
merged 94 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
f54698d
work in progress request manager
staltz Aug 17, 2021
8ddd5e2
remove self feed ID logic from req-manager
staltz Aug 17, 2021
cf5b148
fix typo in import
staltz Aug 17, 2021
f45bac7
add configuration rules
staltz Aug 17, 2021
10fe0e4
fix small mistake
staltz Aug 17, 2021
c0be934
renamed "partially" to "partialReplication"
staltz Aug 20, 2021
42d54cc
move DEFAULT_OPTS to index.js
staltz Aug 20, 2021
4d36c28
update README
staltz Aug 20, 2021
03782bc
protect RequestManager from adding duplicates
staltz Aug 23, 2021
02b632c
update some FIXME comments
staltz Aug 23, 2021
15845c1
first draft of MetafeedFinder
staltz Aug 23, 2021
bd9fa09
add debouncing flush to RequestManager
staltz Aug 23, 2021
b2a18e5
fix tests and add debouncePeriod opts
staltz Sep 7, 2021
f3ffd1e
update dependencies
staltz Sep 8, 2021
266ce93
update ssb-subset-ql
staltz Sep 9, 2021
32f688e
improve RequestManager with partialReplication traversal
staltz Sep 9, 2021
073d43a
add one code comment
staltz Sep 10, 2021
7732163
update deps
staltz Sep 13, 2021
7c4ef2d
fix typos in metafeed-finder
staltz Sep 13, 2021
e4737f0
validate metafeed/announce in metafeed-finder
staltz Sep 14, 2021
5f25cf0
update dev deps
staltz Sep 14, 2021
f5ff2ee
update some code comments
staltz Sep 14, 2021
8d34e51
improve RequestManager's filtering of public msgs
staltz Sep 14, 2021
1f445ca
refactor MetafeedFinder: pluckFromAnnounceMsg can be trusted
staltz Sep 14, 2021
30dcb0a
for now, self feed ID always fully replicates itself
staltz Sep 14, 2021
89a83c2
add more debug() to MetafeedFinder
staltz Sep 15, 2021
41ff783
fix usage of getSubset rpc
staltz Sep 15, 2021
d734877
add a FIXME comment
staltz Sep 15, 2021
59aca75
fix mistakes in RequestManager
staltz Sep 15, 2021
c7ec4c6
MetafeedFinder uses metafeeds.find in case of self ID
staltz Sep 15, 2021
f571fd9
tweak a debug in MetafeedFinder
staltz Sep 15, 2021
5219fff
remove one debug in MetafeedFinder
staltz Sep 15, 2021
6a926ca
remove some obsolete FIXME comments
staltz Sep 15, 2021
047f97f
integration test for partial replication
staltz Sep 15, 2021
54da68e
remove all FIXME from code
staltz Sep 15, 2021
382b727
introduce different templates for each hops level
staltz Sep 16, 2021
1a8b49d
register EBT format in RequestManager, if needed
staltz Sep 16, 2021
2987ed0
do only one database pull-drain in RequestManager
staltz Sep 17, 2021
13b024f
protect RequestManager against quick tombstoning
staltz Sep 17, 2021
c590b11
remove console.logs from tests
staltz Sep 17, 2021
191953a
remove leftovers
staltz Sep 17, 2021
8354bd8
test and implement reconfigure()
staltz Sep 17, 2021
4f9e91f
refactor some names in RequestManager
staltz Sep 19, 2021
77a2818
refactor RequestManager internals a bit
staltz Sep 20, 2021
05ace94
avoid unnecessary database scans in RequestManager
staltz Sep 20, 2021
1328eb4
fix README
staltz Sep 20, 2021
488e526
improve integration/block3 test
staltz Sep 20, 2021
6df9f5a
improve coverage script
staltz Sep 20, 2021
3a48d2f
add one test utility
staltz Sep 22, 2021
5ec114e
RequestManager can handle blocks and unfollows
staltz Sep 22, 2021
2c818cc
remove a hack from tests now that ssb-ebt was fixed
staltz Sep 23, 2021
1e3fbdc
rename ssb-meta-feeds-rpc to ssb-subset-rpc
staltz Sep 23, 2021
e986c85
refactor the test a bit
staltz Sep 23, 2021
0ae3fe9
rename the test file
staltz Sep 23, 2021
59ab6e3
update ssb-meta-feeds to 0.23.0
staltz Sep 23, 2021
cabf98f
add some code comments
staltz Sep 23, 2021
47d8be9
speed up test/intergration/partial
staltz Sep 23, 2021
e528b5b
reconfigure() supports opts.debouncePeriod
staltz Sep 23, 2021
e9f1c9f
use graphStream only for computing third-party blocks
staltz Sep 23, 2021
04661a9
hack block3 test for now
staltz Sep 23, 2021
c27f016
remove some logging
staltz Sep 23, 2021
0fe5964
improve test/integration/partial.js
staltz Sep 24, 2021
1ea63f0
improve test/integration/block3.js
staltz Sep 24, 2021
2f6173b
switch from full to partial if found metafeed/announce
staltz Sep 27, 2021
f550090
add debug in req-manager.js
staltz Sep 27, 2021
9ec50d4
fix flushing boolean in req-manager.js
staltz Sep 27, 2021
9ae9085
refactor internally MetafeedFinder if conditions
staltz Sep 27, 2021
ab9da47
rename some variables in RequestManager
staltz Sep 27, 2021
0286fd3
fix treatment of live MetafeedFinder stream
staltz Sep 27, 2021
f41464d
add start() API and autostart config
staltz Sep 29, 2021
c9b4517
update ssb-meta-feeds to 0.24.0
staltz Oct 1, 2021
8c69236
protect MetafeedFinder forEachNeighborPeer against self ID
staltz Oct 1, 2021
1d283be
refactor RequestManager's _handleBranch()
staltz Oct 6, 2021
fbc7205
tiny renaming in RequestManager _handleBranch
staltz Oct 6, 2021
5be8091
detect tombstones and stop replicating those subfeeds
staltz Oct 7, 2021
3e10ce0
rename some variables in RequestManager
staltz Oct 7, 2021
3342f19
tweak RequestManager _handleBranch logic
staltz Oct 7, 2021
48e9df5
change how "partial replication enabled" is checked
staltz Oct 7, 2021
2ee7063
fix RequestManager _findTemplateForHops() corner case logic
staltz Oct 7, 2021
4a82252
fix tests for tombstoning
staltz Oct 7, 2021
175b70f
add a small timer.unref()
staltz Oct 8, 2021
2338e68
improve pull.drain in MetafeedFinder _flush
staltz Oct 8, 2021
efd7f43
cosmetic refactor of MetafeedFinder period arg
staltz Oct 8, 2021
f547a55
MetafeedFinder calls getSubset on newly connected peers
staltz Oct 8, 2021
afa3fad
make this REUSE compliant
staltz Oct 8, 2021
b3c153a
use ssb-ebt 8.0.0
staltz Oct 12, 2021
26f48fb
MetafeedFinder with period zero behaves synchronously
staltz Oct 17, 2021
7d296c2
MetafeedFinder doesnt flush if there's nothing to flush
staltz Oct 17, 2021
acb09f5
small refactors
staltz Feb 17, 2022
f238c48
batch metafeed-finder RPC calls
staltz Feb 18, 2022
4d4908b
test: intermediary friend does not forward to blocked
staltz Feb 18, 2022
5338f44
remove wrong code comment
staltz Feb 18, 2022
04c35aa
bump several dependencies
staltz Feb 18, 2022
0a451af
tweak tests to show "catch all" replication rule
staltz Feb 18, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@

/node_modules
/pnpm-lock
/.nyc_output
/.nyc_output
/coverage
263 changes: 256 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ SPDX-License-Identifier: CC0-1.0

# ssb-replication-scheduler

*Triggers replication of feeds identified as friendly in the social graph.*
_Triggers replication of feeds identified as friendly in the social graph._

Depends on ssb-friends APIs, and calls ssb-ebt APIs.

Expand All @@ -16,8 +16,8 @@ Depends on ssb-friends APIs, and calls ssb-ebt APIs.

- Requires **Node.js 10** or higher
- Requires **ssb-db** or **ssb-db2**
- Requires **ssb-friends** version **5.0** or higher
- Requires **ssb-ebt** version **7.0** or higher
- Requires [**ssb-friends**](https://github.com/ssbc/ssb-friends) version **5.0** or higher
- Requires [**ssb-ebt**](https://github.com/ssbc/ssb-ebt) version **7.0** or higher

```
npm install --save ssb-replication-scheduler
Expand All @@ -41,10 +41,10 @@ Add this secret-stack plugin like this:

## Usage

There are no APIs, and nothing else you need to do. As soon as the SSB peer is
initialized, `ssb-replication-scheduler` will automatically query the social
graph, and either request replication or stop replication, depending whether the
feed is friendly or blocked.
Typically there is nothing you need to do after installing this plugin. As soon
as the SSB peer is initialized, `ssb-replication-scheduler` will automatically
query the social graph, and either request replication or stop replication,
depending whether the feed is friendly or blocked.

**Opinions embedded in the scheduler:**

Expand All @@ -58,6 +58,255 @@ feed is friendly or blocked.
- Replication is strictly disabled for:
- Any feed you explicitly block

There are two APIs available in case you want to have more control over this
module: `start()` and `reconfigure()`. Read more about these at the bottom of
this file.

## Configuration

Some parameters and opinions can be configured by the user or by application
code through the conventional [ssb-config](https://github.com/ssbc/ssb-config)
object. The possible options are listed below:

```js
{
replicationScheduler: {
/**
* Whether the replication scheduler should start automatically as soon as
* the SSB app is initialized. When `false`, you have to call
* `ssb.replicationScheduler.start()` manually. Default is `true`.
*/
autostart: true,

/**
* If `partialReplication` is an object, it tells the replication scheduler
* to perform partial replication, whenever remote feeds support it. If
* `partialReplication` is `null` (which it is, by default), then all
* friendly feeds will be requested in full.
*
* Read below more about this configuration.
*/
partialReplication: null,
}
}
```

### Configuring partial replication

The `config.replicationScheduler.partialReplication` object describes the tree
of meta feeds that we are interested in replicating, for each hops level. For
each hops level we have a certain _template_ to describe how replication should
work at that level. Notice that this configuration cannot specify **who** we
replicate (that's the job of ssb-friends and your chosen `hops`, see the _Usage_
section above), this configuration just specifies **how** should we replicate a
friendly peer, in other words, the level of granularity for those peers.

#### Template per hops

The high-level overview of the `partialReplication` configuration is:

```js
replicationScheduler: {
partialReplication: {
0: TEMPLATE_FOR_HOPS_0,
1: TEMPLATE_FOR_HOPS_1,
2: TEMPLATE_FOR_HOPS_2_AND_ABOVE,
}
}
```

Soon we'll show how those `TEMPLATE_FOR_HOPS` work, but for now notice that the
highest number will handle all the hops beyond that number, e.g. notice how `2`
is the highest number and it means that `TEMPLATE_FOR_HOPS_2_AND_ABOVE`
configures how to replicate peers at hops 2 or 3 or 4 or higher. There's nothing
special about the number 2, it could also have been this:

```js
replicationScheduler: {
partialReplication: {
0: TEMPLATE_FOR_HOPS_0,
1: TEMPLATE_FOR_HOPS_1_AND_ABOVE,
}
}
```

Or even this (which means we use the same template for all peers, regardless of
their hops distance):

```js
replicationScheduler: {
partialReplication: {
0: TEMPLATE_FOR_HOPS_0_AND_ABOVE,
}
}
```

Or even fractional numbers:

```js
replicationScheduler: {
partialReplication: {
0: TEMPLATE_FOR_HOPS_0,
0.5: TEMPLATE_FOR_HOPS_HALF,
1: TEMPLATE_FOR_HOPS_1_AND_ABOVE,
}
}
```

#### Template structure

A **Template** is JSON which describes how should we do partial replication. If
the template is `null` or a falsy value, then it means that for that hops level
we don't do partial replication and we **will** do **full** replication (which
means pre-2022 SSB replication of the peer's `main` feed).

When the template is a JSON tree of objects and arrays, where the root of the
tree is always the _root meta feed_. The template describes which **keys** in
the metafeeds and subfeeds must match exactly the **values** given. So that if
we write `feedpurposes: 'indexes'`, it means we are interested in matching the
metafeed that has the field `feedpurposes` exactly matching the value "indexes".
All specified fields must match, but omitted fields are allowed to be any value.

The field `subfeeds` is not matching an actual field, instead, it is assumes we
are dealing with a meta feed and this is describing its subfeeds that we would
like to replicate.

#### Special variables

Some keys and some values are special, in the sense that they are not taken
literally, but are going to be substituted by other context-relative values.
These special variables are always prefixed with **`$`**.

- Special keys
- `$format`
- Special values
- `$main`
- `$root`

The field _key_ `$format` refers to [ssb-ebt](https://github.com/ssbc/ssb-ebt)
"replication formats" and can be included in a template to specify which
replication format to use in ssb-ebt. The value of this field should be the
format's name as a string.

If the value of a field, e.g. in ssb-ql-0 queries, are the special strings
`"$main"` or `"$root"`, then they respectively refer to the IDs of the _main
feed_ and of the _root meta feed_.

#### Example

In the example below, we set up partial replication with the meaning:

- For hops 0 (that is, "yourself"), replicate some app feeds and all index feeds
- For hops 1 (direct friends), replicate only 5 specific index feeds
- For hops 2 and beyond, replicate only 2 specific index feeds

```js
partialReplication: {
0: {
subfeeds: [
{ feedpurpose: 'coolgame' },
{ feedpurpose: 'git-ssb' },
{
feedpurpose: 'indexes',
subfeeds: [
{
feedpurpose: 'index',
$format: 'indexed',
},
],
},
],
},

1: {
subfeeds: [
{
feedpurpose: 'indexes',
subfeeds: [
{
feedpurpose: 'index',
metadata: {
querylang: 'ssb-ql-0',
query: { author: '$main', type: null, private: true },
},
$format: 'indexed',
},
{
feedpurpose: 'index',
metadata: {
querylang: 'ssb-ql-0',
query: { author: '$main', type: 'post', private: false },
},
$format: 'indexed',
},
{
feedpurpose: 'index',
metadata: {
querylang: 'ssb-ql-0',
query: { author: '$main', type: 'vote', private: false },
},
$format: 'indexed',
},
{
feedpurpose: 'index',
metadata: {
querylang: 'ssb-ql-0',
query: { author: '$main', type: 'about', private: false },
},
$format: 'indexed',
},
{
feedpurpose: 'index',
metadata: {
querylang: 'ssb-ql-0',
query: { author: '$main', type: 'contact', private: false },
},
$format: 'indexed',
},
],
},
],
},

2: {
subfeeds: [
{
feedpurpose: 'indexes',
subfeeds: [
{
feedpurpose: 'index',
metadata: {
querylang: 'ssb-ql-0',
query: { author: '$main', type: 'about', private: false },
},
$format: 'indexed',
},
{
feedpurpose: 'index',
metadata: {
querylang: 'ssb-ql-0',
query: { author: '$main', type: 'contact', private: false },
},
$format: 'indexed',
},
],
},
],
},
}
```

## APIs

### `ssb.replicationScheduler.start() => void` (sync)


### `ssb.replicationScheduler.reconfigure(config) => void` (sync)

At any point during the execution of your program, you can reconfigure the
replication rules using this API. The configuration object passed to this API
has the same shape as `config.replicationScheduler` (see above) has.

## License

LGPL-3.0
Loading