Skip to content

Go - #3

Open
Yogeshjindal wants to merge 42 commits into
mainfrom
go
Open

Go#3
Yogeshjindal wants to merge 42 commits into
mainfrom
go

Conversation

@Yogeshjindal

Copy link
Copy Markdown

Kafka integration

slayerjain and others added 20 commits January 9, 2026 15:30
Signed-off-by: Shubham Jain <shubhamkjain@outlook.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Copilot AI review requested due to automatic review settings February 9, 2026 06:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a Go-based e-commerce microservices stack (user/product/order + API gateway) with Kafka support and Keploy artifacts for recording/replay, along with Docker Compose and Kubernetes (Kind) deployment resources.

Changes:

  • Added Go implementations for user_service, product_service, and apigateway (Gin + MySQL/sqlx + JWT middleware).
  • Added Kafka producer/consumer utilities and Docker Compose wiring for Kafka/ZooKeeper + topic initialization.
  • Added Keploy configs and recorded HTTP test fixtures, plus K8s/Kind manifests and helper scripts.

Reviewed changes

Copilot reviewed 92 out of 95 changed files in this pull request and generated 19 comments.

Show a summary per file
File Description
go-services/user_service/main.go User auth + user/address CRUD service (Gin + MySQL)
go-services/user_service/keploy.yml Keploy config for user_service
go-services/user_service/db.sql user_db schema (users, addresses)
go-services/user_service/Dockerfile Container build/runtime for user_service
go-services/product_service/main.go Product catalog + stock reserve/release service
go-services/product_service/keploy.yml Keploy config for product_service
go-services/product_service/db.sql product_db schema + seed inserts
go-services/product_service/Dockerfile Container build/runtime for product_service
go-services/apigateway/main.go Simple reverse-proxy API gateway for the services
go-services/apigateway/keploy.yml Keploy config for apigateway
go-services/apigateway/Dockerfile Container build/runtime for apigateway
go-services/internal/config/config.go Shared env-based configuration (incl. Kafka broker parsing)
go-services/internal/db/mysql.go MySQL connection helper w/ retry + pool settings
go-services/internal/auth/jwt.go JWT generation/validation helpers
go-services/internal/middleware/auth.go Gin JWT auth middleware
go-services/internal/kafka/producer.go Kafka producer wrapper (kafka-go)
go-services/internal/kafka/consumer.go Kafka consumer wrapper (kafka-go)
go-services/docker-compose.yml Local stack: MySQLs + Kafka/ZK + services + topic init
go-services/scripts/create-kafka-topics.sh Helper script to create Kafka topics
go-services/test_order_service.sh Test driver script to exercise order flows for Keploy recording
go-services/script.sh Local curl-based end-to-end script (Postman-like)
go-services/port-forward.sh Convenience port-forwarding script for K8s deployments
go-services/order_service/Dockerfile Order service container build (incl. Keploy faketime/CA setup)
go-services/order_service/entrypoint.sh Entry point to install CA then run order-service
go-services/order_service/db.sql order_db schema (orders, order_items)
go-services/order_service/keploy.yml Keploy config for order_service
go-services/order_service/keploy/.gitignore Ignores Keploy reports output
go-services/order_service/keploy/freezeTime/tests/test-1.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-2.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-3.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-4.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-5.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-6.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-7.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-8.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-9.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-10.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-11.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-12.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-13.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-14.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-15.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-16.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-17.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-18.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-19.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-20.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-21.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-22.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/freezeTime/tests/test-23.yaml Keploy recorded HTTP test fixture (freezeTime)
go-services/order_service/keploy/dedup/tests/test-1.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-2.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-3.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-4.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-5.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-6.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-7.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-8.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-9.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-10.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-11.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-12.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-13.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-14.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-15.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-16.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-17.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-18.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-19.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-20.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-21.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-22.yaml Keploy recorded HTTP test fixture (dedup)
go-services/order_service/keploy/dedup/tests/test-23.yaml Keploy recorded HTTP test fixture (dedup)
go-services/k8s/user-service.yaml K8s Service/Deployment for user-service
go-services/k8s/product-service.yaml K8s Service/Deployment for product-service
go-services/k8s/order-service.yaml K8s Service/Deployment for order-service
go-services/k8s/order-service-standalone.yaml Standalone order-service + Keploy agent pod spec
go-services/k8s/mysql-users.yaml K8s MySQL deployment for user_db
go-services/k8s/mysql-products.yaml K8s MySQL deployment for product_db
go-services/k8s/mysql-orders.yaml K8s MySQL deployment for order_db
go-services/k8s/localstack.yaml Localstack SQS init + service/deployment
go-services/k8s/apigateway.yaml K8s Service/Deployment for apigateway
go-services/k8s/README.md K8s/Kind deployment instructions
go-services/kind-config.yaml Kind cluster config (port mapping)
go-services/keploy.yml Root Keploy config for go-services
go-services/go.mod Go module definition + dependencies
go-services/guide.md Keploy workflow notes (local + K8s)
go-services/README.md Main documentation for running/testing stack + Kafka verification
go-services/.gitignore Ignores script/ directory

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +335 to +338
tx, _ := database.Beginx()
_, err := tx.Exec(
"INSERT INTO addresses (id, user_id, line1, line2, city, state, postal_code, country, phone, is_default) VALUES (?,?,?,?,?,?,?,?,?,?)",
addrID, userID, req.Line1, line2, req.City, req.State, req.PostalCode, req.Country, phone, isDefault,

Copilot AI Feb 9, 2026

Copy link

Choose a reason for hiding this comment

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

database.Beginx() errors are ignored (tx, _ := ...). If Beginx fails, tx will be nil and tx.Exec(...) will panic. Handle the Beginx error and return an appropriate 500 response.

Copilot uses AI. Check for mistakes.
Comment on lines +179 to +182
if desc, ok := req["description"]; ok {
sets = append(sets, "description=?")
args = append(args, desc)
}

Copilot AI Feb 9, 2026

Copy link

Choose a reason for hiding this comment

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

description is accepted as an untyped interface{} and forwarded directly to SQL. If a client sends a non-string JSON value (object/array/number), this will fail at runtime. Restrict description to string or null (validate type and return 400 on invalid input).

Copilot uses AI. Check for mistakes.
Comment on lines +4 to +6
until kafka-topics --bootstrap-server localhost:9092 --list >/dev/null 2>&1; do
sleep 1
done

Copilot AI Feb 9, 2026

Copy link

Choose a reason for hiding this comment

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

This script uses --bootstrap-server localhost:9092, but in docker-compose.yml Kafka is exposed on the host as localhost:29092 (and 9092 is only inside the Kafka container/network). If this script is meant to run on the host, it should use localhost:29092 (or accept the bootstrap server as an argument/env var).

Copilot uses AI. Check for mistakes.
Comment on lines +209 to +211
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("Failed to create user: %v", err)})
return

Copilot AI Feb 9, 2026

Copy link

Choose a reason for hiding this comment

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

This error response includes the raw DB error (%v), which can leak internal details (schema/driver messages) to clients. Return a generic message (and log the detailed error server-side) instead.

Copilot uses AI. Check for mistakes.
Comment on lines +346 to +351
if isDefault == 1 {
tx.Exec("UPDATE addresses SET is_default=0 WHERE user_id=? AND id<>?", userID, addrID)
}
tx.Commit()

c.JSON(http.StatusCreated, gin.H{"id": addrID})

Copilot AI Feb 9, 2026

Copy link

Choose a reason for hiding this comment

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

Commit() is called without checking its return value. If the commit fails (e.g., connection drop), the handler still returns 201 Created. Check the tx.Commit() error and return 500 on failure (and rollback where appropriate).

Copilot uses AI. Check for mistakes.
Comment on lines +399 to +404
fields := []string{"line1", "line2", "city", "state", "postal_code", "country", "phone"}
for _, f := range fields {
if val, ok := req[f]; ok {
sets = append(sets, f+"=?")
args = append(args, val)
}

Copilot AI Feb 9, 2026

Copy link

Choose a reason for hiding this comment

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

This dynamic update accepts any JSON type for line1/line2/city/... values and passes them directly to SQL args. Non-string values (objects/arrays) will cause SQL/driver errors at runtime. Validate/coerce expected types for each field (and reject invalid types with 400).

Copilot uses AI. Check for mistakes.
Comment thread go-services/script.sh
Comment on lines +46 to +57
if [ -z "$JWT" ]; then
echo "ERROR: Failed to get JWT token. Trying to create user first..."

# Try to create user first (might need admin token or no auth)
echo "Creating user..."
CREATE_USER_RESPONSE=$(curl -s -X POST "${USER_BASE}/users" \
-H "Content-Type: application/json" \
-d "{
\"username\": \"${USERNAME}\",
\"email\": \"${EMAIL}\",
\"password\": \"${PASSWORD}\"
}")

Copilot AI Feb 9, 2026

Copy link

Choose a reason for hiding this comment

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

This script attempts to create a user without an Authorization header when login fails, but the user_service implementation protects POST /api/v1/users with JWT auth. As written, this fallback path will always fail (and the script exits). Either obtain an admin token first and use it for user creation, or make user creation a public endpoint if that’s intended.

Copilot uses AI. Check for mistakes.
Comment on lines +95 to +96
hashedPwd, _ := bcrypt.GenerateFromPassword([]byte(cfg.AdminPassword), bcrypt.DefaultCost)

Copilot AI Feb 9, 2026

Copy link

Choose a reason for hiding this comment

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

bcrypt.GenerateFromPassword errors are ignored here, which could lead to inserting/updating an empty/invalid hash (and masking configuration issues). Handle the returned error and abort seeding (or log and return) if hashing fails.

Copilot uses AI. Check for mistakes.
Comment on lines +375 to +377
database.Select(&addresses, "SELECT id, line1, line2, city, state, postal_code, country, phone, is_default FROM addresses WHERE user_id=? ORDER BY is_default DESC, created_at DESC", userID)

c.JSON(http.StatusOK, addresses)

Copilot AI Feb 9, 2026

Copy link

Choose a reason for hiding this comment

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

The addresses list query error is ignored. If database.Select fails, this returns 200 with an empty list, hiding DB issues. Handle the error and return 500 when the query fails.

Copilot uses AI. Check for mistakes.
Comment on lines +68 to +71
- name: keploy-data
hostPath:
path: /home/ashish/asish_workspace/flipkart-jan/ecommerce_sample_app/go-services/order_service/keploy
type: Directory

Copilot AI Feb 9, 2026

Copy link

Choose a reason for hiding this comment

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

This manifest hardcodes a developer-specific absolute hostPath (/home/ashish/...). This will not work on other machines/CI and is unsafe to commit as-is. Use a PVC, emptyDir, or a configurable path (and document how to mount Keploy data) instead of an absolute workstation path.

Copilot uses AI. Check for mistakes.
- Add safe_consumer.go and safe_producer.go with graceful shutdown handling
- Update consumer.go and producer.go to use safe wrappers
- Improve order service Dockerfile and entrypoint.sh for better Keploy integration
- Update keploy.yml configuration for order service
- Enhance docker-compose.yml with proper service dependencies
- Remove unnecessary Keploy test sets (dedup and freezeTime)
- Update .gitignore to exclude logs, binaries, coverage, and analysis files
slayerjain and others added 16 commits March 10, 2026 14:49
Alpine 3.19 package registry intermittently fails in CI, causing builds
to error on `apk add ca-certificates`. Copy the certs directly from the
builder stage instead, and bump the runtime base to alpine:3.21.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…real readiness

The MySQL healthchecks used `mysqladmin ping -h localhost`, which probes the unix
socket. During MySQL's init phase the server runs on the socket only
(skip-networking) while it applies /docker-entrypoint-initdb.d, so the socket
ping reports healthy BEFORE the network port (3306) is accepting connections.
Services gated on `depends_on: { condition: service_healthy }` (user_service,
product_service, order_service) then start too early and, under CI load where
init is slow, exhaust their connect-retry budget with "connection refused" and
panic (exit 143), failing the kafka-ecommerce lane intermittently.

Force a TCP probe (`-h 127.0.0.1 --protocol=tcp`) so service_healthy only fires
once 3306 actually serves, and add a 60s start_period grace for slow init under
contention. Dependents now reliably wait for a connectable database.

Signed-off-by: slayerjain <shubhamkjain@outlook.com>
fix(go-services): TCP-based MySQL healthcheck so dependents wait for real readiness
Two attributes made it impossible to run two copies of this stack on one docker
host, which is what keploy's CI needs to exercise the default and low-latency
record modes concurrently.

`container_name:` is GLOBAL to the docker daemon — it deliberately ignores
COMPOSE_PROJECT_NAME. With it set on all eight services, a second
`docker compose up` under a different project name does not get its own
containers: it collides with, or silently reuses, the first stack's. Removing it
lets compose derive `<project>-<service>-N`, which is namespaced.

Nothing depended on those names. Inter-service traffic already addresses
SERVICE names (USER_SERVICE_URL=http://user_service:8082,
AWS_ENDPOINT=http://localstack:4566, DB_HOST=mysql-products), and compose DNS
resolves service names regardless of container_name — verified that every host
referenced in the file is a service name. keploy's --container-name also
matches the service name, not just container_name (pkg/platform/docker:
`containerNameMatch || serviceName == containerName`), so recording against
`order_service` keeps working.

The eight published host ports are the other half: two stacks cannot both bind
3307-3309, 4566 and 8080-8083. They are now `${VAR:-<current>}`, so a caller
that wants a second stack can offset them while every existing consumer —
`docker compose up` with no environment at all — gets byte-identical ports to
before.

Verified with `docker compose config`: with no environment the published ports
are unchanged (3307, 3308, 3309, 4566, 8080, 8081, 8082, 8083), and with
MYSQL_PRODUCTS_PORT/ORDER_SERVICE_PORT set they move to the overrides. Zero
explicit container_name entries remain.

Signed-off-by: Shubham Jain <shubham@keploy.io>
fix(compose): make the stack parallel-safe without changing its defaults
…y uses)

#16 made the ROOT docker-compose.yml parallel-safe, but keploy's kafka-ecommerce
lane does `cd ecommerce_sample_app/go-services` and uses THIS file, which still
had 10 explicit `container_name:` entries and 9 fixed host ports. So the lane
kept colliding exactly as before, and the log gave it away: every container came
up under a bare name (`user_service`, `mysql-products`, `kafka`) with no project
prefix, and the service list included kafka/zookeeper/kafka-init — services that
do not exist in the root file at all.

Same change as #16, applied where it matters:

- `container_name:` removed from all ten services. It is GLOBAL to the docker
  daemon and ignores COMPOSE_PROJECT_NAME, so while it was set two stacks could
  not coexist on one host no matter how they were namespaced.
- the nine published host ports are now `${VAR:-<current>}`.

Nothing depended on the old names: every inter-service reference already uses a
SERVICE name, which compose DNS resolves regardless of container_name — checked
programmatically across every environment value in the file, including the
Kafka bootstrap servers and the three DB_HOSTs. keploy's --container-name also
matches the service name (pkg/platform/docker:
`containerNameMatch || serviceName == containerName`).

Verified with `docker compose config`: with no environment the published ports
are unchanged (2181, 3307-3309, 8080-8083, 29092), and a second axis with
offsets resolves to a fully disjoint set. Zero explicit container_name remain.

Signed-off-by: Shubham Jain <shubham@keploy.io>
fix(compose): make go-services parallel-safe too (the file CI actually uses)
…-init flake

The kafka-ecommerce lane in keploy CI fails intermittently with

  dependency failed to start: container
  kafka-ecom-low-latency-mysql-users-1 is unhealthy

and the cause is structural. mysql:8.0 declares VOLUME /var/lib/mysql and
this compose file names no volume for it, so every container gets a fresh
anonymous volume and every `compose up` pays a full cold
`mysqld --initialize`. The lane runs two matrix axes concurrently, three
MySQLs each, so six cold inits and their fsyncs contend for one host disk.

Pipeline 8806 shows it. The two axes started 17s apart, and during the
replay phase their inits overlapped six ways: those took 102-119s, against
a budget of start_period 60s + retries 20 x interval 5s = 160s. The
container that failed ran 11:54:41 -> 11:57:18 and compose gave up at
11:57:38 -- 177s, over budget -- with a probe history of five consecutive
"Can't connect to MySQL server on '127.0.0.1:3306' (111)".

Nothing in these databases needs to outlive its container -- they are
seeded from db.sql on every start and thrown away -- so put the datadir on
tmpfs and stop paying for the disk round-trips at all.

Measured here (8 cores / 31G, idle; host-specific, so direction rather than
a promise): tmpfs flattens the concurrency scaling completely. One, three
and six containers all reach healthy in 11s, where the anonymous volume
scaled 16s -> 21s -> 22s. That is comfortably inside the existing 60s
start_period, which is why this does NOT raise it. Raising the threshold as
well would mean a green lane could no longer tell you which change fixed
it, and it costs diagnosability: time-to-unhealthy is
start_period + retries*interval, and the CI script gives up at 240s, so a
wider start_period narrows that margin until the script's generic
"failed to start" fires before compose's precise "dependency failed to
start: ... is unhealthy".

The tmpfs is size-capped at 1g. An unbounded Docker tmpfs may grow to 50%
of host RAM -- verified 15.7G on a 32G box -- so six of them could nominally
claim far more than the host has. The cap's failure mode is documented in
the file because it is not the obvious one: MySQL does not exit on a full
datadir, it logs "Disk is full ... waiting", retries every 60s, reprints
only every 600s, and the healthcheck keeps reporting healthy, so a run that
hits it hangs with little pointing at the cause.

--skip-log-bin is what keeps that far away. At rest it saves almost nothing
(202M -> 199M), but binary logging was roughly half the datadir's growth
under writes, and it buys nothing here: no replication, no point-in-time
recovery, and keploy's MySQL capture is wire-protocol based -- the server
greeting packet is byte-identical with and without it, so recorded mocks
cannot diverge. 199M against a 1g cap leaves ~825M free at a measured ~1.5x
amplification.

Not also shrinking innodb_redo_log_capacity, which was tempting: it frees a
further ~68M per container, but the redo log is preallocated, so on tmpfs it
costs no init time to keep -- both variants cold-start in 11s -- and capping
it at 32M makes InnoDB block writer threads with "MY-014084 ... unable to
reserve space in redo log" after ~25MB of writes. That trades a new stall
mode for RAM nothing here is short of.

One cost to be explicit about: tmpfs pages are pinned and non-reclaimable
and are charged to the CI step's memory cgroup, where the anonymous volume
was backed by reclaimable page cache. That is ~199M per container, ~1.2G
across the two concurrent axes. The lane declares no memory limit, so this
is the figure to watch if it ever OOMs.

One behaviour change: the datadir now dies with the container, not just with
the volume, so `compose stop && compose start` re-initialises and re-runs
db.sql instead of preserving rows. CI is unaffected, since it tears the
project down between the record and replay phases and both already started
from a virgin DB. Local `docker compose up` flows in README.md and guide.md
get a clean DB per run, which is what replay determinism wants anyway.

The healthcheck, tmpfs and server flags are now stated once in an
x-mysql-common anchor instead of triplicated. Compose merges that mapping
key-by-key rather than recursively, so a service declaring its own
`healthcheck:` would replace that key wholesale; the file says so.

Signed-off-by: slayerjain <shubhamkjain@outlook.com>
fix(go-services): keep the MySQL test datadirs in RAM to end the cold-init flake
#18 de-triplicated the three MySQL services into `x-mysql-common: &mysql-common`
merged in with `<<: *mysql-common`. Docker accepts that -- it is the pattern the
Compose spec endorses for reuse -- but it broke keploy's kafka-ecommerce lane:

  go-yaml load error in composer at L15.C21:
  unknown anchor 'mysql-common' referenced
  ERROR error while running the app {"error": "exit status 1"}

keploy rewrites the compose file into a temporary one before running the app,
and that rewrite keeps exactly six top-level keys -- version, services,
networks, volumes, configs, secrets -- dropping every other one. `services`
survives as a raw YAML node, so `<<: *mysql-common` was preserved verbatim while
the `x-*` block that defined the anchor was discarded. The generated file then
referenced an anchor that no longer existed and the app never started.

Write the shared block out per service instead. The resolved `docker compose
config` is unchanged: the three services' settings are byte-identical to what
the anchor produced, and everything else in the file is untouched.

An anchor declared INSIDE `services:` would survive the rewrite intact and is
noted in the file as the working alternative. It is not used here because it
makes the three services share one node while keploy mutates the services tree,
so an edit aimed at one service would silently reach all three.

The real defect is keploy's, not this file's, and is fixed separately so that
compose files using the spec's own extension fields round-trip intact. This
change is what unblocks CI in the meantime, since the lane runs whatever keploy
release it is pinned to.

Signed-off-by: slayerjain <shubhamkjain@outlook.com>
…mp.yaml

keploy writes docker-compose-tmp.yaml into the working directory when it rewrites
a compose file to inject its agent. A copy of that generated artifact was
committed, and it has since drifted into a trap: it still carries the
`mysqladmin ping -h localhost` probe that reports healthy while MySQL's
socket-only init server is running, hardcoded host ports 3307-3309 instead of the
`${MYSQL_*_PORT}` indirection that lets axes run in parallel, and hardcoded
container_names that collide on a shared host.

It is not loaded by accident -- keploy only globs docker-compose.yml/.yaml and
compose.yml/.yaml -- but anyone running `docker compose -f docker-compose-tmp.yaml
up` gets that stale config, and any keploy run from go-services/ overwrites the
tracked file and dirties the tree.

Remove it and ignore the path.

Signed-off-by: slayerjain <shubhamkjain@outlook.com>
…ewrite

fix(go-services): stop sharing MySQL config through a top-level anchor
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.

5 participants