Skip to content

Merge upstream 1.0 - #220

Open
piupiuxiupa wants to merge 9 commits into
apache:masterfrom
piupiuxiupa:merge-upstream-1.0
Open

Merge upstream 1.0#220
piupiuxiupa wants to merge 9 commits into
apache:masterfrom
piupiuxiupa:merge-upstream-1.0

Conversation

@piupiuxiupa

Copy link
Copy Markdown

No description provided.

Jinn and others added 9 commits August 14, 2026 14:32
…ion release

Ported from the pre-1.0 fork. aiomysql's Pool only frees a slot inside
release(); calling ensure_closed() on a checked-out connection leaves the
slot permanently counted as in-use, slowly exhausting the pool:

- _cleanup_stale_connections: bad connections found by the periodic
  stale test are now closed-then-released in a finally block instead of
  only ensure_closed() (this ran every ~2x health_check_interval and
  leaked one slot per stale connection found - the root cause of the
  original connection-exhaustion outage).
- _warmup_pool: the failure path now discards held warmup connections
  through the same close-then-release path.
- release_connection: an already-closed checked-out connection is now
  still release()d so the pool's in-use counter stays correct.

Adds a _discard_pool_connection helper (force-close then release) next
to _force_close_raw_connection.

Co-Authored-By: Claude <noreply@anthropic.com>
Adds a configurable ROUTE_PREFIX (e.g. /doris-mcp) so the server can sit
behind a reverse proxy under a sub-path. Ported from the pre-1.0 fork and
adapted to the 1.0 transport structure:

- config: route_prefix field on DorisConfig, ROUTE_PREFIX env read in
  from_env() with "/<segment>" normalization.
- main: --route-prefix CLI arg, prefix stripping + root_path rewrite at
  the top of the single-worker mcp_app dispatcher, / root-info endpoint,
  ROUTE_PREFIX propagated to uvicorn workers via _multiworker_environment.
- multiworker_app: prefix stripping + root_path rewrite in the top-level
  app(); root_info now reports the prefixed endpoint paths.
- start_server.sh: ROUTE_PREFIX env (opt-in), prefixed URL hints, and
  conditional --route-prefix passthrough.

The prefix is stripped in the outer ASGI routers (before exact-path
dispatch), so DorisMCPHTTPTransport and the legacy adapter see clean
/mcp paths and need no changes. uvicorn's own root_path is deliberately
not used: it prepends the prefix to scope["path"] instead of allowing
us to strip it.

Co-Authored-By: Claude <noreply@anthropic.com>
Ported from the pre-1.0 fork onto the 1.0 logger (which now also carries
the SensitiveDataFilter - preserved untouched):

- Port-suffixed log base name: setup_logging() gains base_name and
  ConfigManager passes doris_mcp_server_<port> for http transport so
  multi-instance deployments on different ports do not collide.
- TimestampRotatingFileHandler: size-based rollover renames to
  <base>_<YYYYmmdd_HHMMSS>.log instead of .log.N, pruning oldest
  backups; used for level files, the combined log, and the audit log.
- LogCleanupManager.cleanup_at_startup (default False): first cleanup
  pass waits one full interval so logs from a previous run are not
  purged on boot; start_server.sh no longer deletes *.log on startup.
- RequestAuthContextFilter: injects user/token_id/client_ip from the
  shared mcp_auth_context_var into every log record (reads upstream's
  richer AuthContext), attached to console, level, combined, and audit
  handlers; formatters show [user=... token=... ip=...].

Co-Authored-By: Claude <noreply@anthropic.com>
Ported from the pre-1.0 fork. _convert_numpy_types still raised
"Object of type Decimal is not JSON serializable" for any ADBC query
selecting a DECIMAL column, because Arrow Flight SQL exposes DECIMAL as
decimal.Decimal. Now coerces Decimal (to float, str on overflow),
datetime/date (isoformat), and bytes/bytearray (utf-8 decode, hex
fallback) in both the numpy-available path and the ImportError
fallback. The non-ADBC path already had equivalent handling upstream
via _serialize_row_data.

Co-Authored-By: Claude <noreply@anthropic.com>
Ported from the pre-1.0 fork. get_table_comment_async failed with
"Unknown column 'table_comment'" on Doris versions whose
information_schema.tables lacks TABLE_COMMENT, returning no comment.
On that error it now retries via SHOW TABLE STATUS (Comment column,
present on all versions) and normalizes the key, so table comments
resolve across Doris versions.

Co-Authored-By: Claude <noreply@anthropic.com>
Ported from the pre-1.0 fork. These acquire sites were missed by the
1.0 refactor and leaked a pool slot whenever an exception (or early
error-dict return) preceded release:

- analysis_tools: get_table_summary, analyze_column,
  analyze_table_relationships, get_performance_stats
- dependency_analysis_tools: analyze_dependencies (never released at
  all, on any path)

Each now releases via try/finally using the same defensive
getattr(connection_manager, "release_connection") idiom as the already
fixed get_sql_explain/get_sql_profile.

Co-Authored-By: Claude <noreply@anthropic.com>
- .env.example: safer pool defaults (DORIS_MAX_CONNECTIONS=8,
  DORIS_MAX_CONNECTION_AGE=1800) with a note on the
  WORKERS x max_connections vs Doris max_user_connection_num budget.
- .gitignore: ignore .claude/, .sisyphus/, .pytest_cache/.
- examples/examples.py: DorisUnifiedClient example (HTTP + stdio) from
  the fork; the HTTP URL uses the /doris-mcp route prefix.

Co-Authored-By: Claude <noreply@anthropic.com>
…handler

Missed in the logging re-port; without it _all.log lines show
user/token/ip placeholders as '-' even for authenticated requests.

Co-Authored-By: Claude <noreply@anthropic.com>
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