Commit 46d16760 authored by 神楽坂玲奈's avatar 神楽坂玲奈

test

parent 83cd16fc
{
"port": 500,
"timeout": 10,
"interval": 1000
}
[
{ "id": 1, "inbound_cost": 0, "outbound_cost": 1 },
{ "id": 3, "inbound_cost": 0, "outbound_cost": 1 },
{ "id": 7, "inbound_cost": 0, "outbound_cost": 1 },
{ "id": 9, "inbound_cost": 0, "outbound_cost": 1 }
]
...@@ -8,45 +8,110 @@ ...@@ -8,45 +8,110 @@
"name": "application-name", "name": "application-name",
"version": "0.0.1", "version": "0.0.1",
"dependencies": { "dependencies": {
"@types/lodash": "^4.14.172", "lodash": "^4.17.21"
"lodash": "^4.17.21",
"ts-node": "^9.1.1",
"typescript": "^4.1.3"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^14.14.19" "@types/lodash": "^4.14.172",
"@types/node": "^16.6.1",
"ts-node": "^10.2.0",
"typescript": "^4.3.5"
}
},
"node_modules/@cspotcode/source-map-consumer": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
"integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
"dev": true,
"engines": {
"node": ">= 12"
}
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz",
"integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==",
"dev": true,
"dependencies": {
"@cspotcode/source-map-consumer": "0.8.0"
},
"engines": {
"node": ">=12"
} }
}, },
"node_modules/@tsconfig/node10": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
"integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
"dev": true
},
"node_modules/@tsconfig/node12": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
"integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
"dev": true
},
"node_modules/@tsconfig/node14": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
"integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
"dev": true
},
"node_modules/@tsconfig/node16": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
"dev": true
},
"node_modules/@types/lodash": { "node_modules/@types/lodash": {
"version": "4.14.172", "version": "4.14.172",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.172.tgz", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.172.tgz",
"integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==" "integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==",
"dev": true
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "14.14.19", "version": "16.6.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.19.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.6.1.tgz",
"integrity": "sha512-4nhBPStMK04rruRVtVc6cDqhu7S9GZai0fpXgPXrFpcPX6Xul8xnrjSdGB4KPBVYG/R5+fXWdCM8qBoiULWGPQ==", "integrity": "sha512-Sr7BhXEAer9xyGuCN3Ek9eg9xPviCF2gfu9kTfuU2HkTVAMYSDeX40fvpmo72n5nansg3nsBjuQBrsS28r+NUw==",
"dev": true "dev": true
}, },
"node_modules/acorn": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
"integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/acorn-walk": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz",
"integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==",
"dev": true,
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/arg": { "node_modules/arg": {
"version": "4.1.3", "version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
}, "dev": true
"node_modules/buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
}, },
"node_modules/create-require": { "node_modules/create-require": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true
}, },
"node_modules/diff": { "node_modules/diff": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true,
"engines": { "engines": {
"node": ">=0.3.1" "node": ">=0.3.1"
} }
...@@ -59,54 +124,58 @@ ...@@ -59,54 +124,58 @@
"node_modules/make-error": { "node_modules/make-error": {
"version": "1.3.6", "version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
}, "dev": true
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-support": {
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
}, },
"node_modules/ts-node": { "node_modules/ts-node": {
"version": "9.1.1", "version": "10.2.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.0.tgz",
"integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", "integrity": "sha512-FstYHtQz6isj8rBtYMN4bZdnXN1vq4HCbqn9vdNQcInRqtB86PePJQIxE6es0PhxKWhj2PHuwbG40H+bxkZPmg==",
"dev": true,
"dependencies": { "dependencies": {
"@cspotcode/source-map-support": "0.6.1",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0", "arg": "^4.1.0",
"create-require": "^1.1.0", "create-require": "^1.1.0",
"diff": "^4.0.1", "diff": "^4.0.1",
"make-error": "^1.1.1", "make-error": "^1.1.1",
"source-map-support": "^0.5.17",
"yn": "3.1.1" "yn": "3.1.1"
}, },
"bin": { "bin": {
"ts-node": "dist/bin.js", "ts-node": "dist/bin.js",
"ts-node-cwd": "dist/bin-cwd.js",
"ts-node-script": "dist/bin-script.js", "ts-node-script": "dist/bin-script.js",
"ts-node-transpile-only": "dist/bin-transpile.js", "ts-node-transpile-only": "dist/bin-transpile.js",
"ts-script": "dist/bin-script-deprecated.js" "ts-script": "dist/bin-script-deprecated.js"
}, },
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=12.0.0"
}, },
"peerDependencies": { "peerDependencies": {
"@swc/core": ">=1.2.50",
"@swc/wasm": ">=1.2.50",
"@types/node": "*",
"typescript": ">=2.7" "typescript": ">=2.7"
},
"peerDependenciesMeta": {
"@swc/core": {
"optional": true
},
"@swc/wasm": {
"optional": true
}
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "4.1.3", "version": "4.3.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
"integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
"dev": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"
...@@ -119,42 +188,93 @@ ...@@ -119,42 +188,93 @@
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"dev": true,
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }
} }
}, },
"dependencies": { "dependencies": {
"@cspotcode/source-map-consumer": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
"integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
"dev": true
},
"@cspotcode/source-map-support": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz",
"integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==",
"dev": true,
"requires": {
"@cspotcode/source-map-consumer": "0.8.0"
}
},
"@tsconfig/node10": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
"integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
"dev": true
},
"@tsconfig/node12": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
"integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
"dev": true
},
"@tsconfig/node14": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
"integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
"dev": true
},
"@tsconfig/node16": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
"dev": true
},
"@types/lodash": { "@types/lodash": {
"version": "4.14.172", "version": "4.14.172",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.172.tgz", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.172.tgz",
"integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==" "integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==",
"dev": true
}, },
"@types/node": { "@types/node": {
"version": "14.14.19", "version": "16.6.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.19.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.6.1.tgz",
"integrity": "sha512-4nhBPStMK04rruRVtVc6cDqhu7S9GZai0fpXgPXrFpcPX6Xul8xnrjSdGB4KPBVYG/R5+fXWdCM8qBoiULWGPQ==", "integrity": "sha512-Sr7BhXEAer9xyGuCN3Ek9eg9xPviCF2gfu9kTfuU2HkTVAMYSDeX40fvpmo72n5nansg3nsBjuQBrsS28r+NUw==",
"dev": true
},
"acorn": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
"integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==",
"dev": true
},
"acorn-walk": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz",
"integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==",
"dev": true "dev": true
}, },
"arg": { "arg": {
"version": "4.1.3", "version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
}, "dev": true
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
}, },
"create-require": { "create-require": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true
}, },
"diff": { "diff": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true
}, },
"lodash": { "lodash": {
"version": "4.17.21", "version": "4.17.21",
...@@ -164,44 +284,40 @@ ...@@ -164,44 +284,40 @@
"make-error": { "make-error": {
"version": "1.3.6", "version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
}, "dev": true
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"source-map-support": {
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
}, },
"ts-node": { "ts-node": {
"version": "9.1.1", "version": "10.2.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.0.tgz",
"integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", "integrity": "sha512-FstYHtQz6isj8rBtYMN4bZdnXN1vq4HCbqn9vdNQcInRqtB86PePJQIxE6es0PhxKWhj2PHuwbG40H+bxkZPmg==",
"dev": true,
"requires": { "requires": {
"@cspotcode/source-map-support": "0.6.1",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0", "arg": "^4.1.0",
"create-require": "^1.1.0", "create-require": "^1.1.0",
"diff": "^4.0.1", "diff": "^4.0.1",
"make-error": "^1.1.1", "make-error": "^1.1.1",
"source-map-support": "^0.5.17",
"yn": "3.1.1" "yn": "3.1.1"
} }
}, },
"typescript": { "typescript": {
"version": "4.1.3", "version": "4.3.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
"integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==" "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
"dev": true
}, },
"yn": { "yn": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"dev": true
} }
} }
} }
{ {
"name": "application-name", "name": "railgun-routing-server",
"version": "0.0.1", "version": "0.0.1",
"devDependencies": { "author": "zh99998 <zh99998@gmail.com>",
"@types/node": "^14.14.19"
},
"dependencies": { "dependencies": {
"lodash": "^4.17.21"
},
"devDependencies": {
"@types/lodash": "^4.14.172", "@types/lodash": "^4.14.172",
"lodash": "^4.17.21", "@types/node": "^16.6.1",
"ts-node": "^9.1.1", "ts-node": "^10.2.0",
"typescript": "^4.1.3" "typescript": "^4.3.5"
} }
} }
// 这个文件两端共用
export interface PeerQuality {
delay: number;
jitter: number;
reliability: number;
}
// 路由器向中心服务器发送的消息
export interface UploadMessage {
id: number; // router id
ack: number;
peers?: Record<number, PeerQuality>;
}
// 中心服务器向路由器发送的消息
export interface DownloadMessage {
seq: number,
to: number,
via: number;
}
// 路由器向路由器发送的消息
export interface PeerMessage {
id: number;
seq: number;
time: number;
}
[
{ "id": 2, "inbound_cost": 0, "outbound_cost": 0.8 },
{ "id": 3, "inbound_cost": 0, "outbound_cost": 0.05 },
{ "id": 4, "inbound_cost": 0, "outbound_cost": 0.03 },
{ "id": 6, "inbound_cost": 0, "outbound_cost": 0.8 },
{ "id": 7, "inbound_cost": 0, "outbound_cost": 1 }
]
import { RemoteInfo } from 'dgram'; import { RemoteInfo } from 'dgram';
import { PeerQuality } from './protocol'; import { PeerQuality } from '../protocol';
import servers from '../servers.json'; import routers from '../config/routers.json';
import assert from 'assert'; import assert from 'assert';
import { Quality } from './Quality'; import { Quality } from './Quality';
export class Router { export class Router {
static all: Router[] = servers.map(s => Object.assign(new Router(), s)); static all: Router[] = routers.map(s => Object.assign(new Router(), s));
// config // config
id!: number; id!: number;
inbound_cost!: number; inbound_cost!: number;
outbound_cost!: number; outbound_cost!: number;
//report seq = 0;
peers: Record<number, PeerQuality> = {}; peers: Record<number, PeerQuality> = {};
via: Map<Router, Router> = new Map();
// routing
next_hop: Map<Router, Router> = new Map();
rinfo?: RemoteInfo; rinfo?: RemoteInfo;
reset() { reset() {
this.seq = 0;
this.peers = {}; this.peers = {};
for (const router of Router.all) { for (const router of Router.all) {
this.next_hop.set(router, router); this.via.set(router, router);
} }
} }
lost() { lost() {
this.seq = 0;
this.rinfo = undefined; this.rinfo = undefined;
return console.log(`router ${this.id} lost connection.`); return console.log(`router ${this.id} lost connection.`);
} }
route_quality(to: Router, next_hop = this.next_hop.get(to)!) { route_quality(to: Router, via = this.via.get(to)!) {
assert(next_hop != null); assert(via != null);
assert(this !== next_hop); assert(this !== via);
assert(this !== to); assert(this !== to);
const result = new Quality(); const result = new Quality();
let current: Router = this; let current: Router = this;
let next = next_hop; let next = via;
const route = [current, next]; const route = [current, next];
while (true) { while (true) {
...@@ -50,7 +51,7 @@ export class Router { ...@@ -50,7 +51,7 @@ export class Router {
// 寻找下一跳 // 寻找下一跳
current = next; current = next;
next = current.next_hop.get(to)!; next = current.via.get(to)!;
assert(next); //to server_id 型路由,由于 server 两两相连,下一跳一定是存在的,至少能直达 assert(next); //to server_id 型路由,由于 server 两两相连,下一跳一定是存在的,至少能直达
if (route.includes(next)) { if (route.includes(next)) {
// 环路 // 环路
......
import dgram from 'dgram'; import dgram from 'dgram';
import http from 'http'; import http from 'http';
import peers from '../servers.json';
import { ServerMessage } from './protocol'; import { DownloadMessage, UploadMessage } from '../protocol';
import assert from 'assert'; import assert from 'assert';
import { Router } from './Router'; import { Router } from './Router';
import _ from 'lodash'; import _ from 'lodash';
const server_port = 495; import config from '../config/config.json';
const timeout = 10;
let sequence = 0;
let updating: any = null; let updating: any = null;
let timeout_timer: any = null; let timeout_timer: any = null;
export function send_route(router: Router, to: Router, next_hop: Router) { export function send_route(from: Router, to: Router, via: Router) {
const message = { sequence, to: to.id, next_hop: next_hop.id }; const message: DownloadMessage = { seq: from.seq, to: to.id, via: via.id };
return socket.send(JSON.stringify(message), router.rinfo!.port, router.rinfo!.address); return socket.send(JSON.stringify(message), from.rinfo!.port, from.rinfo!.address);
} }
const socket = dgram const socket = dgram
.createSocket('udp4') .createSocket('udp4')
.on('message', function(message, rinfo) { .on('message', function(message, rinfo) {
try { try {
const hello: ServerMessage = JSON.parse(message.toString()); const hello: UploadMessage = JSON.parse(message.toString());
assert(hello.id); assert(hello.id);
const router: Router = Router.all.find(r => r.id === hello.id)!; const router: Router = Router.all.find(r => r.id === hello.id)!;
assert(router); assert(router);
if (_.isEqual(rinfo, router.rinfo)) { router.rinfo = rinfo;
router.rinfo = rinfo;
if (hello.ack === 0) {
router.reset(); router.reset();
} }
router.peers = hello.peers; if (hello.peers) router.peers = hello.peers;
if (updating) { if (updating) {
if (hello.ack === sequence) { if (hello.ack === router.seq + 1) {
clearInterval(updating); clearInterval(updating);
clearTimeout(timeout_timer); clearTimeout(timeout_timer);
updating = null; updating = null;
sequence++; router.seq++;
} }
return; return;
} }
...@@ -55,28 +53,27 @@ const socket = dgram ...@@ -55,28 +53,27 @@ const socket = dgram
const best_route = _.minBy(Router.all.filter(router => router.id !== from.id), (router) => from.route_quality(to, router).metric())!; const best_route = _.minBy(Router.all.filter(router => router.id !== from.id), (router) => from.route_quality(to, router).metric())!;
// 变更 // 变更
if (from.next_hop.get(to) !== best_route) { if (from.via.get(to) !== best_route) {
from.next_hop.set(to, best_route); from.via.set(to, best_route);
updating = setInterval(() => send_route(from, to, best_route), 1000); updating = setInterval(() => send_route(from, to, best_route), config.interval);
send_route(from, to, best_route); send_route(from, to, best_route);
timeout_timer = setTimeout(function() { timeout_timer = setTimeout(function() {
from.lost(); from.lost();
clearInterval(updating); clearInterval(updating);
updating = null; updating = null;
}, timeout * 1000); }, config.timeout * config.interval);
return; return;
} }
} }
} }
}); });
socket.bind(server_port); socket.bind(config.port);
//web management api //web management api
http http
.createServer(function(req, res) { .createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'application/json' }); res.writeHead(200, { 'Content-Type': 'application/json' });
return res.end(JSON.stringify(peers)); const result: Record<number, Record<number, number>> = Object.fromEntries(Router.all.map(from => [from.id, Object.fromEntries([...from.via.entries()].map(([to, via]) => [to.id, via.id]))]));
return res.end(JSON.stringify(result));
}) })
.listen(server_port); .listen(config.port);
// setInterval(refresh(socket, routers), 1000)
export interface PeerQuality {
delay: number;
jitter: number;
reliability: number;
}
export interface ServerMessage {
id: number;
ack: number;
peers: PeerQuality[];
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment