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
490
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
470
Other Decks in Programming
See All in Programming
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
1.4k
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
6k
私なりのハーネスエンジニアリング ~独自の言語処理系の開発を通して~
seosoft
0
140
Coding with AI: How to trust the storyteller (AWS Community Day Adria, Ljubljana 2026)
slobodan
0
130
graphql-ruby を Spinel で速くしようとした話
mtsmfm
0
130
コーディング自動化の次へ。人の介入をゼロにするファクトリーとサポートAIによる実践
timakin
5
4.9k
現場と育てるRailsモデリング 〜Spreadsheetから始めたモデル設計〜
siroemk
2
1.1k
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
utakaha
3
1.7k
クラウドエージェントは、 何がそんなに便利なのか / what makes cloud agents so useful
rkaga
3
630
Apple Intelligenceとオンデバイス時代の到来
yahir0
0
170
S3 TablesのIcebergデータに、AIエージェントからアクセスしてみた / 20261016developersio2026joetsu-accessing-iceberg-in-s3tables-via-agent
kasacchiful
PRO
0
240
複雑なUIコンポーネントとの ⻑い付き合い⽅:波及するバグからテスト戦略を経て、安全な再設計へ
mixplace
0
490
Featured
See All Featured
SEO for Brand Visibility & Recognition
aleyda
0
4.8k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
950
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
590
Paper Plane (Part 1)
katiecoart
PRO
2
12k
Information Architects: The Missing Link in Design Systems
soysaucechin
1
1.2k
How to Think Like a Performance Engineer
csswizardry
28
2.9k
How to Talk to Developers About Accessibility
jct
2
600
Rails Girls Zürich Keynote
gr2m
96
14k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
730
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Designing for humans not robots
tammielis
254
26k
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 などの重要性が より増すかもしれないと思っています