I am trying to wait for a specific condition, and I would like advice as to how this is done best. I have a struct that looks like this (simplified):
type view struct {
timeFrameReached bool
Rows []*sitRow
}
In a goroutine, I am updating a file, which is read into the view
variable. The number of rows increases, and timeFrameReached
will ultimately be true
.
Elsewhere, I want to wait for the following condition to be true:
view.timeFrameReached == true || len(view.Rows) >= numRows
I am trying to learn channels and how Go's condition variables work, and I would like to know what is the best solution here. Theoretically, I could do something trivial like this:
for {
view = getView()
if view.timeFrameReached == true || len(view.Rows) >= numRows {
break
}
}
but that is obviously a naive solution. The value of numRows
comes from an HTTP request, so the condition method seems challenging. The goroutine would not know when to broadcast the condition because it wouldn't know the number of rows it is looking for.
I think I would do this with a condition variable. The concept is not that a
Signal
should only be done when the condition the waiter wants to check is true, but when it might be true (i.e., the things being checked have changed).The normal pattern for doing this is:
Then, in the code where
view
is changed:Obviously, I've written this without knowing how your program works, so you may have to make some changes.
You could do something similar with a channel by sending on the channel to signal and trying to receive from the channel to wait, but that seems more complicated to me. (Also, if you have more than one goroutine waiting, you can signal all of them to wake up using
cond.Broadcast
.)One idea I have involves communicating the needed number of rows via a channel, and the goroutine that is building the view will do a non-blocking receive to see if the main thread is requesting a certain number of rows. If so, it will send a message back to indicate that the condition is met.
Here the
main
function requests a number of rows:Here the goroutine checks if a certain number of rows are required. If so, it responds with an affirmative signal when ready. The value of that signal is inconsequential.