-
Notifications
You must be signed in to change notification settings - Fork 5
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
Make hops configurable #16
Comments
@christianbundy I would prefer that the conn-scheduler is forked so that such modification could be done. The architecture was designed so that all opinions are in conn-scheduler, while the rest is (as much as possible) unopinionated, and it should be easy to swap out the scheduler: var conn = require('ssb-conn/core')
var gossip = require('ssb-conn/compat')
var connScheduler = require('./my-scheduler')
module.exports = [conn, connScheduler, gossip] The reason why I would avoid a simple config field in ssb-config is that there are plenty of other opinions and values embedded in this default scheduler, that if we would allow all of them to be configured, we would with config files that look as large as Kubernetes config files. And at that point it would feel like trying to code with a config language, which is not Turing complete, and would still fall short of allowing everything to be customized.
I'm in support if you create an alternative scheduler that does away with staging. Just remember the tradeoffs and try to communicate those to the users. The downside of staging is that it requires explicit user input, like a naggy firewall might do. On the other hand, not having staging means the user is not in control and may end up connecting to very undesirable peers, e.g. |
Thanks for the quick response. I don't see a simple way of forking your scheduler, so I'll probably just hack something together above the scheduler. My concern is that if I just copy and paste your file I won't be able to receive updates from you, but if I fork the entire repo then I have to maintain a fork of SSB-CONN. I'd write a scheduler myself, but since yours is ~600 lines I'm hesitant to even start.
Right, I'd like to have a user-defined number of hops to resolve this. |
Hmm, it sounds like the solution is suboptimal. Can you think of another way of tweaking/configuring this scheduler? Like what does 'hack something above the scheduler' look like? |
I was thinking something like: const ssbClient = require("ssb-client");
const pull = require("pull-stream");
const maxHops = 2;
ssbClient().then(api => {
api.friends.hops().then(hops => {
pull(
api.conn.stagedPeers(),
pull.drain(x => {
x.forEach(([address, data]) => {
const key = data.key;
const haveHops = typeof hops[key] === "number";
const hopValue = haveHops ? hops[key] : Infinity;
if (hopValue <= maxHops) {
console.log(`${address}: ⏳`);
api.conn
.connect(address, data)
.then(() => console.log(`${address}: 👍`))
.catch(() => console.log(`${address}: 👎`));
}
});
})
);
});
}); |
That's actually quite an okay solution. If you're comfortable with that, I am too. This kind of approach works quite well in this use case, I'm just a bit concerned that other use cases might not have such a fortunate easy path. For instance implementing "do not automatically connect to staged friends" is quite hard because it works in the opposite direction of the opinions in the default scheduler, and would require a fork of the scheduler. |
I share your concern. I'd really like to be able to download your changes and merge my improvements back upstream (e.g. we could subscribe to If you want people to fork the scheduler, maybe it should be its own module? |
I was reading this today and it seems maybe relevant: https://en.wikipedia.org/wiki/Strategy_pattern |
Yep! CONN basically already uses a Strategy pattern. The "interface" of the scheduler is: interface Scheduler {
constructor(ssb, config);
start(): void;
stop(): void;
} And CONN Core will call the scheduler (whatever it is) with |
Hmm, it looks like my solution above is running |
@christianbundy Running |
Hmm, maybe it's something else. When I run the above code it attempts dozens of connections per second and they only show up in the peer list of a tiny amount of time. My peer list jumps from 1 to 16 to 2 to 6 and continues jumping around every time that I refresh my peer list. I can fix it with a Slightly better: const ssbClient = require("ssb-client");
const pull = require("pull-stream");
const maxHops = 3;
const done = [];
ssbClient().then(api => {
api.friends.hops().then(hops => {
pull(
api.conn.stagedPeers(),
pull.drain(x => {
x.filter(([address]) => done.includes(address) === false).forEach(
([address, data]) => {
console.log(done.length);
const key = data.key;
const haveHops = typeof hops[key] === "number";
const hopValue = haveHops ? hops[key] : Infinity;
if (hopValue <= maxHops) {
console.log(`${address}: ⏳`);
done.push(address);
api.conn
.connect(address, data)
.then(() => console.log(`${address}: 👍`))
.catch(() => console.log(`${address}: 👎`));
}
}
);
})
);
});
}); |
Does the peer list show peers in state And yes it's true that once there are many peers connected, the default scheduler will stay killing some. |
Oh, it was showing all of them -- I didn't consider that peers we haven't finished connecting to would appear in the peer list. I've made a bug report for this as fraction/oasis#319, thanks! |
I wonder why you reopened this issue? :) |
Oops, guess I didn't send the comment! Trying to make this work with a script means that I have to either:
Since the scheduler is bundled with SSB-CONN, is your suggestion to fork SSB-CONN and then maintain a downstream fork with my change? |
No forks are required, you just need to make a package var conn = require('ssb-conn/core')
var gossip = require('ssb-conn/compat')
var connScheduler = require('./my-scheduler')
module.exports = [conn, connScheduler, gossip] I could have built this systems as three modules: You pass this array to |
Or, you could even just make your own scheduler as a (for instance) file in the Oasis codebase, and then that file gets bundled together with Also, it's not even required to use the same techniques that the default scheduler uses. You can get creative and build whatever timing functions to schedule connects and disconnects (as well as staging and unstaging). |
Thanks, it's good to know that those are part of the public API. I'm very hesitant to reach into modules with relative require paths, but that makes it slightly better. To be candid, I'm looking to collaborate on a scheduler rather than write my own from scratch or maintain a fork of your scheduler with just one change. It's just under 600 lines, which really isn't trivial for me to rewrite or casually fork. If that's not something you're interested in I suppose I can try to make a fork aimed at collaboration, but I think I'm just surprised to learn that the scheduler isn't open to contributions. Anyway, I'll close this again, sorry. |
Oh, the default scheduler is open to contributions, of course, as long as: (1) we don't disagree on the embedded opinions in the scheduler (the point is not to fight over which opinion is "right", but to recognize that they are just opinions and both sides should exist and be valid), (2) we don't go too deep into developing sophisticated configuration to tweak the embedded opinions. |
Oh, I must have misunderstood, sorry about that. You wouldn't mind a PR to have |
I've been really trying to avoid "stage" buttons like what Patchwork has, but connecting to 1 hop seems like it might not have enough connections. I was reading your code and noticed this:
https://github.com/staltz/ssb-conn/blob/3a3020a6e28515c8a96bc8d353557e00b409408b/src/conn-scheduler.ts#L184
What would be the best way to make this a configurable value?
The text was updated successfully, but these errors were encountered: