Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
deno-redisの紹介とJSRパッケージの運用について (toranoana.deno #21)
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
uki00a
June 18, 2025
Programming
480
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
deno-redisの紹介とJSRパッケージの運用について (toranoana.deno #21)
uki00a
June 18, 2025
More Decks by uki00a
See All by uki00a
Denoのセキュリティに関する仕組みの紹介 (toranoana.deno #23)
uki00a
0
460
Other Decks in Programming
See All in Programming
Atomic Design, Enforced: Scaling Mobile Design Systems (next.app devCon / droidCon Berlin 2026)
steliosf
PRO
0
140
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
340
The Rails Doctrine Decade
koic
2
530
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
1
350
プロダクトコードからライブラリの境界を見つける
elmetal
PRO
0
110
すこし踏み込む CancellationToken
htkym
2
1.6k
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
360
SREの越境 / SRE Collaboration
y0hgi
2
300
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
570
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
21
21k
残高管理から台帳サービスへの進化
artoy
0
180
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.5k
Featured
See All Featured
What the history of the web can teach us about the future of AI
inesmontani
PRO
2
730
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
530
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
440
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
The browser strikes back
jonoalderson
0
1.8k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
910
YesSQL, Process and Tooling at Scale
rocio
174
15k
Music & Morning Musume
bryan
48
7.4k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.5k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
510
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3k
Transcript
deno-redis の紹介とJSR パッケージの運 用について (toranoana.deno #21)
今日話すこと deno-redis というJSR パッケージを題材に、JSR パッケージの開発や運 用に関する話をします。
自己紹介 @uki00a deno-weekly というWeb サ イトを運営しています RevComm Inc.
deno-redis ( jsr:@db/redis ) について Deno で実装されたRedis クライアント JSR (
jsr:@db/redis ) と deno.land/x (https://deno.land/x/redis) で 公開 作者はkeroxp さんです 2020 年ぐらいからdenodrivers というコミュニティ内で細々とメン テナンスを続けています
deno-redis ( jsr:@db/redis ) について import { connect } from
"jsr:@db/redis"; const redis = await connect({ hostname: "127.0.0.1", port: 6379, }); const ok = await redis.set("key", "foo"); const result = await redis.get("key");
1. Deno v2 における破壊的変更への対応
Deno v1 におけるIO ( Deno.{Reader,Writer} ) // Deno.Reader const buf
= new Uint8Array(128); doSomethingWithInput(await conn.read(buf)); // Deno.Writer const data = new TextEncoder().encode("foo"); await conn.write(data);
Deno v2 におけるIO (Stream API) // ReadableStream const reader =
conn.readable.getReader(); doSomethingWithInput(await reader.read()); reader.releaseLock(); // WritableStream const writer = conn.writable.getWriter(); const data = new TextEncoder().encode("foo"); await writer.write(data); writer.releaseLock();
Deno.{Reader,Writer} からStream API への移行 deno-redis においても Deno.Reader 及び Deno.Writer からStream
API への移行対応を実施することに しかし、移行にあたってビッグバンリリースはできれば避けたいで す...
Deno.{Reader,Writer} からStream API への移行 段階的に移行するために、 Protocol という抽象を用意することにしま した。 export interface
Protocol { sendCommand( command: string, args: Array<RedisValue>, returnsUint8Arrays?: boolean, ): Promise<RedisReply>; readReply(returnsUint8Array?: boolean): Promise<RedisReply>; writeCommand(command: Command): Promise<void>; // ... }
Deno.{Reader,Writer} からStream API への移行 // `Deno.Reader` & `Deno.Writer` ベースの実装 (Deno
v1 向け) export class DenoStreamBasedProtocol implements Protocol { #reader: BufReader; #writer: BufWriter; constructor(conn: Deno.Conn) { this.#reader = new BufReader(conn); this.#writer = new BufWriter(conn); } // 実装... } // Stream API ベースの実装 (Deno v2 向け) export class WebStreamBasedProtocol implements Protocol { #readable: BufferedReadableStream; #writable: WritableStream<Uint8Array>; constructor(conn: Deno.Conn) { this.#readable = new BufferedReadableStream(conn.readable); this.#writable = conn.writable; } // 実装... }
Deno.{Reader,Writer} からStream API への移行 ユーザーが任意でそれぞれの実装を切り替えられるようにします: // Deno v1 向け (Deno.Reader
& Deno.Writer) import { connect as connectV1 } from "jsr:@db/redis"; // Deno v2 向け (Stream API) import { connect as connectV2 } from "jsr:@db/redis/experimental/web-streams-connection"
Deno.{Reader,Writer} からStream API への移行 互換性を担保するために、それぞれの実装に対して同一のテストを実 行します Deno.test("commands", async (t) =>
{ for (const [type, connector] of [["v1", connectV1], ["v2", connectV2]]) { await t.step(type, async (t) => { await t.step("SET", async () => { using client = await connector(); assertEquals(await client.set("key", "foo"), "OK"); }); }); } });
2. パフォーマンスチューニング
Stream API への移行に伴うパフォーマンスの劣化につ いて なんとかStream API への対応については実施できました しかし、Stream API ベースの実装は
Deno.Reader & Deno.Writer ベー スの実装と比較してパフォーマンスが悪いことが分かりました パフォーマンス改善による効果を計測できるよう、ベンチマークの仕 組みがあると便利です
ベンチマーク Deno には deno bench というベンチマークのための仕組みあります const value = "bar".repeat(10);
Deno.bench("get & set", async (b) => { const client = await connect(options); b.start(); const key = "foo"; await client.set(key, value); await client.get(key); b.end(); });
ベンチマーク やりたいこと Deno ( deno-redis ) とNode.js ( ioredis )
で同じベンチマークコード を実行したい 課題 deno bench はNode.js では動作しません...
ベンチマーク benny はDeno とNode.js の両方で動きます (benchmark/benchmark.js) import { add, suite,
/* ... */ } from "benny"; export const run = ({ driver, // "deno-redis" or "ioredis" client, // `Redis` object of `deno-redis` or `ioredis` }) => suite(driver, add("set & get", () => { return async () => { await client.set("foo", "bar"); await client.get("foo"); }; }), );
解決策 BYOB (ReadableStreamBYOBReader) を使用することでパフォーマ ンスをかなり改善できることが判明しました ( Deno.Reader & Deno.Writer と同等程度のパフォーマンスを発揮してくれる)
// ReadableStreamBYOBReader を使いたい場合、`mode: "byob"` を指定する readableStream.getReader({ mode: "byob" }); バッファリングの仕組みが欲しかったので、自前で用意しています (BufferedReadableStream)
3. deno lint の活用
おすすめの設定 JSR パッケージを開発する際は no-console ルールを無効化しておく とおすすめです ( パッケージ内に意図せぬデバッグ用のログが残っ てしまうことを防止できます) {
"lint": { "rules": { "include": ["no-console"] }, "plugins": ["jsr:@uki00a/
[email protected]
"] } } Deno v2.2 でプラグインシステムがサポートされました (deno-lint- plugin-extra-rules という自作プラグインを使っています)
4. CI
依存パッケージをキャッシュする denoland/
[email protected]
から依存パッケージのキャッシュがサポ ートされています: jobs: test: runs-on: ubuntu-latest steps: -
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up Deno uses: denoland/setup-deno@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb # v2.0.3 with: deno-version: 2.3.3 cache: true # キャッシュを有効化 cache-hash: ${{ hashFiles('.deno-version', 'deno.lock') }}
5. 今後について
Deno Deploy Early Access https://x.com/deno_land/status/1929971203512435189 より引用 Soon! (but early access
is now open) Opt in via your dashboard http://dash.deno.com “ “
Deno Deploy Early Access とは? Databases: Coming soon Logs: Supported
Tracing: Supported Metrics: Supported OpenTelemetry export: Work in progress 公式ドキュメントより引用
deno-redis の今後について OpenTelemetry のサポートを強化したい (Deno Deploy Early Access 向け) Cloudflare
Workers のサポート RESP3 のサポートなど
まとめ. Deno ライブラリの開発で意識すると良 いこと 1. ベンチマークやLint 、テストなどのCI 周りを整備すると、メンテナ ンスが継続しやすくなると思います 2.
大掛かりな移行や改修をする場合、抽象の導入やベンチマークによ る計測などを活用して段階的に移行すると安全だと思います 3. Deno Deploy Early Access によってOpenTelemetry などの重要性が より増すかもしれないと思っています