git ssb

0+

alanz / patchwork



forked from Matt McKegg / patchwork

Commit 36cd0eeba48657072d1b4544e72acf7e5eead61f

fix prioritizing connection to pubs that are friends

Matt McKegg committed on 11/3/2016, 9:53:34 PM
Parent: 68976cde98459b3f066c8c3c0fab7c054a4d848c

Files changed

lib/persistent-gossip/index.jschanged
lib/persistent-gossip/init.jschanged
lib/persistent-gossip/schedule.jschanged
lib/friends-with-gossip-priority.jsadded
package.jsonchanged
server-process.jschanged
lib/persistent-gossip/index.jsView
@@ -21,12 +21,8 @@
2121 function stringify(peer) {
2222 return [peer.host, peer.port, peer.key].join(':')
2323 }
2424
25-function isFriends (friends, a, b) {
26- return friends[a] && friends[b] && friends[a][b] && friends[b][a]
27-}
28-
2925 /*
3026 Peers : [{
3127 key: id,
3228 host: ip,
@@ -67,18 +63,8 @@
6763 wakeup: 0,
6864 peers: function () {
6965 return peers
7066 },
71- connectToFriends: function () {
72- server.friends.all((err, friends) => {
73- if (err) return
74- peers.forEach(function(peer) {
75- if (!Schedule.isConnect(peer) && isFriends(friends, server.id, peer.key)) {
76- gossip.connect(peer, function() {})
77- }
78- })
79- })
80- },
8167 get: function (addr) {
8268 addr = ref.parseAddress(addr)
8369 return u.find(peers, function (a) {
8470 return (
@@ -154,11 +140,11 @@
154140 addr.duration = addr.duration || null
155141 peers.push(addr)
156142 notify({ type: 'discover', peer: addr, source: source || 'manual' })
157143 return addr
158- } else if (source === 'local') {
159- // this peer is local to us, override old source
160- addr.source = 'local'
144+ } else if (source === 'friends' || source === 'local') {
145+ // this peer is a friend or local, override old source to prioritize gossip
146+ f.source = source
161147 }
162148 //don't count local over and over
163149 else if(f.source != 'local')
164150 f.announcers ++
lib/persistent-gossip/init.jsView
@@ -19,16 +19,13 @@
1919 if(msg.sync) return
2020 if(!msg.content.address) return
2121 if(ref.isAddress(msg.content.address))
2222 gossip.add(msg.content.address, 'pub')
23- }, gossip.connectToFriends)
23+ })
2424 )
2525
2626 // populate peertable with announcements on the LAN multicast
2727 server.on('local', function (_peer) {
2828 gossip.add(_peer, 'local')
2929 })
3030
3131 }
32-
33-
34-
lib/persistent-gossip/schedule.jsView
@@ -46,8 +46,12 @@
4646 // cjdns creates fake private ip addresses.
4747 return ip.isPrivate(e.host) && e.source === 'local'
4848 }
4949
50+function isFriend (e) {
51+ return e.source === 'friends'
52+}
53+
5054 function isUnattempted (e) {
5155 return !e.stateChange
5256 }
5357
@@ -108,8 +112,9 @@
108112 return (value === undefined || value === '') ? def : value
109113 }
110114
111115 function connect (peers, ts, name, filter, opts) {
116+ opts.group = name
112117 var connected = peers.filter(isConnect).filter(filter)
113118
114119 //disconnect if over quota
115120 if(connected.length > opts.quota) {
@@ -136,21 +141,44 @@
136141 connecting = false
137142 var ts = Date.now()
138143 var peers = gossip.peers()
139144
140- var connected = peers.filter(and(isConnect, not(isLocal))).length
145+ var connected = peers.filter(and(isConnect, not(isLocal), not(isFriend))).length
146+ var connectedFriends = peers.filter(and(isConnect, isFriend)).length
141147
142- connect(peers, ts, 'longterm', exports.isLongterm, {
143- quota: 3, factor: 10e3, max: 10*min, groupMin: 5e3,
144- disable: !conf('global', true)
145- })
146-
147148 connect(peers, ts, 'local', exports.isLocal, {
148149 quota: 3, factor: 2e3, max: 10*min, groupMin: 1e3,
149150 disable: !conf('local', true)
150151 })
151152
152- if(connected < 3)
153+ // prioritize friends
154+ connect(peers, ts, 'friends', and(exports.isFriend, exports.isLongterm), {
155+ quota: 2, factor: 10e3, max: 10*min, groupMin: 5e3,
156+ disable: !conf('local', true)
157+ })
158+
159+ if (connectedFriends < 2)
160+ connect(peers, ts, 'attemptFriend', and(exports.isFriend, exports.isUnattempted), {
161+ min: 0, quota: 1, factor: 0, max: 0, groupMin: 0,
162+ disable: !conf('global', true)
163+ })
164+
165+ connect(peers, ts, 'retryFriends', and(exports.isFriend, exports.isInactive), {
166+ min: 0,
167+ quota: 3, factor: 60e3, max: 3*60*60e3, groupMin: 5*60e3
168+ })
169+
170+ // standard longterm peers
171+ connect(peers, ts, 'longterm', and(
172+ exports.isLongterm,
173+ not(exports.isFriend),
174+ not(exports.isLocal)
175+ ), {
176+ quota: 2, factor: 10e3, max: 10*min, groupMin: 5e3,
177+ disable: !conf('global', true)
178+ })
179+
180+ if(!connected)
153181 connect(peers, ts, 'attempt', exports.isUnattempted, {
154182 min: 0, quota: 1, factor: 0, max: 0, groupMin: 0,
155183 disable: !conf('global', true)
156184 })
@@ -199,6 +227,7 @@
199227 exports.isInactive = isInactive
200228 exports.isLongterm = isLongterm
201229 exports.isLegacy = isLegacy
202230 exports.isLocal = isLocal
231+exports.isFriend = isFriend
203232 exports.isConnectedOrConnecting = isConnect
204233 exports.select = select
lib/friends-with-gossip-priority.jsView
@@ -1,0 +1,178 @@
1+var Graphmitter = require('graphmitter')
2+var pull = require('pull-stream')
3+var mlib = require('ssb-msgs')
4+var memview = require('level-memview')
5+var pushable = require('pull-pushable')
6+var mdm = require('mdmanifest')
7+var valid = require('scuttlebot/lib/validators')
8+var apidoc = require('scuttlebot/lib/apidocs').friends
9+
10+// friends plugin
11+// methods to analyze the social graph
12+// maintains a 'follow' and 'flag' graph
13+
14+function isFunction (f) {
15+ return 'function' === typeof f
16+}
17+
18+function isString (s) {
19+ return 'string' === typeof s
20+}
21+
22+function isFriend (friends, a, b) {
23+ return friends[a] && friends[b] && friends[a][b] && friends[b][a]
24+}
25+
26+exports.name = 'friends'
27+exports.version = '1.0.0'
28+exports.manifest = mdm.manifest(apidoc)
29+
30+exports.init = function (sbot, config) {
31+
32+ var graphs = {
33+ follow: new Graphmitter(),
34+ flag: new Graphmitter()
35+ }
36+
37+ // view processor
38+ var syncCbs = []
39+ function awaitSync (cb) {
40+ if (syncCbs) syncCbs.push(cb)
41+ else cb()
42+ }
43+
44+ // read/watch the log for changes to the social graph
45+ pull(sbot.createLogStream({ live: true }), pull.drain(function (msg) {
46+
47+ if (msg.sync) {
48+ syncCbs.forEach(function (cb) { cb() })
49+ syncCbs = null
50+
51+ if (sbot.gossip) {
52+ // prioritize friends
53+ var friends = graphs['follow'].toJSON()
54+ sbot.gossip.peers().forEach(function(peer) {
55+ if (isFriend(friends, sbot.id, peer.key)) {
56+ sbot.gossip.add(peer, 'friends')
57+ }
58+ })
59+ }
60+
61+ return
62+ }
63+
64+ var c = msg.value.content
65+ if (c.type == 'contact') {
66+ mlib.asLinks(c.contact, 'feed').forEach(function (link) {
67+ if ('following' in c) {
68+ if (c.following)
69+ graphs.follow.edge(msg.value.author, link.link, true)
70+ else
71+ graphs.follow.del(msg.value.author, link.link)
72+
73+ }
74+ if ('flagged' in c) {
75+ if (c.flagged)
76+ graphs.flag.edge(msg.value.author, link.link, c.flagged)
77+ else
78+ graphs.flag.del(msg.value.author, link.link)
79+ }
80+ })
81+ }
82+ }))
83+
84+ return {
85+
86+ get: valid.sync(function (opts) {
87+ var g = graphs[opts.graph || 'follow']
88+ if(!g) throw new Error('opts.graph must be provided')
89+ return g.get(opts.source, opts.dest)
90+ }, 'object?'),
91+
92+ all: valid.async(function (graph, cb) {
93+ if (typeof graph == 'function') {
94+ cb = graph
95+ graph = null
96+ }
97+ if (!graph)
98+ graph = 'follow'
99+ awaitSync(function () {
100+ cb(null, graphs[graph] ? graphs[graph].toJSON() : null)
101+ })
102+ }, 'string?'),
103+
104+ path: valid.sync(function (opts) {
105+ if(isString(opts))
106+ opts = {source: sbot.id, dest: opts}
107+ return graphs.follow.path(opts)
108+
109+ }, 'string|object'),
110+
111+ createFriendStream: valid.source(function (opts) {
112+ opts = opts || {}
113+ var live = opts.live === true
114+ var meta = opts.meta === true
115+ var start = opts.start || sbot.id
116+ var graph = graphs[opts.graph || 'follow']
117+ if(!graph)
118+ return pull.error(new Error('unknown graph:' + opts.graph))
119+ var cancel, ps = pushable(function () {
120+ cancel && cancel()
121+ })
122+
123+ function push (to, hops) {
124+ return ps.push(meta ? {id: to, hops: hops} : to)
125+ }
126+
127+ //by default, also emit your own key.
128+ if(opts.self !== false)
129+ push(start, 0)
130+
131+ var conf = config.friends || {}
132+ cancel = graph.traverse({
133+ start: start,
134+ hops: opts.hops || conf.hops || 3,
135+ max: opts.dunbar || conf.dunbar || 150,
136+ each: function (_, to, hops) {
137+ if(to !== start) push(to, hops)
138+ }
139+ })
140+
141+ if(!live) { cancel(); ps.end() }
142+
143+ return ps
144+ }, 'createFriendStreamOpts?'),
145+
146+ hops: valid.async(function (start, graph, opts, cb) {
147+ if (typeof opts == 'function') { // (start|opts, graph, cb)
148+ cb = opts
149+ opts = null
150+ } else if (typeof graph == 'function') { // (start|opts, cb)
151+ cb = graph
152+ opts = graph = null
153+ }
154+ opts = opts || {}
155+ if(isString(start)) { // (start, ...)
156+ // first arg is id string
157+ opts.start = start
158+ } else if (start && typeof start == 'object') { // (opts, ...)
159+ // first arg is opts
160+ for (var k in start)
161+ opts[k] = start[k]
162+ }
163+
164+ var conf = config.friends || {}
165+ opts.start = opts.start || sbot.id
166+ opts.dunbar = opts.dunbar || conf.dunbar || 150
167+ opts.hops = opts.hops || conf.hops || 3
168+
169+ var g = graphs[graph || 'follow']
170+ if (!g)
171+ return cb(new Error('Invalid graph type: '+graph))
172+
173+ awaitSync(function () {
174+ cb(null, g.traverse(opts))
175+ })
176+ }, ['feedId', 'string?', 'object?'], ['createFriendStreamOpts'])
177+ }
178+}
package.jsonView
@@ -17,11 +17,13 @@
1717 "data-uri-to-buffer": "0.0.4",
1818 "deep-equal": "^1.0.1",
1919 "electron": "~1.4.4",
2020 "electron-default-menu": "~1.0.0",
21+ "graphmitter": "^1.6.3",
2122 "has-network": "0.0.0",
2223 "insert-css": "~1.0.0",
2324 "is-visible": "^2.1.1",
25+ "level-memview": "0.0.0",
2426 "micro-css": "~0.6.2",
2527 "non-private-ip": "^1.4.1",
2628 "on-change-network": "0.0.2",
2729 "on-wakeup": "^1.0.1",
server-process.jsView
@@ -5,9 +5,9 @@
55
66 var createSbot = require('scuttlebot')
77 .use(require('scuttlebot/plugins/master'))
88 .use(require('./lib/persistent-gossip')) // override
9- .use(require('scuttlebot/plugins/friends'))
9+ .use(require('./lib/friends-with-gossip-priority'))
1010 .use(require('scuttlebot/plugins/replicate'))
1111 .use(require('ssb-blobs'))
1212 .use(require('scuttlebot/plugins/invite'))
1313 .use(require('scuttlebot/plugins/block'))

Built with git-ssb-web