Skip to content

Commit

Permalink
Merge pull request #106 from sima-land/38-examples-bun
Browse files Browse the repository at this point in the history
Шаг 59 #38
  • Loading branch information
krutoo committed Mar 6, 2024
2 parents 2512751 + 8891f3e commit 306999f
Show file tree
Hide file tree
Showing 16 changed files with 580 additions and 287 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
/* eslint-disable require-jsdoc, jsdoc/require-jsdoc */
import { createPreset } from '../../../di';
import { KnownToken } from '../../../tokens';
import { PresetTuner } from '../../isomorphic';
import { createPreset } from '../../di';
import { KnownToken } from '../../tokens';
import { PresetTuner } from '../isomorphic';
import {
provideAbortController,
provideFetch,
provideReduxMiddlewareSaga,
} from '../../isomorphic/providers';
import { providePageRender } from '../../node/handler/providers';
import { SpecificExtras } from '../../node/handler/utils';
} from '../isomorphic/providers';
import { providePageRender } from '../node/handler/providers';
import { SpecificExtras } from '../node/handler/utils';
import { HandlerProviders } from './providers';

export function PresetHandler(customize?: PresetTuner) {
export function PresetBunHandler(customize?: PresetTuner) {
const preset = createPreset();

// http fetch
Expand All @@ -38,5 +38,3 @@ export function PresetHandler(customize?: PresetTuner) {

return preset;
}

export { HandlerProvider } from './utils';
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* eslint-disable require-jsdoc, jsdoc/require-jsdoc */
import { renderToString } from 'react-dom/server';
import { Resolve } from '../../../../di';
import { KnownToken } from '../../../../tokens';
import { HelmetContext, RegularHelmet } from '../../../node/handler/utils';
import { Resolve } from '../../../di';
import { KnownToken } from '../../../tokens';
import { HelmetContext, RegularHelmet } from '../../node/handler/utils';
import {
CookieStore,
Middleware,
Expand All @@ -14,12 +14,12 @@ import {
log,
LogHandler,
LogHandlerFactory,
} from '../../../../http';
} from '../../../http';
import { Fragment } from 'react';
import { FetchLogging } from '../../../isomorphic/utils';
import { getForwardedHeaders, getPageResponseFormat } from '../../../server/utils';
import { PageAssets } from '../../../isomorphic/types';
import { RESPONSE_EVENT_TYPE } from '../../../isomorphic/constants';
import { FetchLogging } from '../../isomorphic/utils';
import { getForwardedHeaders, getPageResponseFormat } from '../../server/utils';
import { PageAssets } from '../../isomorphic/types';
import { RESPONSE_EVENT_TYPE } from '../../isomorphic/constants';

export const HandlerProviders = {
handlerMain(resolve: Resolve) {
Expand Down
46 changes: 0 additions & 46 deletions src/preset/bun/bun/index.ts

This file was deleted.

70 changes: 0 additions & 70 deletions src/preset/bun/bun/utils/index.ts

This file was deleted.

50 changes: 48 additions & 2 deletions src/preset/bun/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,48 @@
export { PresetBun } from './bun';
export { PresetHandler, HandlerProvider } from './handler';
/* eslint-disable require-jsdoc, jsdoc/require-jsdoc */
import { createPreset } from '../../di';
import { KnownToken } from '../../tokens';
import { PresetTuner } from '../isomorphic';
import { provideBaseConfig } from '../isomorphic/providers';
import { provideKnownHttpApiHosts, provideSsrBridgeServerSide } from '../node/node/providers';
import { BunProviders } from './providers';

// @todo возможно стоит переименовать в PresetServer (так как в теории это можно использовать не только в Bun но и в Deno, Node.js)
export function PresetBun(customize?: PresetTuner) {
const preset = createPreset();

// config
preset.set(KnownToken.Config.source, BunProviders.configSource);
preset.set(KnownToken.Config.base, provideBaseConfig);

// log
preset.set(KnownToken.logger, BunProviders.logger);

// tracing
// @todo

// metrics
preset.set(KnownToken.Metrics.httpHandler, BunProviders.serveMetrics);

// http fetch
preset.set(KnownToken.Http.fetch, BunProviders.fetch);
preset.set(KnownToken.Http.Fetch.middleware, BunProviders.fetchMiddleware);

// http serve
preset.set(KnownToken.Http.serve, BunProviders.serve);
preset.set(KnownToken.Http.Serve.serviceRoutes, BunProviders.serviceRoutes);
preset.set(KnownToken.Http.Serve.middleware, BunProviders.serveMiddleware);

// http api
preset.set(KnownToken.Http.Api.knownHosts, provideKnownHttpApiHosts);

// ssr bridge
preset.set(KnownToken.SsrBridge.serverSide, provideSsrBridgeServerSide);

if (customize) {
customize({ override: preset.set.bind(preset) });
}

return preset;
}

export { HandlerProvider } from './utils';
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
/* eslint-disable require-jsdoc, jsdoc/require-jsdoc */
import { Resolve } from '../../../../di';
import { KnownToken } from '../../../../tokens';
import { ConfigSource, createConfigSource } from '../../../../config';
import { Logger, createLogger } from '../../../../log';
import { Handler, Middleware, log } from '../../../../http';
import { ServeLogging } from '../utils';
import { providePinoHandler } from '../../../node/node/providers';
import { Resolve } from '../../../di';
import { KnownToken } from '../../../tokens';
import { ConfigSource, createConfigSource } from '../../../config';
import { Logger, createLogger } from '../../../log';
import { Handler, Middleware } from '../../../http';
import { providePinoHandler } from '../../node/node/providers';
import { route, router } from '@krutoo/fetch-tools';
import { getCurrentHub, init, runWithAsyncContext } from '@sentry/bun';
import { createSentryHandler } from '../../../../log/handler/sentry';
import { healthCheck } from '../../../isomorphic/utils';
import { provideFetch } from '../../../isomorphic/providers';
import { toMilliseconds } from '../../../../utils';
import { ServerHandler, ServerMiddleware } from '../../../server/types';
import { applyServerMiddleware } from '../../../server/utils';
import { createSentryHandler } from '../../../log/handler/sentry';
import { provideFetch } from '../../isomorphic/providers';
import { ServerHandler, ServerMiddleware } from '../../server/types';
import {
applyServerMiddleware,
healthCheck,
getServeLogging,
getServeErrorLogging,
getServeMeasuring,
} from '../../server/utils';
import PromClient from 'prom-client';
import { RESPONSE_EVENT_TYPE } from '../../../isomorphic/constants';

export const BunProviders = {
configSource(): ConfigSource {
Expand Down Expand Up @@ -93,103 +95,20 @@ export const BunProviders = {
const config = resolve(KnownToken.Config.base);
const logger = resolve(KnownToken.logger);

const logging = new ServeLogging(logger);

// @todo перенести в preset/server
const ConventionalLabels = {
HTTP_RESPONSE: ['version', 'route', 'code', 'method'],
SSR: ['version', 'route', 'method'],
} as const;

const requestCount = new PromClient.Counter({
name: 'http_request_count',
help: 'Incoming HTTP request count',
labelNames: ConventionalLabels.HTTP_RESPONSE,
});

const responseDuration = new PromClient.Histogram({
name: 'http_response_duration_ms',
help: 'Duration of incoming HTTP requests in ms',
labelNames: ConventionalLabels.HTTP_RESPONSE,
buckets: [30, 100, 200, 500, 1000, 2500, 5000, 10000],
});

const renderDuration = new PromClient.Histogram({
name: 'render_duration_ms',
help: 'Duration of SSR ms',
labelNames: ConventionalLabels.SSR,
buckets: [0.1, 15, 50, 100, 250, 500, 800, 1500],
});

const getLabels = (
req: Request,
res: Response,
): Record<(typeof ConventionalLabels.HTTP_RESPONSE)[number], string | number> => ({
version: config.appVersion,
route: req.url,
code: res.status,
method: req.method,
});

return [
// ВАЖНО: изолируем хлебные крошки чтобы они группировались по входящим запросам
(request, next) => runWithAsyncContext(async () => next(request)),

// ВАЖНО: слой логирования ошибки ПЕРЕД остальными слоями чтобы не упустить ошибки выше
log({
onCatch: data => logging.onRequest(data),
}),
getServeErrorLogging(logger),

// @todo tracing

// метрики
async (request, next, context) => {
const responseStart = process.hrtime.bigint();
let renderStart = 0n;

context.events.addEventListener(
RESPONSE_EVENT_TYPE.renderStart,
() => {
renderStart = process.hrtime.bigint();
},
{ once: true },
);

context.events.addEventListener(
RESPONSE_EVENT_TYPE.renderFinish,
() => {
const renderFinish = process.hrtime.bigint();

renderDuration.observe(
{
version: config.appVersion,
method: request.method,
route: request.url,
},
toMilliseconds(renderFinish - renderStart),
);
},
{ once: true },
);

const response = await next(request);
const responseFinish = process.hrtime.bigint();

responseDuration.observe(
getLabels(request, response),
toMilliseconds(responseFinish - responseStart),
);

requestCount.inc(getLabels(request, response), 1);

return response;
},
getServeMeasuring(config),

// ВАЖНО: слой логирования запроса и ответа ПОСЛЕ остальных слоев чтобы использовать актуальные данные
log({
onRequest: data => logging.onRequest(data),
onResponse: data => logging.onResponse(data),
}),
getServeLogging(logger),
];
},

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable require-jsdoc, jsdoc/require-jsdoc */
import type { ServerHandler } from '../../../server/types';
import { KnownToken } from '../../../../tokens';
import { CURRENT_APP, type Application, type Resolve, Provider } from '../../../../di';
import type { ServerHandler } from '../../server/types';
import { KnownToken } from '../../../tokens';
import { CURRENT_APP, type Application, type Resolve, Provider } from '../../../di';

export function HandlerProvider(getApp: () => Application): Provider<ServerHandler> {
return (resolve: Resolve): ServerHandler => {
Expand Down
1 change: 1 addition & 0 deletions src/preset/isomorphic/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* События в процессе ответа на запрос.
* @todo Переименовать в PAGE_HANDLER_EVENT_TYPE и перенести в preset/server/constants.
*/
export const RESPONSE_EVENT_TYPE = {
// ВАЖНО: пусть здесь остаются строки в качестве значений чтобы их можно было использовать вместе с EventTarget
Expand Down
Loading

0 comments on commit 306999f

Please sign in to comment.