| | const express = require('express'); |
| | const fetch = require('node-fetch'); |
| |
|
| | const app = express(); |
| | const TARGET_URL = 'https://rhknk53jznw37un7.us-east-1.aws.endpoints.huggingface.cloud'; |
| | const MAX_PARALLEL = 1; |
| | const MAX_WAIT_MS = 10 * 60 * 1000; |
| |
|
| | let activeRequests = 0; |
| | const queue = []; |
| |
|
| | async function processQueue() { |
| | while (queue.length > 0 && activeRequests < MAX_PARALLEL) { |
| | const { req, res, next } = queue.shift(); |
| | activeRequests++; |
| | handleRequest(req, res, next).finally(() => { |
| | activeRequests--; |
| | processQueue(); |
| | }); |
| | } |
| | } |
| |
|
| | async function retryWith503Backoff(url, options, startTime) { |
| | let attempt = 0; |
| | let lastResponse = null; |
| | |
| | while (true) { |
| | const elapsed = Date.now() - startTime; |
| | if (elapsed > MAX_WAIT_MS) { |
| | throw new Error('Max wait time exceeded (10 minutes)'); |
| | } |
| | |
| | const response = await fetch(url, options); |
| | lastResponse = response; |
| | |
| | |
| | if (response.ok) { |
| | return response; |
| | } |
| | |
| | |
| | if (response.status === 401) { |
| | return response; |
| | } |
| | |
| | |
| | |
| | if (response.status === 503) { |
| | |
| | const delay = Math.min(1000 * Math.pow(2, attempt), 64000); |
| | attempt++; |
| | |
| | |
| | if (elapsed + delay > MAX_WAIT_MS) { |
| | return response; |
| | } |
| | |
| | await new Promise(resolve => setTimeout(resolve, delay)); |
| | } else { |
| | |
| | if (attempt >= 3) { |
| | return response; |
| | } |
| | |
| | |
| | const delay = (attempt + 1) * 1000; |
| | attempt++; |
| | |
| | |
| | if (elapsed + delay > MAX_WAIT_MS) { |
| | return response; |
| | } |
| | |
| | await new Promise(resolve => setTimeout(resolve, delay)); |
| | } |
| | } |
| | } |
| |
|
| | async function handleRequest(req, res, next) { |
| | try { |
| | const startTime = Date.now(); |
| | const targetUrl = TARGET_URL + req.url; |
| | |
| | const options = { |
| | method: req.method, |
| | headers: { ...req.headers, host: new URL(TARGET_URL).host }, |
| | body: req.method !== 'GET' && req.method !== 'HEAD' ? req.body : undefined |
| | }; |
| | |
| | const response = await retryWith503Backoff(targetUrl, options, startTime); |
| | |
| | res.status(response.status); |
| | response.headers.forEach((value, key) => { |
| | res.setHeader(key, value); |
| | }); |
| | |
| | response.body.pipe(res); |
| | } catch (error) { |
| | res.status(504).json({ error: error.message }); |
| | } |
| | } |
| |
|
| | app.use(express.raw({ type: '*/*', limit: '50mb' })); |
| |
|
| | app.use((req, res, next) => { |
| | if (activeRequests < MAX_PARALLEL) { |
| | activeRequests++; |
| | handleRequest(req, res, next).finally(() => { |
| | activeRequests--; |
| | processQueue(); |
| | }); |
| | } else { |
| | queue.push({ req, res, next }); |
| | } |
| | }); |
| |
|
| | const PORT = process.env.PORT || 7860; |
| | app.listen(PORT, () => { |
| | console.log(`Reverse proxy listening on port ${PORT}`); |
| | console.log(`Proxying to: ${TARGET_URL}`); |
| | console.log(`Max parallel requests: ${MAX_PARALLEL}`); |
| | }); |