-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add enableAutoPipelining parameter (#1062)
* add enableAutoPipelining parameter other changes: - made the proxy return type Redis - handled properties only available in Redis by returning them from redis * add auto pipelining example * rename variables in auto-pipeline * bump version to 1.30.2
- Loading branch information
Showing
27 changed files
with
474 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": "next/core-web-vitals" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
.yarn/install-state.gz | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env*.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
## Auto Pipeline Example | ||
|
||
This nextjs example showcases how Auto Pipelining works. | ||
|
||
In the `app/data/redis.ts` file, we define a redis client with `enableAutoPipelining: true`: | ||
|
||
```tsx | ||
import { Redis } from '@upstash/redis' | ||
|
||
export const LATENCY_LOGGING = true | ||
export const ENABLE_AUTO_PIPELINING = true | ||
|
||
const client = Redis.fromEnv({ | ||
latencyLogging: LATENCY_LOGGING, | ||
enableAutoPipelining: ENABLE_AUTO_PIPELINING | ||
}); | ||
|
||
export default client; | ||
``` | ||
|
||
We utilize this client in the `app/data/getUsers.ts` and `app/data/getEvents.ts` files to fetch data from the redis server (if there is no data, we insert data for the purposes of this example): | ||
|
||
```tsx | ||
// app/data/getUsers.ts | ||
|
||
import client from "./redis" | ||
|
||
export async function getUsers() { | ||
const keys = await client.scan(0, { match: 'user:*' }); | ||
|
||
if (keys[1].length === 0) { | ||
// If no keys found, insert sample data | ||
client.hmset('user:1', {'username': 'Adam', 'birthday': '1990-01-01'}); | ||
client.hmset('user:2', {'username': 'Eve', 'birthday': '1980-01-05'}); | ||
// Add more sample users as needed | ||
} | ||
|
||
const users = await Promise.all(keys[1].map(async key => { | ||
return client.hgetall(key) ?? {username: "default", birthday: "2000-01-01"}; | ||
})); | ||
return users as {username: string, birthday: string}[] | ||
} | ||
``` | ||
|
||
Both `getUsers` and `getEvents` work in a similar way. They first call and await scan to get the keys. Then, they call `HGETALL` with these keys. | ||
|
||
We import the `getUsers` and `getEvents` methods in our page `app/components/page.tsx`: | ||
|
||
```tsx | ||
"use server" | ||
import client from "../data/redis" | ||
import { getEvents } from "../data/getEvents"; | ||
import { getUsers } from "../data/getUsers"; | ||
|
||
const DataComponent = async () => { | ||
|
||
|
||
const [ users, events ] = await Promise.all([ | ||
getUsers(), | ||
getEvents() | ||
]) | ||
|
||
// @ts-ignore pipelineCounter is accessible but not available in the type | ||
const counter = client.pipelineCounter | ||
|
||
return ( | ||
<div> | ||
... skipped to keep the README short ... | ||
</div> | ||
); | ||
}; | ||
|
||
export default DataComponent; | ||
|
||
``` | ||
|
||
Thanks to auto pipelining, the scan commands from the two methods are sent in a single pipeline call. Then, the 4 `HGETALL` commands are sent in a second pipeline. In the end, 6 commands are sent with only two pipelines, with minimal overhead for the programmer. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
"use server" | ||
import client from "../data/redis" | ||
import { getEvents } from "../data/getEvents"; | ||
import { getUsers } from "../data/getUsers"; | ||
|
||
const DataComponent = async () => { | ||
|
||
|
||
const [ users, events ] = await Promise.all([ | ||
getUsers(), | ||
getEvents() | ||
]) | ||
|
||
// @ts-ignore pipelineCounter is accessible but not available in the type | ||
const counter = client.pipelineCounter | ||
|
||
return ( | ||
<div> | ||
|
||
<div> | ||
<h2>Users</h2> | ||
<ul> | ||
{users.map(user => | ||
<li key={user.username}> | ||
<strong>{user.username}</strong> - {user.birthday} | ||
</li> | ||
)} | ||
</ul> | ||
</div> | ||
|
||
<div> | ||
<h2>Events</h2> | ||
<ul> | ||
{events.map(event => | ||
<li key={event.name}> | ||
<strong>{event.name}</strong> - {event.date} | ||
</li> | ||
)} | ||
</ul> | ||
</div> | ||
|
||
<div> | ||
<h2>Number of Pipelines Called:</h2> {counter} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default DataComponent; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
|
||
import client from "./redis" | ||
|
||
export async function getEvents() { | ||
const keys = await client.scan(0, { match: 'event:*' }); | ||
|
||
if (keys[1].length === 0) { | ||
// If no keys found, insert sample data | ||
client.hmset('event:1', {'name': 'Sample Event 1', 'date': '2024-05-13'}); | ||
client.hmset('event:2', {'name': 'Sample Event 2', 'date': '2024-05-14'}); | ||
// Add more sample events as needed | ||
} | ||
|
||
const events = await Promise.all(keys[1].map(async key => { | ||
return client.hgetall(key) ?? {name: "default", date: "2000-01-01"}; | ||
})); | ||
return events as {name: string, date: string}[] | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
|
||
import client from "./redis" | ||
|
||
export async function getUsers() { | ||
const keys = await client.scan(0, { match: 'user:*' }); | ||
|
||
if (keys[1].length === 0) { | ||
// If no keys found, insert sample data | ||
client.hmset('user:1', {'username': 'Adam', 'birthday': '1990-01-01'}); | ||
client.hmset('user:2', {'username': 'Eve', 'birthday': '1980-01-05'}); | ||
// Add more sample users as needed | ||
} | ||
|
||
const users = await Promise.all(keys[1].map(async key => { | ||
return client.hgetall(key) ?? {username: "default", birthday: "2000-01-01"}; | ||
})); | ||
return users as {username: string, birthday: string}[] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
import { Redis } from '@upstash/redis' | ||
|
||
export const LATENCY_LOGGING = true | ||
export const ENABLE_AUTO_PIPELINING = true | ||
|
||
const client = Redis.fromEnv({ | ||
latencyLogging: LATENCY_LOGGING, | ||
enableAutoPipelining: ENABLE_AUTO_PIPELINING | ||
}); | ||
|
||
export default client; |
Binary file not shown.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import type { Metadata } from "next"; | ||
import { Inter } from "next/font/google"; | ||
import "./globals.css"; | ||
|
||
const inter = Inter({ subsets: ["latin"] }); | ||
|
||
export const metadata: Metadata = { | ||
title: "Create Next App", | ||
description: "Generated by create next app", | ||
}; | ||
|
||
export default function RootLayout({ | ||
children, | ||
}: Readonly<{ | ||
children: React.ReactNode; | ||
}>) { | ||
return ( | ||
<html lang="en"> | ||
<body className={inter.className}>{children}</body> | ||
</html> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
"use server" | ||
|
||
import React from 'react'; | ||
import DataComponent from './components/DataComponent' | ||
|
||
const HomePage = () => { | ||
return ( | ||
<div> | ||
<h1>Home Page</h1> | ||
<DataComponent /> | ||
</div> | ||
); | ||
}; | ||
|
||
export default HomePage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/** @type {import('next').NextConfig} */ | ||
const nextConfig = {}; | ||
|
||
export default nextConfig; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"name": "auto-pipeline", | ||
"version": "0.1.0", | ||
"private": true, | ||
"scripts": { | ||
"dev": "next dev", | ||
"build": "next build", | ||
"start": "next start", | ||
"lint": "next lint" | ||
}, | ||
"dependencies": { | ||
"@upstash/redis": "^1.30.1", | ||
"next": "14.2.3", | ||
"react": "^18", | ||
"react-dom": "^18" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^20", | ||
"@types/react": "^18", | ||
"@types/react-dom": "^18", | ||
"eslint": "^8", | ||
"eslint-config-next": "14.2.3", | ||
"postcss": "^8", | ||
"tailwindcss": "^3.4.1", | ||
"typescript": "^5" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** @type {import('postcss-load-config').Config} */ | ||
const config = { | ||
plugins: { | ||
tailwindcss: {}, | ||
}, | ||
}; | ||
|
||
export default config; |
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import type { Config } from "tailwindcss"; | ||
|
||
const config: Config = { | ||
content: [ | ||
"./pages/**/*.{js,ts,jsx,tsx,mdx}", | ||
"./components/**/*.{js,ts,jsx,tsx,mdx}", | ||
"./app/**/*.{js,ts,jsx,tsx,mdx}", | ||
], | ||
theme: { | ||
extend: { | ||
backgroundImage: { | ||
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))", | ||
"gradient-conic": | ||
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", | ||
}, | ||
}, | ||
}, | ||
plugins: [], | ||
}; | ||
export default config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"compilerOptions": { | ||
"lib": ["dom", "dom.iterable", "esnext"], | ||
"allowJs": true, | ||
"skipLibCheck": true, | ||
"strict": true, | ||
"noEmit": true, | ||
"esModuleInterop": true, | ||
"module": "esnext", | ||
"moduleResolution": "bundler", | ||
"resolveJsonModule": true, | ||
"isolatedModules": true, | ||
"jsx": "preserve", | ||
"incremental": true, | ||
"plugins": [ | ||
{ | ||
"name": "next" | ||
} | ||
], | ||
"paths": { | ||
"@/*": ["./*"] | ||
} | ||
}, | ||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], | ||
"exclude": ["node_modules"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.