65 lines
1.4 KiB
Go
65 lines
1.4 KiB
Go
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
|
|
}
|