Skip to content

Add Telemetry support#30

Merged
renatomassaro merged 2 commits intomainfrom
add-telemetry
Dec 21, 2025
Merged

Add Telemetry support#30
renatomassaro merged 2 commits intomainfrom
add-telemetry

Conversation

@renatomassaro
Copy link
Copy Markdown
Owner

@renatomassaro renatomassaro commented Nov 17, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Telemetry added to low-level DB driver and query/transaction paths for richer performance metrics.
  • Refactor

    • Replaced internal orchestration with a unified Repo-backed API and tightened logging metadata per operation.
    • Supervisor/startup responsibilities moved to an explicit supervisor module.
  • Chores

    • Added telemetry dependency and updated tests/startup to use the new APIs.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Nov 17, 2025

Walkthrough

Refactors Feeb.DB to expose a Repo-backed public API, replaces GenServer orchestration with Repo.* calls, introduces telemetry for driver and query operations, adds structured logger metadata handling, replaces Application module with a Supervisor, updates connection manager/entry, and updates tests to use the new API.

Changes

Cohort / File(s) Summary
API Layer & Callsite Migration
lib/feeb/db.ex
Replaces GenServer.call-based transaction and query orchestration with calls to Feeb.DB.Repo (begin/commit/rollback, raw, one, all, insert, update, delete, update_all, delete_all); removes prepared_raw.
Public Repo API & Instrumentation
lib/feeb/db/repo.ex
Adds public API wrappers (begin/commit/rollback, one, all, insert, update, update_all, delete, delete_all, raw) and internal run_query/with_telemetry; implements telemetry emission and scoped Logger.metadata management around operations.
Supervisor / Startup
lib/feeb/db/application.ex, lib/feeb/db/supervisor.ex, test/test_helper.exs
Removes Feeb.DB.Application and Application start callback; adds Feeb.DB.Supervisor module with start_link/1 and init/1; test helper now starts Feeb.DB.Supervisor.
Repo Manager & Entry
lib/feeb/db/repo/manager.ex, lib/feeb/db/repo/manager/repo_entry.ex, test/db/repo/manager_test.exs
Manager: sets Logger.metadata(context:, shard_id:) on init and reorders demonitor after timer stop. RepoEntry: adds time field, set on acquire. Tests updated to call Repo.begin/1.
SQLite Driver Instrumentation
lib/feeb/db/sqlite.ex
Wraps driver operations (open, close, exec, prepare, bind, multi_step) with traced_driver_operation/2 to time calls and emit telemetry [:feebdb, :driver_op, ...].
Mix / Dependencies
mix.exs
Removes mod: {Feeb.DB.Application, []} from application config; adds :telemetry (~> 1.3) dependency.
Tests - Repo Interaction Updates
test/db/repo_test.exs
Replaces GenServer-based test calls with Feeb.DB.Repo public API calls (begin/commit/one/raw/...); updated aliases and call-sites to match new API.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Feeb.DB
  participant Repo
  participant RepoManager
  participant Driver

  Client->>Feeb.DB: invoke query/transaction (was GenServer.call)
  Feeb.DB->>Repo: Repo.begin(txn_type) / Repo.one/all/insert/...
  Repo->>RepoManager: acquire or use repo PID (with metadata)
  RepoManager->>Driver: open/exec/prepare/multi_step (via traced_driver_operation)
  Driver-->>RepoManager: result (with timing)
  RepoManager-->>Repo: repo operation result
  Repo-->>Feeb.DB: formatted result / error
  Feeb.DB-->>Client: return result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay special attention to:
    • New public Repo methods and consistent error/return semantics across all wrappers.
    • Telemetry event shapes and attributes emitted from with_telemetry and traced_driver_operation.
    • Logger.metadata scope management to ensure no metadata leakage across concurrent requests.
    • Supervisor replacement for Application and test startup ordering.

Possibly related PRs

Poem

