Created
March 26, 2019 09:20
-
-
Save mashingan/247ac80f163ea10b9ef02319aaa09bd0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"database/sql" | |
"fmt" | |
"log" | |
"math/rand" | |
"sync" | |
"sync/atomic" | |
"time" | |
_ "github.com/mattn/go-sqlite3" | |
) | |
const gorout int = 10000 | |
func sqliteLogger(message string, errcount *uint64, wg *sync.WaitGroup, p conns) { | |
defer wg.Done() | |
atomic.AddUint64(errcount, 1) | |
c := p.Conn() | |
p.Inc() | |
c.Mutex.Lock() | |
_, err := c.DB.Exec(`insert into logging(message) values(?);`, message) | |
c.Mutex.Unlock() | |
if err != nil { | |
log.Println(err) | |
} | |
} | |
func runner(r *rand.Rand, iter int, tehchan chan int, errcount *uint64, | |
wg *sync.WaitGroup, | |
p conns, | |
) { | |
go func(r *rand.Rand, iter int, tehchan chan int) { | |
somerand := r.Float64() | |
if somerand < 0.5 { | |
wg.Add(1) | |
go sqliteLogger( | |
fmt.Sprintf("Some error happened with: %f and iter: %d", | |
somerand, iter), | |
errcount, wg, p) | |
} | |
tehchan <- iter | |
}(r, iter, tehchan) | |
} | |
type conn struct { | |
*sql.DB | |
*sync.Mutex | |
} | |
type conns struct { | |
cs []*conn | |
count uint64 | |
} | |
func (cs conns) Inc() { | |
atomic.AddUint64(&cs.count, 1) | |
} | |
func (cs conns) Conn() *conn { | |
return cs.cs[cs.count%uint64(len(cs.cs))] | |
} | |
func (c *conn) Close() error { | |
return c.DB.Close() | |
} | |
func openDb() *sql.DB { | |
db, err := sql.Open("sqlite3", "./log_with_sqlite.db") | |
if err != nil { | |
log.Println("Fatal:", err) | |
return nil | |
} | |
_, err = db.Exec("CREATE TABLE IF NOT EXISTS logging(message text);") | |
return db | |
} | |
func dbPool() conns { | |
dbsCount := 4 | |
//connection := make(conns, dbsCount) | |
connection := conns{} | |
connection.count = 0 | |
connection.cs = make([]*conn, dbsCount) | |
for i := 0; i < dbsCount; i++ { | |
connection.cs[i] = &conn{openDb(), &sync.Mutex{}} | |
} | |
return connection | |
} | |
func poolClose(p conns) { | |
for _, c := range p.cs { | |
c.DB.Close() | |
} | |
} | |
func main() { | |
pool := dbPool() | |
defer poolClose(pool) | |
var errcount uint64 = 0 | |
var wg sync.WaitGroup | |
random := rand.New(rand.NewSource(time.Now().Unix())) | |
logchan := make(chan int, 100) | |
fmt.Println("starting goroutine") | |
start := time.Now() | |
for i := 0; i < gorout; i++ { | |
runner(random, i, logchan, &errcount, &wg, pool) | |
} | |
fmt.Println("end loop goroutine") | |
fmt.Println("Waiting sync") | |
count := 0 | |
theloop: | |
for { | |
select { | |
case _, ok := <-logchan: | |
if !ok { | |
break theloop | |
} | |
count++ | |
case <-time.Tick(500 * time.Millisecond): | |
fmt.Println("Ending at count:", count) | |
break theloop | |
} | |
} | |
fmt.Println("Ended") | |
wg.Wait() | |
elapsed := time.Now().Sub(start) | |
fmt.Printf("Total wait is: %v\n", elapsed) | |
fmt.Println("Error count is:", errcount) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment