@miso.ai/doggoganger 0.9.0-beta.15 → 0.9.0-beta.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.js +2 -14
- package/src/middleware/error.js +29 -0
- package/src/middleware/index.js +2 -0
- package/src/middleware/latency.js +39 -0
- package/src/route/index.js +5 -1
- package/src/route/products.js +9 -0
- package/src/utils.js +13 -0
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -5,13 +5,12 @@ import serveStatic from 'koa-static';
|
|
|
5
5
|
import { koaBody } from 'koa-body';
|
|
6
6
|
import _route from './route/index.js';
|
|
7
7
|
import Api from './api/index.js';
|
|
8
|
-
import { exclusion
|
|
9
|
-
import { gaussRandom } from './data/utils.js';
|
|
8
|
+
import { exclusion } from './utils.js';
|
|
10
9
|
|
|
11
10
|
export default function doggoganger({ port = 9901, serve = false, ...options } = {}) {
|
|
12
11
|
const app = new Koa();
|
|
13
12
|
const router = new Router();
|
|
14
|
-
const api = _route(new Api(options));
|
|
13
|
+
const api = _route(new Api(options), options);
|
|
15
14
|
|
|
16
15
|
router.use('/api', api.routes(), api.allowedMethods());
|
|
17
16
|
router.use('/v1', api.routes(), api.allowedMethods());
|
|
@@ -34,7 +33,6 @@ export default function doggoganger({ port = 9901, serve = false, ...options } =
|
|
|
34
33
|
},
|
|
35
34
|
}))
|
|
36
35
|
.use(handleAllPath(options))
|
|
37
|
-
.use(simulateLatency(options))
|
|
38
36
|
.use(router.routes())
|
|
39
37
|
.use(router.allowedMethods())
|
|
40
38
|
.use(handleUnrecognizedPath(options))
|
|
@@ -48,16 +46,6 @@ function handleAllPath({ verbose } = {}) {
|
|
|
48
46
|
};
|
|
49
47
|
}
|
|
50
48
|
|
|
51
|
-
function simulateLatency({ min = 200, max = 2000, verbose } = {}) {
|
|
52
|
-
// TODO: only apply to API calls
|
|
53
|
-
return async (_, next) => {
|
|
54
|
-
const time = ((min + max) + (gaussRandom() * (max - min))) / 2;
|
|
55
|
-
verbose && console.log(`Add latency: ${time}ms`);
|
|
56
|
-
await delay(time);
|
|
57
|
-
await next();
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
49
|
function handleUnrecognizedPath({ verbose } = {}) {
|
|
62
50
|
return async (ctx, next) => {
|
|
63
51
|
verbose && console.log(`Unrecognized path: ${ctx.method} ${ctx.url}`);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { trimObj } from '../utils.js';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_OPTIONS = {
|
|
4
|
+
rate: 0,
|
|
5
|
+
verbose: false,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export default function error(options) {
|
|
9
|
+
const globalOptions = {
|
|
10
|
+
...DEFAULT_OPTIONS,
|
|
11
|
+
...trimObj(options),
|
|
12
|
+
};
|
|
13
|
+
return async (ctx, next) => {
|
|
14
|
+
const { rate, verbose } = {
|
|
15
|
+
...globalOptions,
|
|
16
|
+
...getOptionsFromCtx(ctx),
|
|
17
|
+
};
|
|
18
|
+
if (rate && Math.random() < rate) {
|
|
19
|
+
verbose && console.log(`Simulate error`);
|
|
20
|
+
throw new Error();
|
|
21
|
+
}
|
|
22
|
+
await next();
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getOptionsFromCtx(ctx) {
|
|
27
|
+
const rate = Number(ctx.get('x-error-rate')) || undefined;
|
|
28
|
+
return trimObj({ rate });
|
|
29
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { delay, trimObj } from '../utils.js';
|
|
2
|
+
import { gaussRandom } from '../data/utils.js';
|
|
3
|
+
|
|
4
|
+
const DEFAULT_OPTIONS = {
|
|
5
|
+
enabled: true,
|
|
6
|
+
verbose: false,
|
|
7
|
+
min: 200,
|
|
8
|
+
max: 2000,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default function latency(options) {
|
|
12
|
+
const globalOptions = {
|
|
13
|
+
...DEFAULT_OPTIONS,
|
|
14
|
+
...trimObj(options),
|
|
15
|
+
};
|
|
16
|
+
return async (ctx, next) => {
|
|
17
|
+
const { enabled, min, max, verbose } = {
|
|
18
|
+
...globalOptions,
|
|
19
|
+
...getOptionsFromCtx(ctx),
|
|
20
|
+
};
|
|
21
|
+
if (enabled) {
|
|
22
|
+
const time = (min + max) / 2 + gaussRandom() * (max - min) / 6;
|
|
23
|
+
verbose && console.log(`Add latency: ${time}ms`);
|
|
24
|
+
await delay(time);
|
|
25
|
+
}
|
|
26
|
+
await next();
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function getOptionsFromCtx(ctx) {
|
|
31
|
+
const latencyStr = ctx.get('x-latency') || undefined;
|
|
32
|
+
if (latencyStr === '0' || latencyStr === 'false') {
|
|
33
|
+
return { enabled: false };
|
|
34
|
+
}
|
|
35
|
+
const value = Number(latencyStr) || undefined;
|
|
36
|
+
const min = value || Number(ctx.get('x-latency-min')) || undefined;
|
|
37
|
+
const max = value || Number(ctx.get('x-latency-max')) || undefined;
|
|
38
|
+
return trimObj({ min, max });
|
|
39
|
+
}
|
package/src/route/index.js
CHANGED
|
@@ -4,14 +4,18 @@ import recommendation from './recommendation.js';
|
|
|
4
4
|
import search from './search.js';
|
|
5
5
|
import interactions from './interactions.js';
|
|
6
6
|
import products from './products.js';
|
|
7
|
+
import { latency, error } from '../middleware/index.js';
|
|
7
8
|
|
|
8
9
|
function use(router, path, middleware) {
|
|
9
10
|
router.use(path, middleware.routes(), middleware.allowedMethods());
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
export default function(api) {
|
|
13
|
+
export default function(api, options) {
|
|
13
14
|
const router = new Router();
|
|
14
15
|
|
|
16
|
+
router.use(latency(options.latency));
|
|
17
|
+
//router.use(error(options.error));
|
|
18
|
+
|
|
15
19
|
use(router, '/ask', ask(api));
|
|
16
20
|
use(router, '/recommendation', recommendation(api));
|
|
17
21
|
use(router, '/search', search(api));
|
package/src/route/products.js
CHANGED
package/src/utils.js
CHANGED
|
@@ -28,3 +28,16 @@ export async function exclusion(ctx, next) {
|
|
|
28
28
|
export async function delay(time) {
|
|
29
29
|
return new Promise(resolve => setTimeout(resolve, time));
|
|
30
30
|
}
|
|
31
|
+
|
|
32
|
+
export function trimObj(obj) {
|
|
33
|
+
if (typeof obj !== 'object') {
|
|
34
|
+
return obj;
|
|
35
|
+
}
|
|
36
|
+
const trimmed = {};
|
|
37
|
+
for (const k in obj) {
|
|
38
|
+
if (Object.prototype.hasOwnProperty.call(obj, k) && obj[k] !== undefined) {
|
|
39
|
+
trimmed[k] = obj[k];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return trimmed;
|
|
43
|
+
}
|