m12-lifecycle
リソースのライフサイクル設計に役立ち、RAIIやDropといった概念、接続プールの設計、エラー時のクリーンアップなど、リソースの効率的な管理と安全な解放を実現するSkill。
📜 元の英語説明(参考)
Use when designing resource lifecycles. Keywords: RAII, Drop, resource lifecycle, connection pool, lazy initialization, connection pool design, resource cleanup patterns, cleanup, scope, OnceCell, Lazy, once_cell, OnceLock, transaction, session management, when is Drop called, cleanup on error, guard pattern, scope guard, 资源生命周期, 连接池, 惰性初始化, 资源清理, RAII 模式
🇯🇵 日本人クリエイター向け解説
リソースのライフサイクル設計に役立ち、RAIIやDropといった概念、接続プールの設計、エラー時のクリーンアップなど、リソースの効率的な管理と安全な解放を実現するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o m12-lifecycle.zip https://jpskill.com/download/9270.zip && unzip -o m12-lifecycle.zip && rm m12-lifecycle.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/9270.zip -OutFile "$d\m12-lifecycle.zip"; Expand-Archive "$d\m12-lifecycle.zip" -DestinationPath $d -Force; ri "$d\m12-lifecycle.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
m12-lifecycle.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
m12-lifecycleフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
リソースのライフサイクル
レイヤー 2: 設計の選択
中核となる質問
このリソースはいつ作成、使用、およびクリーンアップされるべきか?
ライフサイクルを実装する前に:
- リソースのスコープは?
- 誰がクリーンアップの責任を負うのか?
- エラーが発生した場合はどうなるか?
ライフサイクルパターン → 実装
| パターン | いつ | 実装 |
|---|---|---|
| RAII | 自動クリーンアップ | Drop トレイト |
| 遅延初期化 | 作成の遅延 | OnceLock, LazyLock |
| プール | 高コストなリソースの再利用 | r2d2, deadpool |
| ガード | スコープされたアクセス | MutexGuard パターン |
| スコープ | トランザクション境界 | カスタム構造体 + Drop |
思考を促すプロンプト
ライフサイクルを設計する前に:
-
リソースのコストは?
- 安価 → 使用ごとに作成
- 高価 → プールまたはキャッシュ
- グローバル → 遅延初期化シングルトン
-
スコープは?
- 関数ローカル → スタック割り当て
- リクエストスコープ → 渡されるか抽出される
- アプリケーション全体 → static または Arc
-
エラーについては?
- クリーンアップは必須 → Drop
- クリーンアップはオプション → 明示的な close
- クリーンアップが失敗する可能性あり → close からの Result
トレースアップ ↑
ドメイン制約へ (レイヤー 3):
"データベース接続をどのように管理すべきか?"
↑ 質問: 接続コストは?
↑ 確認: domain-* (レイテンシ要件)
↑ 確認: インフラストラクチャ (接続制限)
| 質問 | トレース先 | 質問 |
|---|---|---|
| 接続プーリング | domain-* | 許容できるレイテンシは? |
| リソース制限 | domain-* | インフラストラクチャの制約は? |
| トランザクションスコープ | domain-* | 何がアトミックである必要があるか? |
トレースダウン ↓
実装へ (レイヤー 1):
"自動クリーンアップが必要"
↓ m02-resource: Drop を実装
↓ m01-ownership: クリーンアップのためにオーナーをクリア
"遅延初期化が必要"
↓ m03-mutability: スレッドセーフのために OnceLock
↓ m07-concurrency: 同期のために LazyLock
"接続プールが必要"
↓ m07-concurrency: スレッドセーフなプール
↓ m02-resource: 共有のために Arc
クイックリファレンス
| パターン | 型 | ユースケース |
|---|---|---|
| RAII | Drop トレイト |
スコープ終了時の自動クリーンアップ |
| 遅延初期化 | OnceLock, LazyLock |
遅延初期化 |
| プール | r2d2, deadpool |
接続の再利用 |
| ガード | MutexGuard |
スコープされたロックの解放 |
| スコープ | カスタム構造体 | トランザクション境界 |
ライフサイクルイベント
| イベント | Rust のメカニズム |
|---|---|
| 作成 | new(), Default |
| 遅延初期化 | OnceLock::get_or_init |
| 使用 | &self, &mut self |
| クリーンアップ | Drop::drop() |
パターンテンプレート
RAII ガード
struct FileGuard {
path: PathBuf,
_handle: File,
}
impl Drop for FileGuard {
fn drop(&mut self) {
// クリーンアップ: 一時ファイルを削除
let _ = std::fs::remove_file(&self.path);
}
}
遅延初期化シングルトン
use std::sync::OnceLock;
static CONFIG: OnceLock<Config> = OnceLock::new();
fn get_config() -> &'static Config {
CONFIG.get_or_init(|| {
Config::load().expect("config required")
})
}
よくあるエラー
| エラー | 原因 | 修正 |
|---|---|---|
| リソースリーク | Drop を忘れた | Drop または RAII ラッパーを実装 |
| 二重解放 | 手動メモリ | Rust に処理させる |
| Drop 後の使用 | ダングリング参照 | ライフタイムを確認 |
| E0509 move out of Drop | 所有権のあるフィールドの移動 | Option::take() |
| プールの枯渇 | 返却されていない | Drop が返却されるようにする |
アンチパターン
| アンチパターン | なぜ悪いか | より良い方法 |
|---|---|---|
| 手動クリーンアップ | 忘れやすい | RAII/Drop |
lazy_static! |
外部依存 | std::sync::OnceLock |
| グローバルな可変状態 | スレッド安全性がない | OnceLock または適切な同期 |
| close し忘れる | リソースリーク | Drop の実装 |
関連スキル
| いつ | 参照 |
|---|---|
| スマートポインタ | m02-resource |
| スレッドセーフな初期化 | m07-concurrency |
| ドメインスコープ | m09-domain |
| クリーンアップ時のエラー | m06-error-handling |
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Resource Lifecycle
Layer 2: Design Choices
Core Question
When should this resource be created, used, and cleaned up?
Before implementing lifecycle:
- What's the resource's scope?
- Who owns the cleanup responsibility?
- What happens on error?
Lifecycle Pattern → Implementation
| Pattern | When | Implementation |
|---|---|---|
| RAII | Auto cleanup | Drop trait |
| Lazy init | Deferred creation | OnceLock, LazyLock |
| Pool | Reuse expensive resources | r2d2, deadpool |
| Guard | Scoped access | MutexGuard pattern |
| Scope | Transaction boundary | Custom struct + Drop |
Thinking Prompt
Before designing lifecycle:
-
What's the resource cost?
- Cheap → create per use
- Expensive → pool or cache
- Global → lazy singleton
-
What's the scope?
- Function-local → stack allocation
- Request-scoped → passed or extracted
- Application-wide → static or Arc
-
What about errors?
- Cleanup must happen → Drop
- Cleanup is optional → explicit close
- Cleanup can fail → Result from close
Trace Up ↑
To domain constraints (Layer 3):
"How should I manage database connections?"
↑ Ask: What's the connection cost?
↑ Check: domain-* (latency requirements)
↑ Check: Infrastructure (connection limits)
| Question | Trace To | Ask |
|---|---|---|
| Connection pooling | domain-* | What's acceptable latency? |
| Resource limits | domain-* | What are infra constraints? |
| Transaction scope | domain-* | What must be atomic? |
Trace Down ↓
To implementation (Layer 1):
"Need automatic cleanup"
↓ m02-resource: Implement Drop
↓ m01-ownership: Clear owner for cleanup
"Need lazy initialization"
↓ m03-mutability: OnceLock for thread-safe
↓ m07-concurrency: LazyLock for sync
"Need connection pool"
↓ m07-concurrency: Thread-safe pool
↓ m02-resource: Arc for sharing
Quick Reference
| Pattern | Type | Use Case |
|---|---|---|
| RAII | Drop trait |
Auto cleanup on scope exit |
| Lazy Init | OnceLock, LazyLock |
Deferred initialization |
| Pool | r2d2, deadpool |
Connection reuse |
| Guard | MutexGuard |
Scoped lock release |
| Scope | Custom struct | Transaction boundaries |
Lifecycle Events
| Event | Rust Mechanism |
|---|---|
| Creation | new(), Default |
| Lazy Init | OnceLock::get_or_init |
| Usage | &self, &mut self |
| Cleanup | Drop::drop() |
Pattern Templates
RAII Guard
struct FileGuard {
path: PathBuf,
_handle: File,
}
impl Drop for FileGuard {
fn drop(&mut self) {
// Cleanup: remove temp file
let _ = std::fs::remove_file(&self.path);
}
}
Lazy Singleton
use std::sync::OnceLock;
static CONFIG: OnceLock<Config> = OnceLock::new();
fn get_config() -> &'static Config {
CONFIG.get_or_init(|| {
Config::load().expect("config required")
})
}
Common Errors
| Error | Cause | Fix |
|---|---|---|
| Resource leak | Forgot Drop | Implement Drop or RAII wrapper |
| Double free | Manual memory | Let Rust handle |
| Use after drop | Dangling reference | Check lifetimes |
| E0509 move out of Drop | Moving owned field | Option::take() |
| Pool exhaustion | Not returned | Ensure Drop returns |
Anti-Patterns
| Anti-Pattern | Why Bad | Better |
|---|---|---|
| Manual cleanup | Easy to forget | RAII/Drop |
lazy_static! |
External dep | std::sync::OnceLock |
| Global mutable state | Thread unsafety | OnceLock or proper sync |
| Forget to close | Resource leak | Drop impl |
Related Skills
| When | See |
|---|---|
| Smart pointers | m02-resource |
| Thread-safe init | m07-concurrency |
| Domain scopes | m09-domain |
| Error in cleanup | m06-error-handling |