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
// just a function (which can be later started as a goroutine)
func doStuff(s string) {
}
func main() {
// using a named function in a goroutine
go doStuff("foobar")
// using an anonymous inner function in a goroutine
go func (x int) {
// function body goes here
}(42)
}
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 (
"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
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()
}