Skip to content

Commit a2831e2

Browse files
w3b6x9fsansalvadoreGreg Papascharislamolirice
authored
feat: lw13d4 (supabase#30908)
* lw13:d4 * www queues page (supabase#30907) * new products menu * set up cron page * set up cron page * placeholder sections * set up queues page * update meta * update Supabase Queues landing page content * Updated the text to exclude queue creation/management from the API management section * queues www page --------- Co-authored-by: Wen Bo Xie <[email protected]> Co-authored-by: Greg Papas <[email protected]> * feat: add queue module (supabase#30853) * feat: postgres integrations Create a new global navigation and homepage menu section for the Postgres Integrations category. reorg: move cron docs into postgres integrations feat: postgres integrations Create a new global navigation and homepage menu section for the Postgres Integrations category. reorg: move cron docs into postgres integrations docs homepage layout feat: postgres integrations Create a new global navigation and homepage menu section for the Postgres Integrations category. reorg: move cron docs into postgres integrations feat: postgres integrations Create a new global navigation and homepage menu section for the Postgres Integrations category. reorg: move cron docs into postgres integrations docs homepage layout feat: postgres integrations Create a new global navigation and homepage menu section for the Postgres Integrations category. reorg: move cron docs into postgres integrations feat: postgres integrations Create a new global navigation and homepage menu section for the Postgres Integrations category. reorg: move cron docs into postgres integrations docs homepage layout * fix: add pg_cron back to extensions sidebar * update Supabase Cron docs * feat: add queues module feat: add queues module * remove staging url from screenshots * remove outdated cron files * typo * queues description update --------- Co-authored-by: Francesco Sansalvadore <[email protected]> Co-authored-by: Wen Bo Xie <[email protected]> Co-authored-by: Oliver Rice <[email protected]> * visibility timeout to window * queues landing page sql example * capitalize Dashboard * cron blog post citus data callout update * added draft of queues feature * updated features bulleting * pluralize queues * fix Queues features page * Inital bp * queues docs updates * format queues docs * queues blog post updates * edits * Update the images for role in the docs quickstart for queues. * updated images * update images * update more images * Update 2024-12-05-supabase-queues.mdx * fix breaks * punchier title * better ul * clean up * Retake screenshots * grammar * whitelines * video + images * update docs * blog updates * blog update * api snippet * api snippet fix * queues features yt video * api snippet fix * update docs * blog update * api snippet fix and vale * format * vale off * vale off * blog update --------- Co-authored-by: Francesco Sansalvadore <[email protected]> Co-authored-by: Greg Papas <[email protected]> Co-authored-by: Charis <[email protected]> Co-authored-by: Oliver Rice <[email protected]> Co-authored-by: Terry Sutton <[email protected]> Co-authored-by: Copple <[email protected]> Co-authored-by: Ivan Vasilov <[email protected]> Co-authored-by: Jonathan Summers-Muir <[email protected]>
1 parent af5e555 commit a2831e2

File tree

61 files changed

+1083
-87
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1083
-87
lines changed

apps/docs/app/page.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,12 @@ const postgresIntegrations = [
7979
href: '/guides/cron',
8080
description: 'Schedule and monitor recurring Jobs',
8181
},
82-
// {
83-
// title: 'Queues',
84-
// icon: 'queue',
85-
// href: '/guides/queue',
86-
// description: 'Postgres-native pull queues',
87-
// },
82+
{
83+
title: 'Queues',
84+
icon: 'queues',
85+
href: '/guides/queues',
86+
description: 'Durable Message Queues with guaranteed delivery',
87+
},
8888
]
8989

9090
const selfHostingOptions = [

apps/docs/components/Navigation/NavigationMenu/MenuIconPicker.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ function getMenuIcon(menuKey: string, width: number = 16, height: number = 16, c
9595
return <Server width={width} height={height} className={className} />
9696
case 'cron':
9797
return <Clock width={width} height={height} className={className} />
98-
case 'queue':
98+
case 'queues':
9999
return <SquareStack width={width} height={height} className={className} />
100100
default:
101101
return <IconMenuPlatform width={width} height={height} className={className} />

apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ export const GLOBAL_MENU_ITEMS: GlobalMenuItems = [
6363
href: '/guides/cron',
6464
level: 'cron',
6565
},
66-
// {
67-
// label: 'Queues',
68-
// icon: 'queue',
69-
// href: '/guides/queues',
70-
// level: 'queue',
71-
// },
66+
{
67+
label: 'Queues',
68+
icon: 'queues',
69+
href: '/guides/queues',
70+
level: 'queues',
71+
},
7272
],
7373
],
7474
},
@@ -1146,6 +1146,25 @@ export const cron: NavMenuConstant = {
11461146
],
11471147
}
11481148

