Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1272,6 +1272,10 @@ export const functions: NavMenuConstant = {
name: 'Background Tasks',
url: '/guides/functions/background-tasks',
},
{
name: 'Ephemeral Storage',
url: '/guides/functions/ephemeral-storage',
},
{
name: 'Running AI Models',
url: '/guides/functions/ai-models',
Expand Down
56 changes: 38 additions & 18 deletions apps/docs/content/guides/functions/background-tasks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,59 @@ id: 'function-background-tasks'
title: 'Background Tasks'
description: 'How to run background tasks in an Edge Function outside of the request handler'
subtitle: 'How to run background tasks in an Edge Function outside of the request handler'
tocVideo: 'rSKBTJxG9VA'
---

Edge Function instances can process background tasks outside of the request handler. Background tasks are useful for asynchronous operations like uploading a file to Storage, updating a database, or sending events to a logging service. You can respond to the request immediately and leave the task running in the background.

### How long a background task can run
### How it works

A background task can run until the Edge Function instance hits its wall-clock limit or reaches CPU/Memory limit. Check [limits](/docs/guides/functions/limits) for current caps.
You can use `EdgeRuntime.waitUntil(promise)` to explicitly mark background tasks. The Function instance continues to run until the promise provided to `waitUntil` completes.

The maximum duration is capped based on the wall-clock, CPU, and memory limits. The Function will shutdown when it reaches one of these [limits](/docs/guides/functions/limits).

You can listen to the `beforeunload` event handler to be notified when Function invocation is about to be shut down.

### Example

Here's an example of defining a background task using a custom event.
Here's an example of using `EdgeRuntime.waitUntil` to run a background task and using `beforeunload` event to be notified when the instance is about to be shut down.

```ts
// Define a custom event type for the background task.
class MyBackgroundTaskEvent extends Event {
readonly taskPromise: Promise<Response>

constructor(taskPromise: Promise<Response>) {
super('myBackgroundTask')
this.taskPromise = taskPromise
}
async function longRunningTask() {
// do work here
}

globalThis.addEventListener('myBackgroundTask', async (event) => {
const res = await (event as MyBackgroundTaskEvent).taskPromise
console.log(await res.json())
// Mark the longRunningTask's returned promise as a background task.
// note: we are not using await because we don't want it to block.
EdgeRuntime.waitUntil(longRunningTask())

// Use beforeunload event handler to be notified when function is about to shutdown
addEventListener('beforeunload', (ev) => {
console.log('Function will be shutdown due to', ev.detail?.reason)

// save state or log the current progress
})

// Invoke the function using a HTTP request.
// This will start the background task
Deno.serve(async (req) => {
return new Response('ok')
})
```

### Starting a background task in the request handler

You can call `EdgeRuntime.waitUntil` in the request handler too. This will not block the request.

```ts
async function fetchAndLog(url: string) {
const response = await fetch('https://httpbin.org/json')
console.log(response)
}

Deno.serve(async (req) => {
const fetchPromise = fetch('https://httpbin.org/json')
const event = new MyBackgroundTaskEvent(fetchPromise)
globalThis.dispatchEvent(event)
// this will not block the request,
// instead it will run in the background
EdgeRuntime.waitUntil(fetchAndLog('https://httpbin.org/json'))

return new Response('ok')
})
Expand Down
54 changes: 54 additions & 0 deletions apps/docs/content/guides/functions/ephemeral-storage.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
id: 'function-ephemeral-storage'
title: 'Ephemeral Storage'
description: 'Read and write from temporary directory'
subtitle: 'Read and write from temporary directory'
---

Edge Functions provides ephemeral file storage. You can read and write files to the `/tmp` directory.

Ephemeral storage will reset on each function invocation. This means the files you write during an invocation can only be read within the same invocation.

### Use cases

Here are some use cases where ephemeral storage can be useful:

- Unzip an archive of CSVs and then add them as records to the DB
- Custom image manipulation workflows (using [MagickWasm](https://supabase.com/docs/guides/functions/examples/image-manipulation))

You can use [Background Tasks](https://supabase.com/docs/guides/functions/background-tasks) to handle slow file processing outside of a request.

### How to use

You can use [Deno File System APIs](https://docs.deno.com/api/deno/file-system) or the [`node:fs` module](https://docs.deno.com/api/node/fs/) to access the `/tmp` path.

### Example

Here is an example of how to write a user-uploaded zip file into temporary storage for further processing.

```js
Deno.serve(async (req) => {
if (req.headers.get('content-type') !== 'application/zip') {
return new Response('file must be a zip file', {
status: 400,
})
}

const uploadId = crypto.randomUUID()
await Deno.writeFile('/tmp/' + uploadId, req.body)

// do something with the written zip file

return new Response('ok')
})
```

### Unavailable APIs

Currently, the synchronous APIs (eg: `Deno.writeFileSync` or `Deno.mkdirSync`) for creating or writing files are not supported.

You can use sync variations of read APIs (eg: `Deno.readFileSync`).

### Limits

In the hosted platform, a free project can write up to 256MB of data to ephemeral storage. A paid project can write up to 512MB.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const CronjobsTab = () => {
</div>
)

const filteredCronJobs = (cronJobs ?? []).filter((cj) => cj.jobname.includes(searchQuery))
const filteredCronJobs = (cronJobs ?? []).filter((cj) => cj?.jobname?.includes(searchQuery || ''))

return (
<>
Expand Down
2 changes: 1 addition & 1 deletion apps/www/_blog/2024-12-01-orioledb-launch.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: 'OrioleDB Public Alpha'
description: 'Launching OrioleDB Public Alpha'
author: pavel
image: 2024-12-01-orioledb-release/thumb.png
image: 2024-12-01-orioledb-release/og.png
thumb: 2024-12-01-orioledb-release/thumb.png
categories:
- engineering
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,39 @@ export interface AdventLink {

export const days: AdventDay[] = [
{
title: '',
description: '',
id: '',
is_shipped: false,
links: [],
icon: null,
title: 'OrioleDB Public Alpha',
description: 'Postgres storage extension with better performance over default Heap storage',
id: 'orioledb',
is_shipped: true,
links: [
{ url: 'https://supabase.com/blog/orioledb-launch', label: 'Blog post', target: '_blank' },
],
icon: (
<svg
width="49"
height="50"
viewBox="0 0 49 50"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M32.3419 16.1687C26.9198 19.0762 22.2245 19.1919 20.5547 18.8863C24.0908 22.894 28.1618 23.1755 29.7552 22.8152C37.4684 22.442 40.855 13.0158 48.2546 13.2545C46.6043 11.4734 44.4237 11.05 43.5397 11.0609C39.6868 10.8581 35.3857 14.269 32.3419 16.1687Z"
fill="hsl(var(--foreground-light))"
/>
<path
d="M12.6959 13.353C17.8299 18.0154 25.4872 16.6927 28.6741 15.4485C25.7928 15.1342 22.0602 11.6504 20.554 9.94776C15.0031 4.03282 7.47323 1.59481 0.253906 6.21518C4.37942 6.80454 6.27846 7.52486 12.6959 13.353Z"
fill="hsl(var(--foreground-light))"
/>
<path
d="M24.5485 2.22059C21.6148 -0.555946 15.8172 0.496169 13.2852 1.36929C17.4762 1.36929 22.8022 7.61206 24.9414 10.7334C27.6059 14.037 30.8974 13.9871 32.2101 13.5493C31.1624 12.8158 29.7217 10.1441 29.1324 8.89988C27.194 5.18037 25.2688 2.89722 24.5485 2.22059Z"
fill="hsl(var(--foreground-light))"
/>
<path
d="M31.1956 7.73838C30.7536 5.49555 28.9582 3.13734 27.8886 1.82766C30.4359 1.82766 35.7101 3.85375 34.6335 7.26286C34.162 9.88223 34.0878 12.196 34.1096 13.0255C32.3809 11.7158 31.4532 9.04546 31.1956 7.73838Z"
fill="hsl(var(--foreground-light))"
/>
</svg>
),
},
{
title: '',
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading