xxxxxxxxxx
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"sync"
"time"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Username string `json:"username"`
Email string `json:"email"`
}
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
users := PoolNew()
json.NewEncoder(w).Encode(&users)
})
http.ListenAndServe(":3000", nil)
}
func PoolNew() *[]User {
var (
maxOfGorutines int = 1000
wg *sync.WaitGroup = new(sync.WaitGroup)
mutex *sync.Mutex = new(sync.Mutex)
semaphore chan bool = make(chan bool, maxOfGorutines)
users *[]User = new([]User)
)
start := time.Now()
semaphore <- true
wg.Add(1)
go func() {
defer func() {
wg.Done()
<-semaphore
}()
res, err := http.Get("https://jsonplaceholder.typicode.com/users")
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
resByte, err := io.ReadAll(res.Body)
if err != nil {
log.Fatal(err)
}
mutex.Lock()
if err := json.Unmarshal(resByte, &users); err != nil {
log.Fatal(err)
}
mutex.Unlock()
}()
wg.Wait()
fmt.Printf("Total User: %d\n", len(*users))
fmt.Printf("Finish Time: %s\n", time.Since(start))
return users
}
xxxxxxxxxx
func main() {
// A "channel"
ch := make(chan string)
// Start concurrent routines
go push("Moe", ch)
go push("Larry", ch)
go push("Curly", ch)
// Read 3 results
// (Since our goroutines are concurrent,
// the order isn't guaranteed!)
fmt.Println(<-ch, <-ch, <-ch)
}
xxxxxxxxxx
func display() {
// code inside the function
}
// start goroutine
go display()
xxxxxxxxxx
func display() {
// code inside the function
}
// start goroutine
go display()
xxxxxxxxxx
package main
import (
"fmt"
"time"
)
// creating a function
func display(message string) {
fmt.Println(message)
}
func main() {
// calling goroutine
go display("Process 1")
display("Process 2")
}
xxxxxxxxxx
func nextMultiply(ch chan int, wg *sync.WaitGroup) {
defer wg.Done()
if res := <-ch; res == 8 {
fmt.Printf("result -> %d \n", res)
}
}
func multiply(ch chan int, wg *sync.WaitGroup) {
defer wg.Done()
if res := <-ch; res == 4 {
ch <- res * 2
}
}
func main() {
var wg sync.WaitGroup
numberChan := make(chan int)
wg.Add(2)
go nextMultiply(numberChan, &wg)
go multiply(numberChan, &wg)
numberChan <- 2 * 2
defer close(numberChan)
fmt.Println("Waiting for goroutines to finish...")
wg.Wait()
fmt.Println("Done!")
}
xxxxxxxxxx
package main
import (
"encoding/json"
"fmt"
"net/http"
"sync"
"golang.org/x/sync/errgroup"
)
type Users struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
func InternalGorutine() {
var (
usersList []Users = []Users{}
wg *sync.WaitGroup = &sync.WaitGroup{}
errchan chan error = make(chan error)
)
wg.Add(1)
go func() {
wg.Done()
res, err := http.Get("https://jsonplaceholder.typicode.com/users")
if err != nil {
errchan <- err
}
defer res.Body.Close()
if err := json.NewDecoder(res.Body).Decode(&usersList); err != nil {
errchan <- err
}
errchan <- nil
}()
wg.Wait()
if err := <-errchan; err != nil {
panic(err)
}
fmt.Println("InternalGorutine: ", usersList)
}
func ExternalGorutine() {
var (
usersList []Users = []Users{}
erg *errgroup.Group = &errgroup.Group{}
)
erg.Go(func() error {
res, err := http.Get("https://jsonplaceholder.typicode.com/users")
if err != nil {
return nil
}
defer res.Body.Close()
if err := json.NewDecoder(res.Body).Decode(&usersList); err != nil {
return nil
}
return nil
})
if err := erg.Wait(); err != nil {
panic(err)
}
fmt.Println("ExternalGorutine: ", usersList)
}
func main() {
InternalGorutine()
fmt.Printf("\n")
ExternalGorutine()
}
xxxxxxxxxx
package main
import (
"fmt"
"sync"
"time"
)
type User struct {
Name string
Age int
DateOfBirth string
PlaceOfBirth string
}
func main() {
PoolNew()
}
func PoolNew() {
var (
loopCount = 10000000 // 10000000 (10JT) - 100000000 (100JT) - 1000000000 (1M) - 100000000000 (1T)
maxOfGorutines = 1000000
wg sync.WaitGroup
users []User
mutex sync.Mutex
semaphore = make(chan bool, maxOfGorutines)
)
start := time.Now()
for i := 0; i < loopCount; i += maxOfGorutines {
semaphore <- true
wg.Add(1)
go func(startIndex, endIndex int) {
defer func() {
<-semaphore
wg.Done()
}()
for j := startIndex; j < endIndex; j++ {
user := User{
Name: "Jamal Cavalera",
Age: 23,
DateOfBirth: "17 Agustus 2000",
PlaceOfBirth: "Jakarta",
}
mutex.Lock()
users = append(users, user)
mutex.Unlock()
}
}(i, i+maxOfGorutines)
}
wg.Wait()
fmt.Printf("Total User: %d\n", len(users))
fmt.Printf("Finish Time: %s\n", time.Since(start))
}
xxxxxxxxxx
package main
import (
"fmt"
"sync"
)
// GOOD CODE
package main
import (
"fmt"
"sync"
)
func main() {
var (
wg *sync.WaitGroup = new(sync.WaitGroup)
release chan bool = make(chan bool, 1)
received chan string = make(chan string)
)
wg.Add(3)
release <- true
go func(receiveChan chan string, releaseChan chan bool) {
defer wg.Done()
<-releaseChan
receiveChan <- "Hello World 1"
}(received, release)
release <- true
go func(receiveChan chan string, releaseChan chan bool) {
defer wg.Done()
<-releaseChan
data := <-receiveChan
fmt.Println("data 1", data)
receiveChan <- "Hello World 2"
}(received, release)
release <- true
go func(receiveChan chan string, releaseChan chan bool) {
defer wg.Done()
<-releaseChan
data := <-receiveChan
fmt.Println("data 2", data)
}(received, release)
wg.Wait()
}
// WRONG CODE
package main
import (
"fmt"
)
func main() {
var (
release chan bool = make(chan bool, 1)
received chan string = make(chan string)
)
release <- true
go func(receiveChan chan string) {
<-release
receiveChan <- "Hello World 1"
}(received)
release <- true
go func(receiveChan chan string) {
<-release
data := <-receiveChan
fmt.Println("data 1", data)
receiveChan <- "Hello World 2"
}(received)
release <- true
go func(receiveChan chan string) {
<-release
data := <-receiveChan
fmt.Println("data 2", data)
}(received)
}
// WRONG CODE
func main() {
var (
wg *sync.WaitGroup = new(sync.WaitGroup)
received chan string = make(chan string)
)
wg.Add(3)
go func(receiveChan chan string) {
defer wg.Done()
receiveChan <- "Hello World 1"
}(received)
go func(receiveChan chan string) {
defer wg.Done()
data := <-receiveChan
fmt.Println("data 1", data)
receiveChan <- "Hello World 2"
}(received)
go func(receiveChan chan string) {
defer wg.Done()
data := <-receiveChan
fmt.Println("data 2", data)
}(received)
wg.Wait()
}