[Golang] Make a coffee with go routine
Lại một năm mới đến, ban đã viết ra những kế hoạch, điều minh mong muốn chưa hè ? Hay vẫn còn tiếc nuối những gì chưa hoàn thành trong năm trước. Còn nếu bạn đã hoành thành năm 2022 một cách rực rỡ thì wow, ta cạn chai này
Và dù bạn ở trong trường hợp nào, thì mình vẫn xin mời bạn một ly cà phê. Một ly cà phê có thể có một chút đắng nhẹ trong vòm miệng đâu đó khoảng vài mươi giây và đi nhẹ qua cuống họng bạn với một vị ngọt thanh. Nó sẽ giống như những bước đi của bạn. Tất nhiên, sẽ có một chút gian nan nhưng không sao, sau cùng ta cũng sẽ về la mã. Không để bạn chờ lâu nữa, tôi đi làm coffee ngay đây.
1. Lời tựa
- Goroutine là gì ? Một khái niệm đầy đủ chính xác thì các bạn có thể coi ở đây go_tour. Năm mới, để nhẹ đầu thì các bạn cứ hiểu nôm na là các function/method được thi một cách độc lập và đồng thời. Nghĩa là, trong 1 đoạn block code, ban call 2 function A, B thì 2 function đó được chạy một cách (gần như) đồng thời, không ai phải đợi ai, mỗi người một cuộc sống riêng.
go A() // use 'go' keyword to start 1 goroutine or start run this function asynchronously
go B()
- Công thức pha cà phê:
- Boil water
- Prepare coffee into the filter(phin coffee)
- Press coffee
- Put the boiled water into the filter
- Wait in some seconds
- Enjoy
- Những điều trăn trở và cách giải quyết:
- Để các bạn không phải đơi lâu, trong quá trình đun sôi tôi phải chuẩn bị coffee vào phin và nén nó thật chăt trước. Sau đó nước vừa sôi, thì tôi phải đổ vào phin ngay. Vì thế, tôi sẽ đặt 3 job - "Boil water, Prepare coffee into the filter, Press coffee" được thưc hiện một cách cùng lúc (async job group) và những job còn lại sẽ được thực hiện 1 cách tuần tự (synchronous job group).
- Để chắc chắn rằng, nhóm async job được chạy trước, tôi sẽ dùng WaitGroup. Nó là một kỹ thuật giúp ta block chương trình lai và đơi một nhóm go routine chạy xong.
- Ngoài ra, tôi muốn "Boil water" job được thực thi ngay khi call bởi vì đun sôi nước là công việc lâu nhất. Nghĩa là, tôi sẽ phải can thiệp quyền chọn go routine nào sẽ chạy thay vì để golang runtime quyết định. Và giải pháp ở đây là "Gosched function" của runtime package, goroutine will be scheduled for running after that.
2. Make a coffee
Simple job
/* coffee/coffee.go */
var delayForSwitchJob = time.Second * 3
func DoAJob(action string, duration time.Duration) {
time.Sleep(delayForSwitchJob)
fmt.Printf("%v: %v \n", time.Now().Format("02-Jan-2006 15:04:05"), action)
time.Sleep(duration)
}
BoilingWaterJob
/* coffee/coffee.go */
var completeBoilingWater = false
func BoilingWaterJob(duration time.Duration) {
fmt.Printf("%v: %v \n", time.Now().Format("02-Jan-2006 15:04:05"), "Boil water")
time.Sleep(duration)
completeBoilingWater = true
fmt.Printf("%v: %v \n", time.Now().Format("02-Jan-2006 15:04:05"), "Ring! Ring! Ring! Completing boiling water ...")
}
Scheduling Job
/* coffee/coffee.go */
func MakeASimpleCupOfCoffee() {
/*
** Asynchronous
** Wait 3 jobs: "Boil water", "Prepare coffee into the filter", "Press coffee"
**
*/
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
BoilingWaterJob(time.Second * 60)
runtime.Gosched()
}()
go func() {
defer wg.Done()
DoAJob("Prepare coffee into the filter", time.Second*15)
DoAJob("Press coffee", time.Second*10)
}()
wg.Wait()
/* Synchronous */
if completeBoilingWater {
DoAJob("Put the boiled water into the filter", time.Second*5)
DoAJob("Wait in some seconds ...", time.Second*60)
fmt.Printf("%v: %v \n", time.Now().Format("02-Jan-2006 15:04:05"), "Enjoy ...")
}
}
Build coffee
main.go
func main() {
go coffee.MakeASimpleCupOfCoffee()
/* Wait a cup of coffee is made*/
time.Sleep(time.Second * 150)
}
Running in console and enjoy a coffee
3. Vài lời sau cuối
- Một lần nữa rất cám ơn bạn đã kiên nhẫn đã đọc tới đây. 😝😝 Về mặt technical thì mình biết cũng ko có gì ghê gớm lắm. Nếu bạn là một người khó tính và đòi hỏi một ly coffee ngon hơn, may be coffee của chúng ta nên được build trên một async job system với đầy đủ feature hơn. Tuy nhiên, ly coffee này của mình được ra đời trong quá trình mình tiếp cận go routine và mình muốn moi thứ thật simple giống như cái tên của nó.
- Đầu năm mới, chúc bạn thật nhiều sức khoẻ và thành công nhé.
- Source code
All rights reserved