-
Notifications
You must be signed in to change notification settings - Fork 490
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: update to ipfs-geoip v9 #2061
Changes from all commits
e0f482f
ff8719a
2c650fb
a2a36c0
056195f
a40d8d7
dfba157
780be59
ef1f699
98312a2
39e704e
109ccfd
ab9bb6f
d527194
7d24f15
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,46 +5,69 @@ | |
* @see https://alchemy.com/blog/how-to-polyfill-node-core-modules-in-webpack-5 | ||
*/ | ||
const webpack = require('webpack') | ||
const PURE_ESM_MODULES = [ | ||
'ipfs-geoip' | ||
] | ||
|
||
/** | ||
* This function goes through the loader rules and applies modifier function to the said rule. | ||
* Validation can be set within the modifier function. | ||
* | ||
* @param {import('webpack').RuleSetRule[]} rules | ||
* @param {function} modifier defaults to identity function | ||
* @returns {import('webpack').RuleSetRule[]} | ||
*/ | ||
function modifyBabelLoaderRule (rules, root = true) { | ||
const foundRules = [] | ||
rules.forEach((rule, i) => { | ||
if (rule.loader != null) { | ||
if (rule.loader.includes('babel-loader')) { | ||
foundRules.push(rule) | ||
} | ||
} else if (rule.use?.loader != null) { | ||
if (typeof rule.use.loader !== 'string') { | ||
if (rule.use.loader.find(loader => loader.indexOf('babel-loader') >= 0)) { | ||
foundRules.push(rule) | ||
} | ||
} else if (rule.use.loader.indexOf('babel-loader') >= 0) { | ||
foundRules.push(rule) | ||
} | ||
} else if (rule.oneOf) { | ||
const nestedRules = modifyBabelLoaderRule(rule.oneOf, false) | ||
foundRules.push(...nestedRules) | ||
function modifyBabelLoaderRules (rules, modifier = r => r) { | ||
return rules.map(rule => { | ||
if (rule.oneOf) { | ||
rule.oneOf = modifyBabelLoaderRules(rule.oneOf, modifier) | ||
} else if (rule.use) { | ||
rule.use = modifyBabelLoaderRules(rule.use, modifier) | ||
} else { | ||
rule = modifier(rule) | ||
} | ||
return rule | ||
}) | ||
} | ||
|
||
if (root) { | ||
foundRules.forEach((rule, index) => { | ||
if (rule.include?.indexOf('src') >= 0) { | ||
console.log('Found CRA babel-loader rule for source files. Modifying it to instrument for code coverage.') | ||
console.log('rule: ', rule) | ||
rule.options.plugins.push('istanbul') | ||
/** | ||
* Adds exclude rules for pure ESM Modules. | ||
* | ||
* @param {import('webpack').RuleSetRule[]} rules | ||
* @returns {import('webpack').RuleSetRule[]} | ||
*/ | ||
function modifyBabelLoaderRuleForBuild (rules) { | ||
return modifyBabelLoaderRules(rules, rule => { | ||
if (rule.loader && rule.loader.includes('babel-loader')) { | ||
if ('exclude' in rule) { | ||
if (!Array.isArray(rule.exclude)) { | ||
rule.exclude = [rule.exclude] | ||
} | ||
PURE_ESM_MODULES.forEach(module => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since pure ESM modules like |
||
rule.exclude.push(new RegExp(`node_modules/${module}`)) | ||
}) | ||
} | ||
}) | ||
} | ||
} | ||
return rule | ||
}) | ||
} | ||
|
||
return foundRules | ||
/** | ||
* Adds instrumentation plugin for code coverage in test mode. | ||
* | ||
* @param {import('webpack').RuleSetRule[]} rules | ||
* @returns {import('webpack').RuleSetRule[]} | ||
*/ | ||
function modifyBabelLoaderRuleForTest (rules) { | ||
return modifyBabelLoaderRules(rules, rule => { | ||
if (rule.options && rule.options.plugins) { | ||
rule.options.plugins.push('istanbul') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this also gives us an opportunity to inject instrumentation in a much more cleaner way. |
||
} | ||
return rule | ||
}) | ||
} | ||
|
||
function webpackOverride (config) { | ||
function webpackOverride(config) { | ||
const fallback = config.resolve.fallback || {} | ||
|
||
Object.assign(fallback, { | ||
|
@@ -63,10 +86,12 @@ function webpackOverride (config) { | |
}) | ||
]) | ||
|
||
config.module.rules = modifyBabelLoaderRuleForBuild(config.module.rules) | ||
|
||
// Instrument for code coverage in development mode | ||
const REACT_APP_ENV = process.env.REACT_APP_ENV ?? process.env.NODE_ENV ?? 'production' | ||
if (REACT_APP_ENV === 'test') { | ||
modifyBabelLoaderRule(config.module.rules) | ||
config.module.rules = modifyBabelLoaderRuleForTest(config.module.rules) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. explicit assignment instead of in place modification on pass by reference. |
||
} | ||
|
||
return config | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import { createAsyncResourceBundle, createSelector } from 'redux-bundler' | ||
import { getConfiguredCache } from 'money-clip' | ||
import geoip from 'ipfs-geoip' | ||
import { lookup } from 'ipfs-geoip' | ||
import PQueue from 'p-queue' | ||
import HLRU from 'hashlru' | ||
import Multiaddr from 'multiaddr' | ||
|
@@ -32,10 +32,8 @@ function createPeersLocations (opts) { | |
const bundle = createAsyncResourceBundle({ | ||
name: 'peerLocations', | ||
actionBaseType: 'PEER_LOCATIONS', | ||
getPromise: async ({ store, getIpfs }) => { | ||
const peers = store.selectPeers() | ||
return peerLocResolver.findLocations(peers, getIpfs) | ||
}, | ||
getPromise: ({ store }) => peerLocResolver.findLocations( | ||
store.selectAvailableGatewayUrl(), store.selectPeers()), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. now we can just pull the list the gateway urls active and pass the peers. |
||
staleAfter: UPDATE_EVERY, | ||
retryAfter: UPDATE_EVERY, | ||
persist: false, | ||
|
@@ -227,7 +225,7 @@ class PeerLocationResolver { | |
this.pass = 0 | ||
} | ||
|
||
async findLocations (peers, getIpfs) { | ||
async findLocations (gatewayUrls, peers) { | ||
const res = {} | ||
|
||
for (const p of this.optimizedPeerSet(peers)) { | ||
|
@@ -257,7 +255,7 @@ class PeerLocationResolver { | |
|
||
this.geoipLookupPromises.set(ipv4Addr, this.queue.add(async () => { | ||
try { | ||
const data = await geoip.lookup(getIpfs(), ipv4Addr) | ||
const data = await lookup(gatewayUrls, ipv4Addr) | ||
await this.geoipCache.set(ipv4Addr, data) | ||
} catch (e) { | ||
// mark this one as failed so we don't retry again | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -274,55 +274,58 @@ describe('PeerLocationResolver', () => { | |
|
||
const result = await getPromise({ | ||
store: { | ||
selectPeers: () => [{ | ||
peer: '1aaa1', | ||
latency: 'n/a', | ||
addr: { | ||
stringTuples: () => [[4, '123.123.123.123']] | ||
selectPeers: () => [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. reformatted for readability. tab +1 |
||
{ | ||
peer: '1aaa1', | ||
latency: 'n/a', | ||
addr: { | ||
stringTuples: () => [[4, '123.123.123.123']] | ||
} | ||
}, | ||
{ | ||
peer: '1b1', | ||
latency: '1ms', | ||
addr: { | ||
stringTuples: () => [[4, '127.0.0.1']] | ||
} | ||
}, | ||
{ | ||
peer: '3b3', | ||
latency: '1ms', | ||
addr: { | ||
stringTuples: () => [[4, '16.19.16.19']] | ||
} | ||
}, | ||
{ | ||
peer: '44asd', | ||
latency: '1ms', | ||
addr: { | ||
stringTuples: () => [[4, '4.4.4.4']] | ||
} | ||
}, | ||
{ | ||
peer: '4sameAs4', | ||
latency: '1ms', | ||
addr: { | ||
stringTuples: () => [[4, '4.4.4.4']] | ||
} | ||
}, | ||
{ | ||
peer: 'newPeerThatShouldThrow', | ||
latency: '100s', | ||
addr: { | ||
stringTuples: () => [[4, '5.5.5.5']] | ||
} | ||
}, | ||
{ | ||
peer: 'sameIpAs1', | ||
latency: 'n/a', | ||
addr: { | ||
stringTuples: () => [[4, '123.123.123.123']] | ||
} | ||
} | ||
}, | ||
{ | ||
peer: '1b1', | ||
latency: '1ms', | ||
addr: { | ||
stringTuples: () => [[4, '127.0.0.1']] | ||
} | ||
}, | ||
{ | ||
peer: '3b3', | ||
latency: '1ms', | ||
addr: { | ||
stringTuples: () => [[4, '16.19.16.19']] | ||
} | ||
}, | ||
{ | ||
peer: '44asd', | ||
latency: '1ms', | ||
addr: { | ||
stringTuples: () => [[4, '4.4.4.4']] | ||
} | ||
}, | ||
{ | ||
peer: '4sameAs4', | ||
latency: '1ms', | ||
addr: { | ||
stringTuples: () => [[4, '4.4.4.4']] | ||
} | ||
}, | ||
{ | ||
peer: 'newPeerThatShouldThrow', | ||
latency: '100s', | ||
addr: { | ||
stringTuples: () => [[4, '5.5.5.5']] | ||
} | ||
}, | ||
{ | ||
peer: 'sameIpAs1', | ||
latency: 'n/a', | ||
addr: { | ||
stringTuples: () => [[4, '123.123.123.123']] | ||
} | ||
}] | ||
], | ||
selectAvailableGatewayUrl: () => 'https://ipfs.io' | ||
}, | ||
getIpfs: () => 'smth' | ||
}) | ||
|
@@ -346,10 +349,13 @@ describe('PeerLocationResolver', () => { | |
} | ||
})) | ||
|
||
const mockStore = { | ||
selectAvailableGatewayUrl: () => 'https://ipfs.io', | ||
selectPeers: () => peers | ||
} | ||
|
||
const result = await getPromise({ | ||
store: { | ||
selectPeers: () => peers | ||
} | ||
store: mockStore | ||
}) | ||
|
||
expect(result).toEqual({ | ||
|
@@ -368,10 +374,9 @@ describe('PeerLocationResolver', () => { | |
// ==== 100 ==== | ||
|
||
const result100 = await getPromise({ | ||
store: { | ||
selectPeers: () => peers | ||
} | ||
store: mockStore | ||
}) | ||
|
||
const expect100 = new Array(100).fill().reduce((prev, _, index) => ({ | ||
...prev, | ||
[`${index}aa`]: 'location-cached' | ||
|
@@ -382,9 +387,7 @@ describe('PeerLocationResolver', () => { | |
// ==== 200 ==== | ||
|
||
const result200 = await getPromise({ | ||
store: { | ||
selectPeers: () => peers | ||
} | ||
store: mockStore | ||
}) | ||
const expect200 = new Array(200).fill().reduce((prev, _, index) => ({ | ||
...prev, | ||
|
@@ -396,9 +399,7 @@ describe('PeerLocationResolver', () => { | |
// ==== Over 200 ==== | ||
|
||
const resultMore = await getPromise({ | ||
store: { | ||
selectPeers: () => peers | ||
} | ||
store: mockStore | ||
}) | ||
|
||
const expectMore = new Array(1000).fill().reduce((prev, _, index) => ({ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,7 @@ import AddConnection from './AddConnection/AddConnection' | |
import CliTutorMode from '../components/cli-tutor-mode/CliTutorMode' | ||
import { cliCmdKeys, cliCommandList } from '../bundles/files/consts' | ||
|
||
const PeersPage = ({ t, toursEnabled, handleJoyrideCallback, isCliTutorModeEnabled }) => ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unused assignment. |
||
const PeersPage = ({ t, toursEnabled, handleJoyrideCallback }) => ( | ||
<div data-id='PeersPage' className='overflow-hidden'> | ||
<Helmet> | ||
<title>{t('title')} | IPFS</title> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactored the logic to make this painless and D.R.Y.