Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about Context chapter #720

Open
JadaTBK opened this issue Dec 13, 2023 · 1 comment
Open

Question about Context chapter #720

JadaTBK opened this issue Dec 13, 2023 · 1 comment

Comments

@JadaTBK
Copy link

JadaTBK commented Dec 13, 2023

I'm working my way through the chapters, and I was curious about how to possibly hit the case in the goroutine with the comment in the snippet below. I tried a handful of things, but whenever the context is cancelled, only the other case for <-ctx.Done() is ever hit. (I changed the log to fmt for simplistic debugging)

I removed the case in the goroutine, and the desired behavior remains the same, so I'm not sure the purpose of it's inclusion if it's not possible to hit it?

Is it protection to prevent the goroutines from continuing to work? If so, then why is it never hit?

Pulled from context/v3/testdoubles.go

// Fetch returns response after a short delay.
func (s *SpyStore) Fetch(ctx context.Context) (string, error) {
	data := make(chan string, 1)

	go func() {
		var result string
		for _, c := range s.response {
			select {
			case <-ctx.Done():
				//How to hit this case?
				log.Println("spy store got cancelled")
				return
			default:
				result += string(c)
			}
		}
		data <- result
	}()

	select {
	case <-ctx.Done():
                //Only ever hits this case
		return "", ctx.Err()
	case res := <-data:
		return res, nil
	}
}

Thank you for the great guide! It's been very helpful for someone who is pretty green on TDD and Go!

@adolfo-cia
Copy link

adolfo-cia commented Feb 1, 2024

I was going to that chapter as well and asked the same thing. It's like the select at the bottom of Fetch function listens the context's done channel first, terminating the goroutine as this no longer runs.

I coded this alernative, not sure if it's ok, but it's working:

func (s *SpyStore) Fetch(ctx context.Context) (string, error) {

	data := make(chan string, 1)
	cancelled := make(chan struct{})

	go func() {
		var result string
		for _, c := range s.response {
			select {
			case <-ctx.Done():
				log.Println("spy store got cancelled")
				cancelled <- struct{}{}
				return
			default:
				time.Sleep(1 * time.Millisecond)
				result += string(c)
				log.Println(result)
			}
		}
		log.Println("writing result to data channel")
		data <- result
	}()

	select {
	case <-cancelled:
		log.Println("cancelled")
		return "", ctx.Err()
	case res := <-data:
		log.Println("data done")
		return res, nil
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants