Skip to content

feat(log-ingestor): Make database connection pool size configurable (fixes #2039). - #2413

Open
junhaoliao wants to merge 12 commits into
y-scope:mainfrom
junhaoliao:feat/log-ingestor-database-connection-pool-size
Open

feat(log-ingestor): Make database connection pool size configurable (fixes #2039).#2413
junhaoliao wants to merge 12 commits into
y-scope:mainfrom
junhaoliao:feat/log-ingestor-database-connection-pool-size

Conversation

@junhaoliao

@junhaoliao junhaoliao commented Jul 22, 2026

Copy link
Copy Markdown
Member

Description

Fixes #2039.

The log-ingestor previously constructed its MySQL connection pool with a hardcoded maximum of 100 connections. This PR adds log_ingestor.database_connection_pool_size so operators can tune that limit while preserving 100 as the default, and passes the configured value to the pool constructor:

let database_connection_pool_size = clp_config
.log_ingestor
.as_ref()
.context("Invalid CLP config: log-ingestor is not configured")?
.database_connection_pool_size
.get();
let mysql_pool = clp_rust_utils::database::mysql::create_clp_db_mysql_pool(
&clp_config.database,
&clp_credentials.database,
database_connection_pool_size,
)
.await?;
.

The Python configuration model validates the setting as a positive value that fits in a Rust u32, while the Rust mirror uses NonZeroU32 to reject zero during deserialization. The configured value is passed to create_clp_db_mysql_pool, and a missing log-ingestor configuration is reported as a startup error instead of introducing a new panic path.

The packaged clp-config.yaml template documents the new setting, and focused Rust tests cover the default, a custom value, and rejection of zero. The tests use the project's anyhow::Result convention, and adjacent Rust error, panic, and expect messages follow the lowercase, no-period style. The Helm chart exposes the same setting through clpConfig.log_ingestor, renders it into the CLP ConfigMap, and bumps the chart version to 0.4.1-dev.2.

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

Rust lint

$ task lint:check-rust-static
task: Task "toolchains-rust" is up to date
task: [lint:cargo-workspace-clippy] . "/home/junhao/workspace/5-clp/build/toolchains/rust/env"
cargo +nightly clippy --all-targets --all-features -- -D warnings
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.22s

Rust tests

$ set -o pipefail
$ task tests:rust-all 2>&1 | tail -n 12
        PASS [   0.116s] (30/36) log-ingestor::log_ingestor_tests test_compression_listener::test_compression_listener
        PASS [   0.211s] (31/36) log-ingestor::log_ingestor_tests test_compression_listener::test_listener_hard_timeout
        PASS [   1.096s] (32/36) log-ingestor::log_ingestor_tests test_ingestion_job::test_s3_scanner
        PASS [   2.186s] (33/36) log-ingestor::log_ingestor_tests test_scan::test_scan_prefix_early_exit
        PASS [   8.132s] (34/36) log-ingestor::log_ingestor_tests test_ingestion_job::test_sqs_listener
        PASS [  10.018s] (35/36) log-ingestor::log_ingestor_tests test_ingestion_job::test_s3_scanner_single_object
        PASS [  11.498s] (36/36) log-ingestor::log_ingestor_tests test_scan::test_scan_prefix_multi_page_filtering
────────────
     Summary [  11.501s] 36 tests run: 36 passed, 0 skipped
task: [tests:rust-all] tools/scripts/localstack/stop.py \
--name "clp-localstack-rust-72c363a2-59c8-4bf7-9d02-7fc076b2426d"
2026-07-24 20:39:05 [INFO] LocalStack container stopped successfully.

Configuration and generated schema

$ uv run --directory components/clp-py-utils python - <<'PY'
from pydantic import ValidationError
from clp_py_utils.clp_config import LogIngestor

assert LogIngestor().database_connection_pool_size == 100
assert LogIngestor(database_connection_pool_size=42).database_connection_pool_size == 42
for invalid_value in (0, 2**32):
    try:
        LogIngestor(database_connection_pool_size=invalid_value)
    except ValidationError:
        pass
    else:
        raise AssertionError(f"accepted invalid pool size: {invalid_value}")
print("log-ingestor pool-size validation passed")
PY
log-ingestor pool-size validation passed

$ jq '.["$defs"].LogIngestor.properties.database_connection_pool_size' build/config-schema/clp-config.schema.json
{
  "default": 100,
  "exclusiveMaximum": 4294967296,
  "exclusiveMinimum": 0,
  "title": "Database Connection Pool Size",
  "type": "integer"
}

Helm chart

$ set -o pipefail
$ task lint:check-helm 2>&1 | tail -n 16
Linting chart "clp => (version: \"0.4.1-dev.2\", path: \"tools/deployment/package-helm\")"
Checking chart "clp => (version: \"0.4.1-dev.2\", path: \"tools/deployment/package-helm\")" for a version bump...
Old chart version: 0.4.1-dev.1
New chart version: 0.4.1-dev.2
Chart version ok.
Validating tools/deployment/package-helm/Chart.yaml...
Validation success! 👍
Validating maintainers...
==> Linting tools/deployment/package-helm

1 chart(s) linted, 0 chart(s) failed

------------------------------------------------------------------------------------------------------------------------
 ✔︎ clp => (version: "0.4.1-dev.2", path: "tools/deployment/package-helm")
------------------------------------------------------------------------------------------------------------------------
All charts linted successfully

$ . build/toolchains/helm/env
$ helm template test tools/deployment/package-helm | rg -m1 'database_connection_pool_size:'
      database_connection_pool_size: 100

$ helm template test tools/deployment/package-helm --set clpConfig.log_ingestor.database_connection_pool_size=42 | rg -m1 'database_connection_pool_size:'
      database_connection_pool_size: 42

$ helm template test tools/deployment/package-helm \
    --show-only templates/configmap.yaml \
    --set clpConfig.log_ingestor.database_connection_pool_size=42 \
  | uv run --directory components/clp-py-utils python -c '
import sys
import yaml
from clp_py_utils.clp_config import ClpConfig

manifest = yaml.safe_load(sys.stdin)
config = ClpConfig.model_validate(yaml.safe_load(manifest["data"]["clp-config.yaml"]))
assert config.log_ingestor is not None
assert config.log_ingestor.database_connection_pool_size == 42
print("rendered Helm CLP config validation passed")
'
rendered Helm CLP config validation passed

$ set -o pipefail
$ task helm:package 2>&1 | tail -n 4
task: [helm:package] mkdir -p '/home/junhao/workspace/5-clp/build/clp-package-helm'
task: [helm:package] . "/home/junhao/workspace/5-clp/build/toolchains/helm/env"
helm package "/home/junhao/workspace/5-clp/tools/deployment/package-helm" --destination "/home/junhao/workspace/5-clp/build/clp-package-helm"
Successfully packaged chart and saved it to: /home/junhao/workspace/5-clp/build/clp-package-helm/clp-0.4.1-dev.2.tgz

Full build

$ set -o pipefail
$ task 2>&1 | tail -n 12
task: [package] rm -rf '/home/junhao/workspace/5-clp/build/clp-package'
task: [package] rsync --archive "components/package-template/src/" "/home/junhao/workspace/5-clp/build/clp-package"
task: [package] if [ ! -f "components/package-template/src/etc/clp-config.yaml" ] ; then
  rsync --archive \
    "/home/junhao/workspace/5-clp/build/clp-package/etc/clp-config.template.json.yaml" \
    "/home/junhao/workspace/5-clp/build/clp-package/etc/clp-config.yaml"
fi
task: [package] rsync --archive --mkpath "/home/junhao/workspace/5-clp/build/config-schema/" "/home/junhao/workspace/5-clp/build/clp-package/usr/share/config-schemas/"
task: [package] rsync --archive --mkpath "/home/junhao/workspace/5-clp/build/webui/settings.json" "/home/junhao/workspace/5-clp/build/clp-package/etc/webui/"
task: [package] rsync --archive "tools/deployment/package/" "/home/junhao/workspace/5-clp/build/clp-package"
task: [package] rsync --archive "/home/junhao/workspace/5-clp/build/clp-package-image.id" "/home/junhao/workspace/5-clp/build/clp-package"
task: [package] echo '0.13.1-dev' > '/home/junhao/workspace/5-clp/build/clp-package/VERSION'

Package smoke test

The package smoke test could not reach compression because the local Docker Compose v5.3.1 installation hit the zero-replica dependency regression tracked in #2374. The partially started package was stopped successfully.

$ docker compose version
Docker Compose version v5.3.1

$ set -o pipefail
$ ./sbin/start-clp.sh 2>&1 | tail -n 15
 Container clp-package-4c3a6764-4a1e-44af-8e29-7c11221f5993-garbage-collector-1 Waiting 
 Container clp-package-4c3a6764-4a1e-44af-8e29-7c11221f5993-db-table-creator-1 Waiting 
 Container clp-package-4c3a6764-4a1e-44af-8e29-7c11221f5993-otel-collector-1 Waiting 
 Container clp-package-4c3a6764-4a1e-44af-8e29-7c11221f5993-query-worker-1 Waiting 
clp-package-4c3a6764-4a1e-44af-8e29-7c11221f5993 is missing dependency log-ingestor
2026-07-22T00:47:46.762 ERROR [start_clp] Failed to start CLP.
Traceback (most recent call last):
  File "/opt/clp/lib/python3/site-packages/clp_package_utils/scripts/start_clp.py", line 136, in main
    controller.start()
  File "/opt/clp/lib/python3/site-packages/clp_package_utils/controller.py", line 1240, in start
    subprocess.run(
  File "/usr/lib/python3.10/subprocess.py", line 526, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['docker', 'compose', '--project-name', 'clp-package-4c3a6764-4a1e-44af-8e29-7c11221f5993', '--file', 'docker-compose.yaml', 'up', '--detach', '--wait']' returned non-zero exit status 1.

Summary by CodeRabbit

  • New Features

    • Added configurable database connection pool sizing for log ingestion, defaulting to 100 connections.
    • Added validation to prevent zero or invalid pool-size values.
    • Included the setting in configuration templates and Helm deployments.
  • Bug Fixes

    • Log ingestion now reports a clear error when required configuration is missing.
  • Documentation

    • Updated configuration and error documentation to reflect the new behaviour.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The log-ingestor MySQL pool size is now configurable through Python and Rust configuration, validated as positive, exposed through deployment templates, and passed to pool creation. Missing configuration returns an error, with accompanying documentation and test updates.

Changes

Log-ingestor pool configuration

Layer / File(s) Summary
Configuration contracts and validation
components/clp-py-utils/..., components/clp-rust-utils/..., components/package-template/...
Python and Rust configuration models define the pool-size field and default, enforce positive bounds, and test JSON deserialization behavior.
Deployment configuration wiring
tools/deployment/package-helm/...
Helm values and generated config expose database_connection_pool_size, defaulting to 100.
Runtime pool-size wiring and error contract
components/log-ingestor/src/ingestion_job_manager*
Connector setup reads the configured pool size, passes it to MySQL pool creation, and returns contextual errors when log-ingestor configuration is absent.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

  • Issue 2385 — The PR replaces the hardcoded MySQL pool size and exposes it through log-ingestor configuration and Helm values.

Suggested reviewers: linzhihao-723

Sequence Diagram(s)

sequenceDiagram
  participant LogIngestorConfig
  participant ClpDbIngestionConnector
  participant MySQLPool
  LogIngestorConfig->>ClpDbIngestionConnector: provide configured pool size
  ClpDbIngestionConnector->>MySQLPool: create pool with configured size
  ClpDbIngestionConnector-->>LogIngestorConfig: return contextual error if configuration is missing
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR also changes unrelated error-message wording and doc cleanup in ingestion_job_manager.rs, which is outside the pool-size feature. Remove or justify the message/doc-only edits so the PR stays focused on the configurable pool-size change.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The config field, validation, defaults, runtime wiring, and deployment templates all implement the requested configurable pool size in #2039.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main change: making the log-ingestor database connection pool size configurable.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@junhaoliao
junhaoliao marked this pull request as ready for review July 22, 2026 01:48
@junhaoliao
junhaoliao requested a review from a team as a code owner July 22, 2026 01:48
@junhaoliao
junhaoliao requested a review from LinZhihao-723 July 22, 2026 01:48
@junhaoliao
junhaoliao marked this pull request as draft July 22, 2026 01:48
@junhaoliao
junhaoliao marked this pull request as ready for review July 22, 2026 02:21

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/clp-py-utils/clp_py_utils/clp_config.py`:
- Line 100: Add or confirm Python-side validation tests for the
DatabaseConnectionPoolSize alias covering 0, 2**32, and 2**32 - 1; assert the
exclusive lower and upper bounds reject 0 and 2**32 while accepting 2**32 - 1,
preserving alignment with Rust’s NonZeroU32 contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9e7a8fb2-fb79-46dc-b1b2-6e1b57248347

📥 Commits

Reviewing files that changed from the base of the PR and between d1248be and 1a8431a.

📒 Files selected for processing (5)
  • components/clp-py-utils/clp_py_utils/clp_config.py
  • components/clp-rust-utils/src/clp_config/package/config.rs
  • components/log-ingestor/src/ingestion_job_manager.rs
  • components/log-ingestor/src/ingestion_job_manager/clp_ingestion.rs
  • components/package-template/src/etc/clp-config.template.json.yaml
💤 Files with no reviewable changes (1)
  • components/log-ingestor/src/ingestion_job_manager.rs

Comment thread components/clp-py-utils/clp_py_utils/clp_config.py
Comment on lines +232 to +233
const DEFAULT_LOG_INGESTOR_DATABASE_CONNECTION_POOL_SIZE: NonZeroU32 =
NonZeroU32::new(100).unwrap();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  • How about moving it into default?
  • If not, we should move it after all public symbols to follow the symbol ordering guideline here.
  • Please don't use unwrap: use expect("Readable reason").

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.

Make MySQL pool size configurable in log-ingestor

2 participants