Я совершенно новичок в Go, только учусь (в данный момент я играю с каналами и занимаюсь рутиной, я пытаюсь понять координацию).Я застрял с проблемой.
Я не понимаю, что происходит за кулисами, когда я начинаю 2 идти рутины.ServiceAlpha отвечает за установку тактового импульса на ServiceBeta и за смерть, если он получает событие прерывания на канале прерывания. ServiceBeta отвечает за запись какой-то глупой строки в мой вывод журнала, и у него есть TTL (он исходит от serviceAlpha), поэтому, если он не получает пульс вВремя TTL должно завершить свою работу и вернуться к своему вызывающему, но перед выходом должно выдать какое-либо событие abort ServiceAlpha на канале abort
Моя проблема Я не понимаю, почему он продолжает работать после TTL и
вывод выглядит следующим образом:
2019/04/28 17:21:44 Main | START
2019/04/28 17:21:44 serviceBeta | START
2019/04/28 17:21:44 serviceAlpha | START
2019/04/28 17:21:44 serviceAlpha | There was not abort
2019/04/28 17:21:44 serviceAlpha | rand = 3
2019/04/28 17:21:45 serviceBeta | TICKER: 2019-04-28 17:21:45.2870594 +0200 CEST m=+1.003883901
2019/04/28 17:21:46 serviceBeta | TICKER: 2019-04-28 17:21:46.2867957 +0200 CEST m=+2.003620201
2019/04/28 17:21:47 serviceBeta | TICKER: 2019-04-28 17:21:47.2866242 +0200 CEST m=+3.003448701
2019/04/28 17:21:47 serviceAlpha | There was not abort
2019/04/28 17:21:47 serviceAlpha | rand = 5
2019/04/28 17:21:48 serviceBeta | TICKER: 2019-04-28 17:21:48.2869918 +0200 CEST m=+4.003816301
2019/04/28 17:21:49 serviceBeta | TICKER: 2019-04-28 17:21:49.2863265 +0200 CEST m=+5.003151001
2019/04/28 17:21:50 serviceBeta | TICKER: 2019-04-28 17:21:50.2868071 +0200 CEST m=+6.003631601
2019/04/28 17:21:51 serviceBeta | TICKER: 2019-04-28 17:21:51.2866738 +0200 CEST m=+7.003498301
2019/04/28 17:21:51 serviceBeta | ABORT 2019-04-28 17:21:51.2866738 +0200 CEST m=+7.003498301
Keeps running...
missing serviceBeta: STOP
and ServiceAlpha,and Main also
Я почти уверен, что есть много проблем с этим кодом, поэтому мои вопросы - В чем проблема в этом дизайне?:) - Как правильно его кодировать?
Буду признателен за любую помощь!
Дарви
package main
import (
"log"
rand2 "math/rand"
"sync"
"time"
)
func main() {
log.Println("Main | START")
var wg sync.WaitGroup
var resetTTL = make(chan interface{})
var abort = make(chan interface{})
defer func() {
log.Println("Main | defer closing channels")
close(resetTTL)
close(abort)
}()
wg.Add(1)
go serviceAlpha(1, 5, resetTTL, abort, &wg)
wg.Add(1)
go serviceBeta(4*time.Second, resetTTL, abort, &wg)
wg.Wait()
log.Println("Main | STOP")
}
func serviceAlpha(min, max int, ttlReset chan<- interface{}, abort <-chan interface{}, wg *sync.WaitGroup) {
log.Println("serviceAlpha | START")
var randTTL int
loop:
for {
select {
case <-abort:
log.Println("serviceAlpha | There was an abort, breaking from loop")
break loop
default:
log.Println("serviceAlpha | There was not abort")
break
}
randTTL = rand2.Intn(max-min) + min + 1
log.Printf("serviceAlpha | rand = %v", randTTL)
time.Sleep(time.Duration(randTTL) * time.Second)
ttlReset <- true
}
log.Println("serviceAlpha | STOP")
wg.Done()
}
func serviceBeta(ttl time.Duration, ttlReset <-chan interface{}, abort chan<- interface{}, wg *sync.WaitGroup) {
log.Println("serviceBeta | START")
var ttlTimer = time.NewTimer(ttl)
var tickerTimer = time.NewTicker(1 * time.Second)
loop:
for {
select {
case <-ttlReset:
ttlTimer.Stop()
ttlTimer.Reset(ttl)
case tt := <-tickerTimer.C:
log.Println("serviceBeta | TICKER: ", tt)
case ttl := <-ttlTimer.C:
log.Println("serviceBeta | ABORT", ttl)
break loop
}
}
abort <- true
log.Println("serviceBeta | STOP")
wg.Done()
}