Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
deno-redisの紹介とJSRパッケージの運用について (toranoana.deno #21)
Search
uki00a
June 18, 2025
Programming
420
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
410
Other Decks in Programming
See All in Programming
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.1k
エージェンティックRAGにAWSで入門しよう!
har1101
8
1.6k
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
3
4k
AIだと陥りがちなJakarta EE最新技術への移行時の落とし穴と解決策
tnagao7
0
110
コンテキストの使い捨てをやめる — ビジネスルール駆動開発と miko —
ioki
0
200
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
1
170
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
280
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
770
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
540
軽量Java基盤の設計 DIコンテナに頼らない、長期保守と1秒起動の実現 JJUG CCC 2026 Spring
macha64
0
520
Vite+ Unified Toolchain for the Web
naokihaba
0
310
「エンジニアインターン、どうやって取った?」準備のリアルを語るLT会 Progate BAR
akiomatic
0
130
Featured
See All Featured
From π to Pie charts
rasagy
0
210
What's in a price? How to price your products and services
michaelherold
247
13k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
Code Reviewing Like a Champion
maltzj
528
40k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
1
350
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
590
Art, The Web, and Tiny UX
lynnandtonic
304
22k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.9k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
The Language of Interfaces
destraynor
162
27k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Technical Leadership for Architectural Decision Making
baasie
3
410
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 などの重要性が より増すかもしれないと思っています