Skip to content

feat(tidb-stmt-cache): add Pulsar partitioned-topic replay scenario#140

Open
khareyash05 wants to merge 2 commits into
mainfrom
feat/tidb-stmt-cache-pulsar-routing
Open

feat(tidb-stmt-cache): add Pulsar partitioned-topic replay scenario#140
khareyash05 wants to merge 2 commits into
mainfrom
feat/tidb-stmt-cache-pulsar-routing

Conversation

@khareyash05
Copy link
Copy Markdown
Member

@khareyash05 khareyash05 commented Jun 3, 2026

Summary

  • Extends tidb-stmt-cache with a Pulsar producer + JPA-driven POST /events/patch endpoint that exercises Apache Pulsar's default RoundRobinPartition routing — the producer-side behaviour that surfaces the partition-suffix replay mismatch fixed in keploy/enterprise#2064.
  • Bean shape, JDBC params, JPA settings, and request body are deliberately generic so the regression repro is portable across deployments.
  • Existing /api/kv/* orphan-EXECUTE endpoints are untouched.

What's new

Path Purpose
pom.xml Adds spring-boot-starter-data-jpa + pulsar-client:3.1.1
application.properties Hikari autoCommit=false, JDBC prepStmtCacheSize=500&prepStmtCacheSqlLimit=2048, JPA provider_disables_autocommit=true, MySQLDialect, open-in-view=false, Pulsar broker/topic/partition-count
DataSourceConfig.java HikariCP bean wired for the autoCommit + provider_disables_autocommit pairing
EventEntity.java / EventRepository.java JPA persistence, Hibernate auto-DDL creates the events table
PulsarConfig.java PulsarClient + Producer<byte[]> with MessageRoutingMode.RoundRobinPartition
EventsController.java @Transactional POST /events/patch — JPA save + sync Pulsar send
docker-compose.yml Adds Pulsar 4.0.3 standalone + one-shot init container that creates the 8-partition topic
Dockerfile Two-stage Maven → JRE 17 build
k8s/ Namespace + TiDB + Pulsar + app manifests with keploy.io/record-session=true label
README.md Walkthroughs: local docker-compose smoke path and in-cluster k8s-proxy auto-replay path

Why RoundRobinPartition specifically

Pulsar's Java client default routing picks a random starting partition per producer instance. Across record/replay sessions the same producer publishing the same payload routes to a different partition number, so a recording captured on …events-partition-N cannot serve a live SEND to …events-partition-M. This is the smallest reliable repro — pinning routing (SinglePartition + fixed key) would mask the bug.

Test plan

  • mvn -DskipTests package — 8 sources compile, fat jar builds.
  • docker compose up -d boots TiDB, Pulsar (with 8 partitions), and the app cleanly.
  • curl POST /events/patch returns {"message":"Event patched"} with HTTP 200 against the local stack (docker compose mode, no agent).
  • In-cluster deployment via k8s/ manifests: TiDB / Pulsar / app all reach Ready; POST /events/patch returns 200 against the in-cluster Service.
  • k8s-proxy webhook injects the keploy-agent sidecar when the keploy.io/record-session label is present.
  • End-to-end replay verification — blocked locally on a kind eBPF cgroup-namespace issue (sidecar mode does not see peer container cgroups on this runtime); will validate against a DaemonSet-mode deployment.

🤖 Generated with Claude Code

khareyash05 and others added 2 commits June 3, 2026 17:22
Extends the existing TiDB orphan-COM_STMT_EXECUTE sample with an
HTTP endpoint that exercises Apache Pulsar's RoundRobinPartition
routing — the producer-side behaviour that triggers keploy's
partition-suffix replay mismatch (keploy/enterprise#2064).

The bean shape, JDBC parameters and JPA settings replicate the
Flipkart Global-Shipment-Master service's production config so a
recording captured against this sample produces mocks structurally
identical to the customer's:

  * HikariCP autoCommit=false paired with
    spring.jpa.properties.hibernate.connection.provider_disables_autocommit=true
  * JDBC URL: useServerPrepStmts=true&cachePrepStmts=true
              &prepStmtCacheSize=500&prepStmtCacheSqlLimit=2048
  * Hibernate MySQLDialect (TiDB is wire-compatible on :4000),
    open-in-view=false
  * Pulsar producer with MessageRoutingMode.RoundRobinPartition
    against an 8-partition topic pre-created by the
    docker-compose pulsar-init container

New endpoint: POST /events/patch — JPA-saves an Event row through
TiDB then synchronously publishes the payload to the partitioned
topic; mirrors the Flipkart endpoint shape exactly so the customer's
mocks.yaml can be replayed against this sample.

Existing /api/kv/* endpoints (orphan-EXECUTE scenario) are unchanged.

Additions:
  * EventEntity / EventRepository: JPA persistence, Hibernate
    auto-DDL creates the `events` table.
  * PulsarConfig: PulsarClient + Producer<byte[]> beans.
  * EventsController: @transactional POST /events/patch.
  * docker-compose: Apache Pulsar 4.0.3 standalone + one-shot
    pulsar-init that creates the partitioned topic.
  * Dockerfile: two-stage Maven -> JRE 17 build.
  * k8s/ manifests: namespace, TiDB Deployment+Service, Pulsar
    Deployment+Service+Job, app Deployment+Service with
    keploy.io/record-session=true for the static webhook.
  * README: walkthroughs for the local docker-compose smoke path
    and the in-cluster k8s-proxy auto-replay path.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The original sample documentation and inline comments named the
internal service, recording, message broker tenant, and entity-id
format the regression was first reported against. None of those
identifiers are needed to explain the bug — the failure mode is a
generic property of RoundRobinPartition routing across record/replay
sessions. Replace them with neutral phrasing.

Behavioural changes: none. Only docs, comments, and the example
curl payloads are touched.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@khareyash05 khareyash05 force-pushed the feat/tidb-stmt-cache-pulsar-routing branch from 248f082 to ff6c672 Compare June 3, 2026 11:52
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