Skip to content

Instantly share code, notes, and snippets.

@jmingov
Last active June 5, 2018 20:26
Show Gist options
  • Save jmingov/6d80e403c17c96f4ca6b2968e5e5ae8d to your computer and use it in GitHub Desktop.
Save jmingov/6d80e403c17c96f4ca6b2968e5e5ae8d to your computer and use it in GitHub Desktop.
package main
import (
"log"
"math/rand"
"time"
)
const TIME_LIMIT = time.Second
var doneProducing = make(chan bool)
var pwChan = make(chan int)
var wrChan = make(chan int)
var doneReceiving = make(chan bool)
var initTime = time.Now()
var numWorkers = 10
var jobs = 98
func main() {
// start producing jobs
go produce(jobs)
// start waiting for jobs done
go receiver(jobs)
// start workers for jobs
for i := 0; i < numWorkers; i++ {
go work()
}
// wait for done producing
<-doneProducing
}
func produce(totalJobs int) {
// current job
i := 0
// marker for timing
jobsProduced := 0
// start tracking time passed producing
t := time.Now()
for {
// we have sent 1 job per worker
if jobsProduced == numWorkers {
// if moreThanTimeLimit has passed
if moreThanTL(t) {
// reset
jobsProduced = 0
t = time.Now()
}
} else {
// normal round, send work
log.Printf("Sending %d", i)
// send job
pwChan <- i
// add to counters
i += 1
jobsProduced += 1
}
// we finished doing our jobs, quit producing
if i == totalJobs {
//log.Printf("Rondas done %d", i)
break
}
}
end(initTime, "PRODUCE")
// make main wait for all to finish
doneProducing <- <-doneReceiving
}
func work() {
// the routine receives the data,
// sleeps for a random time
// and sends response to receiver (wrChan)
for {
resp := <-pwChan
// do work
//log.Printf("Consuming %d", d)
myrand := time.Duration(random(0, 500))
//log.Printf("sllep %s", myrand*(time.Second/100))
time.Sleep(myrand * (time.Second / 100))
wrChan <- resp
}
}
func receiver(totalJobs int) {
// waits for msgs from workers
for {
u := <-wrChan
log.Printf("Received %d", u)
// all workers finished, quit
if u == (totalJobs - 1) {
break
}
}
end(initTime, "RECEIVE")
doneReceiving <- true
}
////
// helpers
////
func end(t time.Time, s string) {
elapsed := time.Since(t)
log.Printf("%s took %s", s, elapsed)
}
func moreThanTL(t time.Time) bool {
elapsed := time.Since(t)
if TIME_LIMIT < elapsed {
return true
}
return false
}
func random(min, max int) int {
rand.Seed(time.Now().Unix())
return rand.Intn(max-min) + min
}
@jmingov
Copy link
Author

jmingov commented Jun 4, 2018

i.e: For sending mails with aws respecting the rate limits with golang

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment