spark-server/.cursor/skills/spark-im-v3/SKILL.md
2026-09-16 19:08:06 +08:00

2.1 KiB

name description
spark-im-v3 Implements Spark IM modular monolith per architecture V3. Use when writing or reviewing spark-server Go code, TCP/gnet, Gin HTTP, messages, deliver queue, inbox ZSET, Nginx 443 SNI, PROXY protocol, or SEND_ACK. Trigger terms: IM, MsgId, TaskPool, deliver:queue, SYNC_INBOX, gnet, RealIP.

Spark IM V3

Read invariants.md before changing send/sync/transport. Full design: docs/architecture-v3.md. Lint: .golangci.yaml.

Layout

cmd/server                  process entry
internal/bootstrap          config, lifecycle
internal/transport/http     Gin, loopback :8080
internal/transport/tcp      gnet EventLoop + TaskPool + Frame
internal/module/*           Application services (HTTP and TCP share these)
internal/infrastructure     mysql, redis, id, logger, push

Module files: service.go + entity types + repository.go interface. No extra DDD layer.

Send path (must keep this order)

  1. TaskPool (not EventLoop)
  2. Permission (friend / block / group mute) — fail before INSERT
  3. Snowflake MsgId (or client MsgId within ±5m)
  4. MySQL txn: messages + conversations.last_msg_id
  5. DeliverQueue.Push (reliable list)
  6. SEND_ACK

If step 5 fails, do not ACK. Client retries the same client_msg_id.

EventLoop vs pools

Pool Owns
gnet EventLoop PROXY, TLS, Frame, heartbeat, PUSH_ACK, Submit
TaskPool AUTH, SEND, SYNC, READ, RECALL, MySQL
Deliver Worker ZSET inbox, Session.Send, mailbox on push fail, PushNotifier

Commands

AUTH HEARTBEAT GENERATE_MSG_ID SEND_MESSAGE SEND_ACK MESSAGE PUSH_ACK READ RECALL SYNC_INBOX SYNC_MESSAGES KICK

Media: HTTP upload credential, message content is object key only. Frame max 64KB. Compress body over 512B.

When adding a feature

  • HTTP writes must enqueue deliver jobs for online devices.
  • List/unread go to Redis ZSET, not MySQL row-per-member.
  • New goroutine I/O does not belong in OnTraffic.
  • Run make lint (funlen 100).

Additional resources