package pool import ( "fmt" "sync" "time" ) // DBManager simulates a connection pool using a channel of "connections". type DBManager struct { pool chan int } // NewDBManager creates a pool manager with capacity `cap`. func NewDBManager(cap int) *DBManager { p := make(chan int, cap) // initialize simulated connections IDs 1..cap for i := 1; i <= cap; i++ { p <- i } return &DBManager{pool: p} } // getConn pulls a connection id from pool (blocking if none available) func (m *DBManager) getConn() int { return <-m.pool } // releaseConn returns a connection id to the pool func (m *DBManager) releaseConn(id int) { m.pool <- id } // EksekusiQuery simulates executing a query: take connection, wait 1s, release. func (m *DBManager) EksekusiQuery(query string) string { conn := m.getConn() // Simulate query execution time.Sleep(time.Second * 1) m.releaseConn(conn) return fmt.Sprintf("conn-%d executed: %s", conn, query) } // RunQueries launches n goroutines that call EksekusiQuery. // Returns list of responses in the order goroutines finished. func (m *DBManager) RunQueries(n int) []string { var wg sync.WaitGroup wg.Add(n) resCh := make(chan string, n) for i := 0; i < n; i++ { q := fmt.Sprintf("SELECT %d", i+1) go func(query string) { defer wg.Done() res := m.EksekusiQuery(query) resCh <- res }(q) } wg.Wait() close(resCh) out := make([]string, 0, n) for s := range resCh { out = append(out, s) } return out }