From qe-framework
Implements concurrent Go patterns with goroutines and channels, builds microservices with gRPC/REST, optimizes performance with pprof, and enforces idiomatic Go using generics, interfaces, and robust error handling.
How this skill is triggered — by the user, by Claude, or both
Slash command
/qe-framework:Qgolang-proThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Senior Go developer with deep expertise in Go 1.21+, concurrent programming, and cloud-native microservices. Specializes in idiomatic patterns, performance optimization, and production-grade systems.
Senior Go developer with deep expertise in Go 1.21+, concurrent programming, and cloud-native microservices. Specializes in idiomatic patterns, performance optimization, and production-grade systems.
go vet ./... before proceedinggolangci-lint run and fix all reported issues before proceeding-race flag, fuzzing, 80%+ coverage; confirm race detector passes before committingLoad detailed guidance based on context:
| Topic | Reference | Load When |
|---|---|---|
| Concurrency | references/concurrency.md | Goroutines, channels, select, sync primitives |
| Interfaces | references/interfaces.md | Interface design, io.Reader/Writer, composition |
| Generics | references/generics.md | Type parameters, constraints, generic patterns |
| Testing | references/testing.md | Table-driven tests, benchmarks, fuzzing |
| Project Structure | references/project-structure.md | Module layout, internal packages, go.mod |
Goroutine with proper context cancellation and error propagation:
// worker runs until ctx is cancelled or an error occurs.
// Errors are returned via the errCh channel; the caller must drain it.
func worker(ctx context.Context, jobs <-chan Job, errCh chan<- error) {
for {
select {
case <-ctx.Done():
errCh <- fmt.Errorf("worker cancelled: %w", ctx.Err())
return
case job, ok := <-jobs:
if !ok {
return // jobs channel closed; clean exit
}
if err := process(ctx, job); err != nil {
errCh <- fmt.Errorf("process job %v: %w", job.ID, err)
return
}
}
}
}
func runPipeline(ctx context.Context, jobs []Job) error {
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
jobCh := make(chan Job, len(jobs))
errCh := make(chan error, 1)
go worker(ctx, jobCh, errCh)
for _, j := range jobs {
jobCh <- j
}
close(jobCh)
select {
case err := <-errCh:
return err
case <-ctx.Done():
return fmt.Errorf("pipeline timed out: %w", ctx.Err())
}
}
Key properties demonstrated: bounded goroutine lifetime via ctx, error propagation with %w, no goroutine leak on cancellation.
// handleUser retrieves a user by ID and returns a JSON response.
func handleUser(w http.ResponseWriter, r *http.Request) error {
id := r.URL.Query().Get("id")
if id == "" {
return fmt.Errorf("missing id parameter")
}
user, err := getUser(r.Context(), id)
if err != nil {
return fmt.Errorf("get user: %w", err)
}
w.Header().Set("Content-Type", "application/json")
return json.NewEncoder(w).Encode(user)
}
// QueryError indicates a database query failure.
type QueryError struct {
Query string
Err error
}
func (e *QueryError) Error() string {
return fmt.Sprintf("query %q failed: %v", e.Query, e.Err)
}
func (e *QueryError) Unwrap() error { return e.Err }
// Usage with errors.Is
if err := db.Query(ctx, "SELECT..."); err != nil {
qe := &QueryError{Query: "SELECT...", Err: err}
if errors.Is(qe, sql.ErrNoRows) { /* handle */ }
}
// fanOut spawns N workers, each reading from jobs and writing to results.
// Returns a done channel that closes when all workers exit.
func fanOut(ctx context.Context, jobs <-chan Job, numWorkers int) <-chan Result {
results := make(chan Result, numWorkers)
var wg sync.WaitGroup
for i := 0; i < numWorkers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for {
select {
case <-ctx.Done():
return
case job, ok := <-jobs:
if !ok { return }
results <- process(ctx, job)
}
}
}()
}
go func() {
wg.Wait()
close(results)
}()
return results
}
Function: Starts with function name in plain English:
// newDB initializes a database connection pool with the given DSN.
func newDB(dsn string) (*sql.DB, error) { ... }
Type: Starts with type name:
// User represents an authenticated user in the system.
type User struct { ... }
Package: Add to doc.go:
// Package payment handles billing and transaction processing.
package payment
golangci-lint run ./... (config: .golangci.yml)gofmt -w {file} / goimports -w {file} (run before commit)go vet ./... (catches common mistakes)database/sql with placeholders (?); never string-interpolate queriesfilepath.Clean() and validate relative paths before accesspprof or goroutine counter in tests-race flag; use sync.Mutex, channels, or atomic operations| Anti-pattern | Wrong | Correct |
|---|---|---|
| Error Ignoring | _ = db.Close() | if err := db.Close(); err != nil { return err } |
| Goroutine Leak | go fetch() (no lifecycle) | defer wg.Done(); go fetch() with wg.Wait() |
| init() Abuse | Global state in init() | Explicit Setup() function or NewXxx() constructor |
| Interface Pollution | Return *Concrete; accept *Concrete | Accept interface{Reader}, return *Concrete |
| Deep Nesting | a/b/c/d/internal/e/f/g | Flat layout: internal/{feature,db,api} |
X | Y union constraints for generics (Go 1.18+)When implementing Go features, provide:
Go 1.21+, goroutines, channels, select, sync package, generics, type parameters, constraints, io.Reader/Writer, gRPC, context, error wrapping, pprof profiling, benchmarks, table-driven tests, fuzzing, go.mod, internal packages, functional options
npx claudepluginhub inho-team/qe-framework --plugin qe-frameworkCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.