containerHelpers.ts•2.16 kB
export const MAX_CONTAINERS = 50
export async function startAndWaitForPort(
environment: 'dev' | 'prod' | 'test',
container: Container | undefined,
portToAwait: number,
maxTries = 10
): Promise<boolean> {
if (environment === 'dev' || environment === 'test') {
console.log('Running in dev, assuming locally running container')
return true
}
if (!container) {
throw new Error('Error: ctx.container is undefined. Does this DO support containers?')
}
const port = container.getTcpPort(portToAwait)
// promise to make sure the container does not exit
let monitor
for (let i = 0; i < maxTries; i++) {
try {
if (!container.running) {
console.log('starting container')
container.start({
enableInternet: true,
})
// force DO to keep track of running state
monitor = container.monitor()
void monitor.then(() => console.log('Container exited'))
}
const conn = await port.connect(`10.0.0.1:${portToAwait}`)
await conn.close()
console.log('Connected')
return true
} catch (err: any) {
if (!(err instanceof Error)) {
throw err
}
console.error('Error connecting to the container on', i, 'try', err)
if (err.message.includes('listening')) {
await new Promise((res) => setTimeout(res, 300))
continue
}
// no container yet
if (err.message.includes('there is no container instance that can be provided')) {
await new Promise((res) => setTimeout(res, 300))
continue
}
console.log(err)
return false
}
}
return false
}
export async function proxyFetch(
environment: 'dev' | 'prod' | 'test',
container: Container | undefined,
request: Request,
portNumber: number
): Promise<Response> {
if (environment === 'dev' || environment === 'test') {
const url = request.url
.replace('https://', 'http://')
.replace('http://host', 'http://localhost')
return fetch(url, request.clone() as Request)
}
if (!container) {
throw new Error('Error: ctx.container is undefined. Does this DO support containers?')
}
return await container
.getTcpPort(portNumber)
.fetch(request.url.replace('https://', 'http://'), request.clone() as Request)
}