1149+
export const queues: NavMenuConstant = {
1150+
icon: 'queues',
1151+
title: 'Queues',
1152+
url: '/guides/queues',
1153+
items: [
1154+
{ name: 'Overview', url: '/guides/queues' },
1155+
{
1156+
name: 'Getting Started',
1157+
url: undefined,
1158+
items: [{ name: 'Quickstart', url: '/guides/queues/quickstart' }],
1159+
},
1160+
{
1161+
name: 'References',
1162+
url: undefined,
1163+
items: [{ name: 'API', url: '/guides/queues/api' }],
1164+
},
1165+
],
1166+
}
1167+
11491168
export const api: NavMenuConstant = {
11501169
icon: 'rest',
11511170
title: 'REST API',

apps/docs/components/Navigation/NavigationMenu/NavigationMenu.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ enum MenuId {
1616
Storage = 'storage',
1717
Ai = 'ai',
1818
Cron = 'cron',
19+
Queues = 'queues',
1920
Platform = 'platform',
2021
Deployment = 'deployment',
2122
MonitoringTroubleshooting = 'monitoring_troubleshooting',
@@ -78,6 +79,10 @@ const menus: Menu[] = [
7879
id: MenuId.Graphql,
7980
type: 'guide',
8081
},
82+
{
83+
id: MenuId.Queues,
84+
type: 'guide',
85+
},
8186
{
8287
id: MenuId.Auth,
8388
type: 'guide',

apps/docs/components/Navigation/NavigationMenu/NavigationMenu.utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ export const getMenuId = (pathname: string | null) => {
129129
return MenuId.MonitoringTroubleshooting
130130
case pathname.startsWith('platform'):
131131
return MenuId.Platform
132+
case pathname.startsWith('queues'):
133+
return MenuId.Queues
132134
case pathname.startsWith('realtime'):
133135
return MenuId.Realtime
134136
case pathname.startsWith('resources'):
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
title: Supabase Queues
3+
subtitle: 'Durable Message Queues with Guaranteed Delivery in Postgres'
4+
---
5+
6+
Supabase Queues is a Postgres-native durable Message Queue system with guaranteed delivery built on the [pgmq database extension](https://github.com/tembo-io/pgmq). It offers developers a seamless way to persist and process Messages in the background while improving the resiliency and scalability of their applications and services.
7+
8+
Queues couples the reliability of Postgres with the simplicity Supabase's platform and developer experience, enabling developers to manage Background Tasks with zero configuration.
9+
10+
## Features
11+
12+
- **Postgres Native**
13+
<br />
14+
Built on top of the `pgmq` database extension, create and manage Queues with any Postgres tooling.
15+
- **Guaranteed Message Delivery**
16+
<br />
17+
Messages added to Queues are guaranteed to be delivered to your consumers.
18+
- **Exactly Once Message Delivery**
19+
<br />A Message is delivered exactly once to a consumer within a customizable visibility window.
20+
- **Message Durability and Archival**
21+
<br />
22+
Messages are stored in Postgres and you can choose to archive them for analytical or auditing purposes.
23+
- **Granular Authorization**
24+
<br />
25+
Control client-side consumer access to Queues with API permissions and Row Level Security (RLS) policies.
26+
- **Queue Management and Monitoring**
27+
<br />
28+
Create, manage, and monitor Queues and Messages in the Supabase Dashboard.
29+
30+
## Resources
31+
32+
- [Quickstart](/docs/guides/queues/quickstart)
33+
- [API Reference](/docs/guides/queues/api)
34+
- [`pgmq` GitHub Repository](https://github.com/tembo-io/pgmq)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
title: API
3+
---
4+
5+
{/* <!-- vale off --> */}
6+
When you create a Queue in Supabase, you can choose to create helper database functions in the `pgmq_public` schema. This schema exposes operations to manage Queue Messages to consumers client-side, but does not expose functions for creating or dropping Queues.
7+
8+
Database functions in `pgmq_public` can be exposed via Supabase Data API so consumers client-side can call them. Visit the [Quickstart](/docs/guides/queues/quickstart) for an example.
9+
10+
## `pgmq_public.pop(queue_name)`
11+
12+
Retrieves the next available message and deletes it from the specified Queue.
13+
14+
- `queue_name` (text): Queue name
15+
16+
---
17+
18+
### `pgmq_public.send(queue_name, message, sleep_seconds)`
19+
20+
Adds a Message to the specified Queue, optionally delaying its visibility to all consumers by a number of seconds.
21+
22+
- `queue_name` (text): Queue name
23+
- `message` (jsonb): Message payload to send
24+
- `sleep_seconds` (integer, optional): Delay message visibility by specified seconds. Defaults to 0
25+
26+
---
27+
28+
### `pgmq_public.send_batch(queue_name, messages, sleep_seconds)`
29+
30+
Adds a batch of Messages to the specified Queue, optionally delaying their availability to all consumers by a number of seconds.
31+
32+
- `queue_name` (text): Queue name
33+
- `messages` (jsonb[]): Array of message payloads to send
34+
- `sleep_seconds` (integer, optional): Delay messages visibility by specified seconds. Defaults to 0
35+
36+
---
37+
38+
### `pgmq_public.archive(queue_name, message_id)`
39+
40+
Archives a Message by moving it from the Queue table to the Queue's archive table.
41+
42+
- `queue_name` (text): Queue name
43+
- `message_id` (bigint): ID of the Message to archive
44+
45+
---
46+
47+
### `pgmq_public.delete(queue_name, message_id)`
48+
49+
Permanently deletes a Message from the specified Queue.
50+
51+
- `queue_name` (text): Queue name
52+
- `message_id` (bigint): ID of the Message to delete
53+
54+
---
55+
56+
### `pgmq_public.read(queue_name, sleep_seconds, n)`
57+
58+
Reads up to "n" Messages from the specified Queue with an optional "sleep_seconds" (visibility timeout).
59+
60+
- `queue_name` (text): Queue name
61+
- `sleep_seconds` (integer): Visibility timeout in seconds
62+
- `n` (integer): Maximum number of Messages to read
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
---
2+
title: Quickstart
3+
subtitle: 'Learn how to use Supabase Queues to add and read messages'
4+
---
5+
6+
{/* <!-- vale off --> */}
7+
This guide is an introduction to interacting with Supabase Queues via the Dashboard and official client library. Check out [Queues API Reference](/docs/guides/queues/api) for more details on our API.
8+
9+
## Concepts
10+
11+
Supabase Queues is a pull-based Message Queue consisting of three main components: Queues, Messages, and Queue Types.
12+
13+
### Pull-Based Queue
14+
15+
A pull-based Queue is a Message storage and delivery system where consumers actively fetch Messages when they're ready to process them - similar to constantly refreshing a webpage to display the latest updates. Our pull-based Queues process Messages in a First-In-First-Out (FIFO) manner without priority levels.
16+
17+
### Message
18+
19+
A Message in a Queue is a json object that is stored until a consumer explicitly processes and removes it, like a task waiting in a to-do list until someone checks and completes it.
20+
21+
### Queue Types
22+
23+
Supabase Queues offers three types of Queues:
24+
25+
- **Basic Queue**: A durable Queue that stores Messages in a logged table.
26+
- **Unlogged Queue**: A transient Queue that stores Messages in an unlogged table for better performance but may result in loss of Queue Messages.
27+
28+
- **Partitioned Queue** (_Coming Soon_): A durable and scalable Queue that stores Messages in multiple table partitions for better performance.
29+
30+
## Create Queues
31+
32+
To get started, navigate to the [Supabase Queues](/dashboard/project/_/integrations/queues/overview) Postgres Module under Integrations in the Dashboard and enable the `pgmq` extension.
33+
34+
<Admonition type="note">
35+
36+
`pgmq` extension is available in Postgres version 15.6.1.143 or later.
37+
38+
</Admonition>
39+
40+
<Image
41+
alt="Supabase Dashboard Integrations page, showing the Queues Postgres Module"
42+
src={{
43+
dark: '/docs/img/queues-quickstart-install.png',
44+
light: '/docs/img/queues-quickstart-install.png',
45+
}}
46+
/>
47+
48+
On the [Queues page](/dashboard/project/_/integrations/queues/queues):
49+
50+
- Click **Add a new queue** button
51+
52+
<Admonition type="note">
53+
54+
If you've already created a Queue click the **Create a queue** button instead.
55+
56+
</Admonition>
57+
58+
- Name your queue
59+
60+
<Admonition type="note">
61+
62+
Queue names can only be lowercase and hyphens and underscores are permitted.
63+
64+
</Admonition>
65+
66+
- Select your [Queue Type](#queue-types)
67+
68+
<Image
69+
alt="Create a Queue from the Supabase Dashboard"
70+
src={{
71+
dark: '/docs/img/queues-quickstart-create.png',
72+
light: '/docs/img/queues-quickstart-create.png',
73+
}}
74+
zoomable
75+
className="max-w-lg !mx-auto"
76+
/>
77+
78+
### What happens when you create a queue?
79+
80+
Every new Queue creates two tables in the `pgmq` schema. These tables are `pgmq.q_<queue_name>` to store and process active messages and `pgmq.a_<queue_name>` to store any archived messages.
81+
82+
A "Basic Queue" will create `pgmq.q_<queue_name>` and `pgmq.a_<queue_name>` tables as logged tables.
83+
84+
However, an "Unlogged Queue" will create `pgmq.q_<queue_name>` as an unlogged table for better performance while sacrificing durability. The `pgmq.a_<queue_name>` table will still be created as a logged table so your archived messages remain safe and secure.
85+
86+
## Expose Queues to client-side consumers
87+
88+
Queues, by default, are not exposed over Supabase Data API and are only accessible via Postgres clients.
89+
90+
However, you may grant client-side consumers access to your Queues by enabling the Supabase Data API and granting permissions to the Queues API, which is a collection of database functions in the `pgmq_public` schema that wraps the database functions in the `pgmq` schema.
91+
92+
This is to prevent direct access to the `pgmq` schema and its tables (RLS is not enabled by default on any tables) and database functions.
93+
94+
To get started, navigate to the Queues [Settings page](/dashboard/project/_/integrations/queues/settings) and toggle on “Expose Queues via PostgREST”. Once enabled, Supabase creates and exposes a `pgmq_public` schema containing database function wrappers to a subset of `pgmq`'s database functions.
95+
96+
<Image
97+
alt="Screenshot of Queues settings with toggle to expose to PostgREST"
98+
src={{
99+
dark: '/docs/img/queues-quickstart-settings.png',
100+
light: '/docs/img/queues-quickstart-settings.png',
101+
}}
102+
/>
103+
104+
### Enable RLS on your tables in `pgmq` schema
105+
106+
For security purposes, you must enable Row Level Security (RLS) on all Queue tables (all tables in `pgmq` schema that begin with `q_`) if the Data API is enabled.
107+
108+
You’ll want to create RLS policies for any Queues you want your client-side consumers to interact with.
109+
110+
<Image
111+
alt="Screenshot of creating an RLS policy from the Queues settings"
112+
src={{
113+
dark: '/docs/img/queues-quickstart-rls.png',
114+
light: '/docs/img/queues-quickstart-rls.png',
115+
}}
116+
/>
117+
118+
### Grant permissions to `pgmq_public` database functions
119+
120+
On top of enabling RLS and writing RLS policies on the underlying Queue tables, you must grant the correct permissions to the `pgmq_public` database functions for each Data API role.
121+
122+
The permissions required for each Queue API database function:
123+
124+
| **Operations** | **Permissions Required** |
125+
| ------------------- | ------------------------ |
126+
| `send` `send_batch` | `Select` `Insert` |
127+
| `read` `pop` | `Select` `Update` |
128+
| `archive` `delete` | `Select` `Delete` |
129+
130+
<Image
131+
alt="Screenshot of configuring API access for roles from the Queues settings"
132+
src={{
133+
dark: '/docs/img/queues-quickstart-roles.png',
134+
light: '/docs/img/queues-quickstart-roles-light.png',
135+
}}
136+
/>
137+
138+
<Admonition type="note">
139+
140+
`postgres` and `service_role` roles should never be exposed client-side.
141+
142+
</Admonition>
143+
144+
### Enqueuing and Dequeuing Messages
145+
146+
Once your Queue has been created, you can begin enqueuing and dequeuing Messages.
147+
148+
Here's a TypeScript example using the official Supabase client library:
149+
150+
```tsx
151+
import { createClient } from '@supabase/supabase-js'
152+
153+
const supabaseUrl = 'supabaseURL'
154+
const supabaseKey = 'supabaseKey'
155+
156+
const supabase = createClient(supabaseUrl, supabaseKey)
157+
158+
const QueuesTest: React.FC = () => {
159+
//Add a Message
160+
const sendToQueue = async () => {
161+
const result = await supabase.rpc('send', {
162+
queue_name: 'foo',
163+
message: { hello: 'world' },
164+
sleep_seconds: 30,
165+
})
166+
console.log(result)
167+
}
168+
169+
//Dequeue Message
170+
const popFromQueue = async () => {
171+
const result = await supabase.rpc('pop', { queue_name: 'foo' })
172+
console.log(result)
173+
}
174+
175+
return (
176+
<div className="p-6">
177+
<h2 className="text-2xl font-bold mb-4">Queue Test Component</h2>
178+
<button
179+
onClick={sendToQueue}
180+
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 mr-4"
181+
>
182+
Add Message
183+
</button>
184+
<button
185+
onClick={popFromQueue}
186+
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
187+
>
188+
Pop Message
189+
</button>
190+
</div>
191+
)
192+
}
193+
194+
export default QueuesTest
195+
```

0 commit comments

Comments
 (0)