🐰 I hop from GenServer tunnels to Repo's sunlit glade,
Telemetry hums where quiet queries played,
Metadata tucked in each little paw,
Timers ticking softly, driver traces saw,
A rabbit cheers the warren's tidy trade.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.77% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add Telemetry support' accurately reflects the main objective of this pull request, which integrates telemetry instrumentation throughout the codebase for query execution and driver operations.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add-telemetry

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@renatomassaro renatomassaro marked this pull request as ready for review December 21, 2025 23:08
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
test/test_helper.exs (1)

1-2: Consider adding error handling for supervisor startup.

The supervisor is now manually started, but there's no error handling if start_link fails. Consider using pattern matching to make test failures more explicit:

🔎 Proposed improvement
-Feeb.DB.Supervisor.start_link([])
-
+{:ok, _pid} = Feeb.DB.Supervisor.start_link([])
+
lib/feeb/db/sqlite.ex (1)

92-92: Minor: Remove unnecessary blank line.

The blank line before the function definition is unnecessary.

🔎 Proposed cleanup
-
 defp traced_driver_operation(operation, args) do
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1c563f0 and 557976c.

📒 Files selected for processing (10)
  • lib/feeb/db.ex (12 hunks)
  • lib/feeb/db/application.ex (1 hunks)
  • lib/feeb/db/repo.ex (6 hunks)
  • lib/feeb/db/repo/manager.ex (2 hunks)
  • lib/feeb/db/repo/manager/repo_entry.ex (2 hunks)
  • lib/feeb/db/sqlite.ex (3 hunks)
  • mix.exs (2 hunks)
  • test/db/repo/manager_test.exs (2 hunks)
  • test/db/repo_test.exs (7 hunks)
  • test/test_helper.exs (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo.ex:142-153
Timestamp: 2024-11-28T09:59:48.623Z
Learning: In the `Feeb.DB.Repo` module, the GenServer processes messages sequentially, so there is no race condition within `handle_call/3` functions, and `state` mutations are safe from concurrent modifications.
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 22
File: priv/test/queries/test/posts.sql:4-5
Timestamp: 2025-04-26T13:15:03.540Z
Learning: Feeb.DB requires all database statements to be executed within user-initiated transactions, making additional explicit transaction wrapping unnecessary. The "delete_all" and similar operations are executed as single SQL statements which are inherently atomic even when they affect multiple rows, maintaining ACID guarantees without requiring additional transaction control.
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo/manager.ex:137-154
Timestamp: 2024-11-28T10:03:22.695Z
Learning: In the `Feeb.DB.Repo.Manager` module (`lib/feeb/db/repo/manager.ex`), it's acceptable to terminate caller processes using `Process.exit(caller_pid, :feebdb_repo_timeout)` in the `handle_info/2` callback when a repository timeout occurs, as the timeout is a contract and the process should die if it exceeds it.
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo.ex:144-145
Timestamp: 2024-11-28T10:01:57.103Z
Learning: In `lib/feeb/db/repo.ex`, when working with Erlang/Elixir code, it's idiomatic to use the same parameter name in function pattern matching to assert that parameters are equal. For example, defining `defp assert_release_signal_from_manager!(manager_pid, manager_pid), do: :ok` is acceptable and preferred.
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 16
File: lib/feeb/db/schema.ex:393-401
Timestamp: 2024-12-17T00:35:18.307Z
Learning: In `Feeb.DB.Schema`, prefer to let the system crash if the schema implementation is wrong, rather than handling exceptions in `trigger_after_read_callbacks/2`, to avoid passing around potentially incorrect or invalid data.
📚 Learning: 2024-11-28T10:01:57.103Z
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo.ex:144-145
Timestamp: 2024-11-28T10:01:57.103Z
Learning: In `lib/feeb/db/repo.ex`, when working with Erlang/Elixir code, it's idiomatic to use the same parameter name in function pattern matching to assert that parameters are equal. For example, defining `defp assert_release_signal_from_manager!(manager_pid, manager_pid), do: :ok` is acceptable and preferred.

Applied to files:

  • test/db/repo/manager_test.exs
  • test/db/repo_test.exs
  • lib/feeb/db.ex
  • lib/feeb/db/repo/manager/repo_entry.ex
  • lib/feeb/db/repo/manager.ex
  • lib/feeb/db/application.ex
  • lib/feeb/db/repo.ex
📚 Learning: 2024-11-28T10:03:22.695Z
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo/manager.ex:137-154
Timestamp: 2024-11-28T10:03:22.695Z
Learning: In the `Feeb.DB.Repo.Manager` module (`lib/feeb/db/repo/manager.ex`), it's acceptable to terminate caller processes using `Process.exit(caller_pid, :feebdb_repo_timeout)` in the `handle_info/2` callback when a repository timeout occurs, as the timeout is a contract and the process should die if it exceeds it.

Applied to files:

  • test/db/repo/manager_test.exs
  • test/db/repo_test.exs
  • lib/feeb/db.ex
  • lib/feeb/db/repo/manager/repo_entry.ex
  • lib/feeb/db/repo/manager.ex
  • lib/feeb/db/application.ex
  • lib/feeb/db/repo.ex
📚 Learning: 2024-11-28T09:59:48.623Z
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo.ex:142-153
Timestamp: 2024-11-28T09:59:48.623Z
Learning: In the `Feeb.DB.Repo` module, the GenServer processes messages sequentially, so there is no race condition within `handle_call/3` functions, and `state` mutations are safe from concurrent modifications.

Applied to files:

  • test/db/repo/manager_test.exs
  • test/db/repo_test.exs
  • lib/feeb/db.ex
  • lib/feeb/db/repo/manager/repo_entry.ex
  • lib/feeb/db/application.ex
  • lib/feeb/db/repo.ex
📚 Learning: 2024-11-28T10:08:23.649Z
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo/manager.ex:249-250
Timestamp: 2024-11-28T10:08:23.649Z
Learning: In `lib/feeb/db/repo/manager.ex`, within the `do_release_connection/2` function, the line `:ok = Repo.notify_release(pid)` is intentionally designed to match `:ok`, ensuring that if `Repo.notify_release/1` fails, a `MatchError` is raised to trigger a crash and restart of the system. This is by design to handle critical errors, and handling potential errors from `Repo.notify_release/1` is not desired.

Applied to files:

  • test/db/repo/manager_test.exs
  • test/db/repo_test.exs
  • lib/feeb/db.ex
  • lib/feeb/db/repo/manager/repo_entry.ex
  • lib/feeb/db/repo/manager.ex
  • lib/feeb/db/repo.ex
📚 Learning: 2025-04-26T13:15:03.540Z
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 22
File: priv/test/queries/test/posts.sql:4-5
Timestamp: 2025-04-26T13:15:03.540Z
Learning: Feeb.DB requires all database statements to be executed within user-initiated transactions, making additional explicit transaction wrapping unnecessary. The "delete_all" and similar operations are executed as single SQL statements which are inherently atomic even when they affect multiple rows, maintaining ACID guarantees without requiring additional transaction control.

Applied to files:

  • test/db/repo_test.exs
  • lib/feeb/db.ex
  • lib/feeb/db/repo.ex
  • lib/feeb/db/sqlite.ex
📚 Learning: 2024-12-17T00:35:18.307Z
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 16
File: lib/feeb/db/schema.ex:393-401
Timestamp: 2024-12-17T00:35:18.307Z
Learning: In `Feeb.DB.Schema`, prefer to let the system crash if the schema implementation is wrong, rather than handling exceptions in `trigger_after_read_callbacks/2`, to avoid passing around potentially incorrect or invalid data.

Applied to files:

  • lib/feeb/db.ex
  • test/test_helper.exs
  • lib/feeb/db/repo.ex
🧬 Code graph analysis (5)
test/db/repo/manager_test.exs (2)
lib/feeb/db.ex (1)
  • begin (24-32)
lib/feeb/db/repo.ex (1)
  • begin (25-33)
lib/feeb/db.ex (1)
lib/feeb/db/repo.ex (4)
  • begin (25-33)
  • commit (35-37)
  • rollback (39-43)
  • raw (66-72)
test/test_helper.exs (4)
lib/feeb/db/application.ex (1)
  • start_link (7-9)
lib/feeb/db/repo/manager.ex (1)
  • start_link (64-66)
lib/feeb/db/repo/manager/supervisor.ex (1)
  • start_link (10-12)
lib/feeb/db/repo/manager/registry.ex (1)
  • start_link (60-62)
lib/feeb/db/application.ex (3)
lib/feeb/db/repo/manager/supervisor.ex (2)
  • start_link (10-12)
  • init (18-20)
lib/feeb/db/repo/manager/registry.ex (2)
  • start_link (60-62)
  • init (64-67)
lib/feeb/db/repo.ex (1)
  • init (125-160)
lib/feeb/db/repo.ex (1)
lib/feeb/db.ex (1)
  • begin (24-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: linters
🔇 Additional comments (19)
mix.exs (2)

59-59: LGTM! Telemetry dependency added.

The telemetry dependency supports the instrumentation added throughout the codebase for observability.


33-33: The mod: [] configuration is correct for a library design. FeebDB is a library (not a standalone application), and libraries should not auto-start supervisors. Consuming applications are responsible for manually starting Feeb.DB.Supervisor.start_link([]) in their own supervision tree, as demonstrated in the test setup.

lib/feeb/db/repo/manager/repo_entry.ex (1)

3-3: LGTM! Time tracking added for observability.

The addition of the time field to track acquisition timestamps supports telemetry and monitoring of repo lease durations. The implementation correctly captures the system time at acquisition.

Also applies to: 23-23

lib/feeb/db/repo/manager.ex (2)

84-86: LGTM! Logger metadata enhancement.

Setting logger metadata with context and shard_id in init/1 improves log traceability for this manager process. The subsequent log message will now include this context.


254-256: LGTM! Cleanup ordering clarified.

The demonitor operation now follows timer cancellation, making the cleanup sequence more explicit. Both operations are independent, so the reordering doesn't affect correctness.

test/db/repo/manager_test.exs (2)

4-4: LGTM! Alias updated for new API.

Adding Repo to the alias list supports the migration to the Repo-backed public API.


334-334: LGTM! Migration to Repo public API.

The test now uses Repo.begin/2 instead of directly calling the GenServer, aligning with the new Repo-backed transaction API introduced in this PR.

test/db/repo_test.exs (1)

89-89: LGTM! Comprehensive migration to Repo public API.

All test interactions have been successfully migrated from GenServer-based calls to the new Repo public API (Repo.begin, Repo.commit, Repo.one, Repo.raw, Repo.close, Repo.notify_release). The changes are consistent throughout and align with the PR's architectural shift to Repo-backed operations.

Also applies to: 93-93, 103-103, 105-105, 115-115, 117-119, 127-127, 129-129, 135-135, 138-138, 145-145, 149-152, 160-160, 170-170, 177-177, 183-183, 190-190, 193-193, 201-202, 205-206, 209-209, 218-219, 223-224, 236-237, 240-240

lib/feeb/db/sqlite.ex (1)

16-16: LGTM! Driver operations now instrumented.

All SQLite driver operations are now routed through traced_driver_operation for telemetry instrumentation, enabling observability of driver performance.

Also applies to: 18-18, 20-20, 38-38, 46-46, 86-86

lib/feeb/db/application.ex (1)

1-19: Architectural shift to manual supervisor startup looks correct.

The module has been successfully converted from an OTP Application to a Supervisor, allowing manual startup instead of automatic application lifecycle management. The implementation follows standard Supervisor patterns with start_link/1 and init/1 callbacks.

lib/feeb/db.ex (4)

31-31: LGTM! Transaction operations properly delegated to Repo module.

The refactoring from direct GenServer calls to Repo-backed operations is clean and maintains the same semantics while adding telemetry instrumentation at the Repo layer.

Also applies to: 61-61, 72-72


82-82: LGTM! Query operations properly delegated to Repo module.

The consistent refactoring pattern for read operations (raw, one, all) maintains the existing API contract while centralizing telemetry and logging at the Repo layer.

Also applies to: 111-111, 142-142


165-165: LGTM! Mutation operations properly delegated to Repo module.

All write operations (insert, update, update_all, delete, delete_all) now consistently delegate to the Repo module, completing the refactoring pattern across all database operations.

Also applies to: 187-187, 197-197, 221-221, 231-231


270-270: TODO comment noted for shard-aware telemetry.

The placeholder is reasonable for future enhancement. Shard-level telemetry metrics could be valuable for monitoring and debugging multi-shard deployments.

lib/feeb/db/repo.ex (5)

25-43: LGTM! Transaction API with telemetry instrumentation.

The public API functions for begin, commit, and rollback properly wrap GenServer calls with telemetry and propagate logger metadata from the caller context. The with_telemetry helper ensures consistent instrumentation across all transaction operations.


45-72: LGTM! Well-designed telemetry instrumentation.

The query execution pathway is well-structured:

  • Public API functions consistently delegate to run_query helper
  • with_telemetry properly implements start/stop/exception event pattern with duration tracking
  • Exception handling correctly preserves stacktraces using :erlang.raise/3
  • Logger metadata is propagated from caller context to GenServer handlers

The telemetry events include rich metadata (query_type, domain, query_name) that will be valuable for observability.

Also applies to: 84-121


126-126: LGTM! Process-level logger metadata initialization.

Setting structured logger metadata during initialization ensures all subsequent log entries from this repo process include essential context (context, shard_id, path, mode), which significantly improves observability and log filtering capabilities.


258-362: LGTM! Proper logger metadata scope management in GenServer handlers.

All transaction and query handlers correctly:

  • Accept log_meta parameter from callers
  • Manage metadata scope with start/end helpers
  • Clean up metadata on both success and error paths
  • Include appropriate debug and error logging

The scope management ensures caller-specific metadata is active during operations without polluting the process-level metadata.


521-530: LGTM! Clean logger metadata scope helpers.

The metadata scope management implementation is straightforward and correct:

  • Uses namespaced process dictionary key to avoid conflicts
  • Properly saves/restores metadata using Logger.reset_metadata
  • Simple design that handles the scope lifecycle cleanly

@@ -1,17 +1,20 @@
defmodule Feeb.DB.Application do
defmodule Feeb.DB.Supervisor do
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check for supervisor and application files in lib/feeb/db/
fd -e ex lib/feeb/db/ | sort

Repository: renatomassaro/FeebDB

Length of output: 417


🏁 Script executed:

# List all .ex files in lib/feeb/db/ directory
fd . lib/feeb/db/ -e ex

Repository: renatomassaro/FeebDB

Length of output: 1064


🏁 Script executed:

# Read the application.ex file to check the module name
cat -n lib/feeb/db/application.ex | head -20

Repository: renatomassaro/FeebDB

Length of output: 592


Rename file to match module name: application.exsupervisor.ex

The module Feeb.DB.Supervisor is defined in lib/feeb/db/application.ex, violating Elixir conventions where module names must match file paths. Rename the file to lib/feeb/db/supervisor.ex.

🤖 Prompt for AI Agents
In lib/feeb/db/application.ex around line 1, the file defines module
Feeb.DB.Supervisor but its filename doesn't match the module name; rename
lib/feeb/db/application.ex to lib/feeb/db/supervisor.ex and update any
references or imports that point to the old file path (ensure the module remains
defmodule Feeb.DB.Supervisor do and update project refs, mix/compile if
necessary) so Elixir module/file conventions are satisfied.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/feeb/db.ex (1)

141-146: Ensure reason from Repo.all is a valid argument for raise/1.

The code calls raise reason on errors from Repo.all, but Exqlite (the underlying SQLite driver) may return atoms or other error terms that are not valid for raise/1. The SQLite module even has a TODO comment noting uncertainty about error types. Wrap the error appropriately before raising—either ensure it's a string/exception struct or use raise RuntimeError, message: inspect(reason) to handle arbitrary error terms.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 557976c and 5545307.

📒 Files selected for processing (11)
  • lib/feeb/db.ex (12 hunks)
  • lib/feeb/db/application.ex (0 hunks)
  • lib/feeb/db/repo.ex (6 hunks)
  • lib/feeb/db/repo/manager.ex (2 hunks)
  • lib/feeb/db/repo/manager/repo_entry.ex (2 hunks)
  • lib/feeb/db/sqlite.ex (3 hunks)
  • lib/feeb/db/supervisor.ex (1 hunks)
  • mix.exs (2 hunks)
  • test/db/repo/manager_test.exs (2 hunks)
  • test/db/repo_test.exs (7 hunks)
  • test/test_helper.exs (1 hunks)
💤 Files with no reviewable changes (1)
  • lib/feeb/db/application.ex
🚧 Files skipped from review as they are similar to previous changes (4)
  • lib/feeb/db/sqlite.ex
  • lib/feeb/db/repo/manager/repo_entry.ex
  • lib/feeb/db/repo/manager.ex
  • test/db/repo/manager_test.exs
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo.ex:142-153
Timestamp: 2024-11-28T09:59:48.623Z
Learning: In the `Feeb.DB.Repo` module, the GenServer processes messages sequentially, so there is no race condition within `handle_call/3` functions, and `state` mutations are safe from concurrent modifications.
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo.ex:144-145
Timestamp: 2024-11-28T10:01:57.103Z
Learning: In `lib/feeb/db/repo.ex`, when working with Erlang/Elixir code, it's idiomatic to use the same parameter name in function pattern matching to assert that parameters are equal. For example, defining `defp assert_release_signal_from_manager!(manager_pid, manager_pid), do: :ok` is acceptable and preferred.
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo/manager.ex:137-154
Timestamp: 2024-11-28T10:03:22.695Z
Learning: In the `Feeb.DB.Repo.Manager` module (`lib/feeb/db/repo/manager.ex`), it's acceptable to terminate caller processes using `Process.exit(caller_pid, :feebdb_repo_timeout)` in the `handle_info/2` callback when a repository timeout occurs, as the timeout is a contract and the process should die if it exceeds it.
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 22
File: priv/test/queries/test/posts.sql:4-5
Timestamp: 2025-04-26T13:15:03.540Z
Learning: Feeb.DB requires all database statements to be executed within user-initiated transactions, making additional explicit transaction wrapping unnecessary. The "delete_all" and similar operations are executed as single SQL statements which are inherently atomic even when they affect multiple rows, maintaining ACID guarantees without requiring additional transaction control.
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 16
File: lib/feeb/db/schema.ex:393-401
Timestamp: 2024-12-17T00:35:18.307Z
Learning: In `Feeb.DB.Schema`, prefer to let the system crash if the schema implementation is wrong, rather than handling exceptions in `trigger_after_read_callbacks/2`, to avoid passing around potentially incorrect or invalid data.
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo/manager.ex:249-250
Timestamp: 2024-11-28T10:08:23.649Z
Learning: In `lib/feeb/db/repo/manager.ex`, within the `do_release_connection/2` function, the line `:ok = Repo.notify_release(pid)` is intentionally designed to match `:ok`, ensuring that if `Repo.notify_release/1` fails, a `MatchError` is raised to trigger a crash and restart of the system. This is by design to handle critical errors, and handling potential errors from `Repo.notify_release/1` is not desired.
📚 Learning: 2024-11-28T10:01:57.103Z
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo.ex:144-145
Timestamp: 2024-11-28T10:01:57.103Z
Learning: In `lib/feeb/db/repo.ex`, when working with Erlang/Elixir code, it's idiomatic to use the same parameter name in function pattern matching to assert that parameters are equal. For example, defining `defp assert_release_signal_from_manager!(manager_pid, manager_pid), do: :ok` is acceptable and preferred.

Applied to files:

  • lib/feeb/db/supervisor.ex
  • lib/feeb/db.ex
  • lib/feeb/db/repo.ex
  • test/db/repo_test.exs
📚 Learning: 2024-11-28T10:03:22.695Z
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo/manager.ex:137-154
Timestamp: 2024-11-28T10:03:22.695Z
Learning: In the `Feeb.DB.Repo.Manager` module (`lib/feeb/db/repo/manager.ex`), it's acceptable to terminate caller processes using `Process.exit(caller_pid, :feebdb_repo_timeout)` in the `handle_info/2` callback when a repository timeout occurs, as the timeout is a contract and the process should die if it exceeds it.

Applied to files:

  • lib/feeb/db/supervisor.ex
  • lib/feeb/db.ex
  • lib/feeb/db/repo.ex
  • test/db/repo_test.exs
📚 Learning: 2024-11-28T09:59:48.623Z
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo.ex:142-153
Timestamp: 2024-11-28T09:59:48.623Z
Learning: In the `Feeb.DB.Repo` module, the GenServer processes messages sequentially, so there is no race condition within `handle_call/3` functions, and `state` mutations are safe from concurrent modifications.

Applied to files:

  • lib/feeb/db/supervisor.ex
  • lib/feeb/db.ex
  • lib/feeb/db/repo.ex
  • test/db/repo_test.exs
📚 Learning: 2024-11-28T10:08:23.649Z
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 15
File: lib/feeb/db/repo/manager.ex:249-250
Timestamp: 2024-11-28T10:08:23.649Z
Learning: In `lib/feeb/db/repo/manager.ex`, within the `do_release_connection/2` function, the line `:ok = Repo.notify_release(pid)` is intentionally designed to match `:ok`, ensuring that if `Repo.notify_release/1` fails, a `MatchError` is raised to trigger a crash and restart of the system. This is by design to handle critical errors, and handling potential errors from `Repo.notify_release/1` is not desired.

Applied to files:

  • lib/feeb/db/supervisor.ex
  • lib/feeb/db.ex
  • lib/feeb/db/repo.ex
  • test/db/repo_test.exs
📚 Learning: 2025-04-26T13:15:03.540Z
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 22
File: priv/test/queries/test/posts.sql:4-5
Timestamp: 2025-04-26T13:15:03.540Z
Learning: Feeb.DB requires all database statements to be executed within user-initiated transactions, making additional explicit transaction wrapping unnecessary. The "delete_all" and similar operations are executed as single SQL statements which are inherently atomic even when they affect multiple rows, maintaining ACID guarantees without requiring additional transaction control.

Applied to files:

  • lib/feeb/db.ex
  • lib/feeb/db/repo.ex
  • test/db/repo_test.exs
📚 Learning: 2024-12-17T00:35:18.307Z
Learnt from: renatomassaro
Repo: renatomassaro/FeebDB PR: 16
File: lib/feeb/db/schema.ex:393-401
Timestamp: 2024-12-17T00:35:18.307Z
Learning: In `Feeb.DB.Schema`, prefer to let the system crash if the schema implementation is wrong, rather than handling exceptions in `trigger_after_read_callbacks/2`, to avoid passing around potentially incorrect or invalid data.

Applied to files:

  • lib/feeb/db.ex
  • test/test_helper.exs
  • lib/feeb/db/repo.ex
🧬 Code graph analysis (5)
lib/feeb/db/supervisor.ex (2)
lib/feeb/db/repo/manager.ex (2)
  • start_link (64-66)
  • init (83-99)
lib/feeb/db/repo.ex (1)
  • init (125-160)
lib/feeb/db.ex (1)
lib/feeb/db/repo.ex (4)
  • begin (25-33)
  • commit (35-37)
  • rollback (39-43)
  • raw (66-72)
test/test_helper.exs (4)
lib/feeb/db/repo/manager.ex (1)
  • start_link (64-66)
lib/feeb/db/supervisor.ex (1)
  • start_link (7-9)
lib/feeb/db/repo/manager/supervisor.ex (1)
  • start_link (10-12)
lib/feeb/db/repo/manager/registry.ex (1)
  • start_link (60-62)
lib/feeb/db/repo.ex (1)
lib/feeb/db.ex (1)
  • begin (24-32)
test/db/repo_test.exs (2)
lib/feeb/db.ex (2)
  • begin (24-32)
  • raw (81-83)
lib/feeb/db/repo.ex (3)
  • begin (25-33)
  • commit (35-37)
  • raw (66-72)
🔇 Additional comments (19)
mix.exs (2)

30-35: Application module removed — verify production startup path.

Setting mod: [] disables automatic supervision tree startup. This is fine for library usage where consumers start Feeb.DB.Supervisor manually, but verify this is the intended behavior for production deployments.


59-59: Telemetry dependency looks good.

The {:telemetry, "~> 1.3"} dependency aligns with the PR objective to add telemetry support.

test/test_helper.exs (1)

1-2: LGTM!

Correctly starts Feeb.DB.Supervisor before test initialization, aligning with the removal of the automatic application startup module.

test/db/repo_test.exs (6)

84-99: LGTM!

The transaction lifecycle tests correctly use the new Repo.begin/2 and Repo.commit/1 API, maintaining the same test coverage for transaction state management.


101-121: LGTM!

Error handling tests for double-begin and commit-without-transaction scenarios properly exercise the new Repo API error paths.


123-140: LGTM!

Query tests (Repo.one) correctly verify both successful lookups and error conditions (multiple results, wrong bindings).


142-166: LGTM!

Raw query tests properly exercise Repo.raw/3 for reads, writes with bindings, and implicit transaction warnings.


168-196: LGTM!

Connection close tests verify both happy path and the guard against closing during an active transaction.


198-249: No action needed. The block_forever/0 function is properly defined in test/support/utils.ex and is accessible in this test file through the Test.Feeb.DBCase module, which imports Test.Utils.

lib/feeb/db/supervisor.ex (1)

1-19: LGTM!

The supervisor structure is well-organized with appropriate one_for_one strategy. The boot task runs as a temporary child, which is suitable for one-shot initialization.

lib/feeb/db.ex (5)

31-31: LGTM!

Clean migration from GenServer call to Repo.begin/2 API with telemetry support.


60-64: LGTM!

Repo.commit/1 usage is correct, and delete_env/0 properly releases the connection after commit.


71-75: LGTM!

Rollback follows the same pattern as commit, correctly cleaning up environment state.


81-88: LGTM!

Raw query functions properly delegate to Repo.raw/3.


269-275: LGTM!

The setup logic correctly fetches or creates a manager and obtains a repo connection. The TODO comment appropriately flags future telemetry work.

lib/feeb/db/repo.ex (4)

97-121: LGTM! Solid telemetry implementation.

The with_telemetry/3 implementation correctly:

  • Measures duration using monotonic time
  • Emits start/stop/exception events following telemetry conventions
  • Preserves stacktraces using :erlang.raise
  • Includes comprehensive metadata for exception events

523-530: Logger metadata scope management is sound.

The implementation correctly saves and restores Logger metadata using the process dictionary. The scope helpers are used consistently in handle_call functions with cleanup on both success and error paths.

Note: If an exception (not {:error, ...}) occurs between start_custom_log_metadata_scope and end_custom_log_metadata_scope, metadata won't be restored. However, this would cause a GenServer crash, resetting process state anyway. Based on learnings showing this codebase prefers crashes over defensive handling, the current approach is acceptable.


258-326: Logger metadata handling is well-designed.

The handle_call modifications show consistent patterns:

  • Operations that execute database commands use start_custom_log_metadata_scope to ensure all logs within the operation have caller context
  • Error-only paths efficiently pass log_meta directly to Logger functions
  • All scope cleanup happens before replying

The implementation correctly balances efficiency with proper metadata propagation.


126-126: Good addition of structured logging context.

Setting Logger metadata during initialization ensures all logs from this Repo process include the context, shard_id, path, and mode. This facilitates debugging and log analysis.

@renatomassaro renatomassaro merged commit 0d0d604 into main Dec 21, 2025
3 checks passed
@renatomassaro renatomassaro deleted the add-telemetry branch December 21, 2025 23:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant