@torrent-tv/proxy 2.101.36 → 2.101.37

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@torrent-tv/proxy",
3
- "version": "2.101.36",
3
+ "version": "2.101.37",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {
@@ -84,6 +84,8 @@ export async function handleApiTranscodeSessionsPost(req, reply, { viewerRequest
84
84
  const cancellation = new AbortController();
85
85
  const timing = { startedAt: performance.now(), openMs: 0, openCalls: 0,
86
86
  planWaitInclusiveMs: null, masterMs: null, offerMs: null, tracksMs: null };
87
+ const forwardedRequestId = typeof req.headers?.["x-ttv-forwarded-request-id"] === "string"
88
+ ? req.headers["x-ttv-forwarded-request-id"] : "unknown";
87
89
  const cancelled = () => cancellation.abort();
88
90
  reply.raw?.once?.("close", cancelled);
89
91
  if (reply.raw?.destroyed) cancelled();
@@ -220,6 +222,7 @@ export async function handleApiTranscodeSessionsPost(req, reply, { viewerRequest
220
222
  const elapsed = (key) => Number.isFinite(timing[key]) ? timing[key].toFixed(1) : "n/a";
221
223
  logger.info(
222
224
  `transcode-session timing outcome=${cancellation.signal.aborted ? "cancelled" : "handler-return"} ` +
225
+ `requestId=${forwardedRequestId} ` +
223
226
  `consumer=${consumerId || "unknown"} file=${fileIndex} openCalls=${timing.openCalls} ` +
224
227
  `openMs=${timing.openMs.toFixed(1)} planWaitInclusiveMs=${elapsed("planWaitInclusiveMs")} ` +
225
228
  `masterMs=${elapsed("masterMs")} offerMs=${elapsed("offerMs")} tracksMs=${elapsed("tracksMs")} ` +
package/server.js CHANGED
@@ -11,6 +11,7 @@ import fastifyCors from "@fastify/cors";
11
11
  import fastifyHelmet from "@fastify/helmet";
12
12
  import getPort from "get-port";
13
13
  import { createRequire } from "node:module";
14
+ import { performance } from "node:perf_hooks";
14
15
  import { handleHealthGet } from "./routes/health/get.js";
15
16
  import { handleMediaGet } from "./routes/media/get.js";
16
17
  import { ProbeRequests } from "./services/media/ProbeRequests.js";
@@ -170,6 +171,22 @@ export async function startProxyServer({
170
171
  app.addHook("onRequest", async (_req, reply) => {
171
172
  reply.header("Access-Control-Allow-Private-Network", "true");
172
173
  });
174
+ app.addHook("onRequest", async (req, reply) => {
175
+ const requestId = req.headers["x-ttv-forwarded-request-id"];
176
+ if (typeof requestId !== "string") return;
177
+ const startedAt = performance.now();
178
+ reply.raw.once("finish", () => {
179
+ logger.info(`[http-response] requestId=${requestId} method=${req.method} url=${req.url} ` +
180
+ `responseMs=${(performance.now() - startedAt).toFixed(1)} status=${reply.statusCode} ` +
181
+ `contentLength=${reply.raw.getHeader("content-length") ?? "unknown"}`);
182
+ });
183
+ reply.raw.once("close", () => {
184
+ if (!reply.raw.writableFinished) {
185
+ logger.warn(`[http-response] requestId=${requestId} method=${req.method} url=${req.url} ` +
186
+ `closedMs=${(performance.now() - startedAt).toFixed(1)} status=${reply.statusCode}`);
187
+ }
188
+ });
189
+ });
173
190
 
174
191
  const sourceRegistry = createSourceRegistry(200);
175
192
  // The torrent runs on its own thread. Profiling a live seek (2026-08-02)
@@ -276,13 +276,16 @@ export class LocalObservations {
276
276
  */
277
277
  noteFirstFrame({ seconds, features, featureSnapshots = null, stages = null }) {
278
278
  if (!Number.isFinite(seconds) || seconds < 0 || !features || typeof features !== "object") return;
279
+ const measuredStages = stagesOf(stages);
280
+ if (!measuredStages) return;
279
281
  const key = this.#firstFrameKey();
280
282
  const snapshots = [features, ...(Array.isArray(featureSnapshots) ? featureSnapshots : [])]
281
283
  .filter(value => value && typeof value === "object").slice(0, 2).map(firstFrameFeatures);
282
- const readings = [...(this.#entries.firstFrame[key] ?? []), {
284
+ const usableReadings = (this.#entries.firstFrame[key] ?? []).filter(reading => stagesOf(reading.stages));
285
+ const readings = [...usableReadings, {
283
286
  ...snapshots[0],
284
287
  featureSnapshots: snapshots,
285
- stages: stagesOf(stages),
288
+ stages: measuredStages,
286
289
  at: this.#now()
287
290
  }].slice(-READINGS_KEPT);
288
291
  this.#entries.firstFrame[key] = readings;
@@ -1171,7 +1171,11 @@ export function createDataChannelHandler({
1171
1171
  log(`[dc] ${method} ${path}${queryInfo}${bodyInfo}`);
1172
1172
 
1173
1173
  const targetUrl = `http://127.0.0.1:${proxyPort}${path}${query ? `?${query}` : ""}`;
1174
- const requestHeaders = { ...(forwardedHeaders ?? {}), host: `127.0.0.1:${proxyPort}` };
1174
+ const requestHeaders = {
1175
+ ...(forwardedHeaders ?? {}),
1176
+ host: `127.0.0.1:${proxyPort}`,
1177
+ "x-ttv-forwarded-request-id": requestId
1178
+ };
1175
1179
 
1176
1180
  let response;
1177
1181
  // [net-debug] TEMPORARY: time spent in the local fetch (waiting for the