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

problem with ex9.3 cancelable function memo #12

Open
woofyzhao opened this issue Mar 2, 2019 · 1 comment
Open

problem with ex9.3 cancelable function memo #12

woofyzhao opened this issue Mar 2, 2019 · 1 comment

Comments

@woofyzhao
Copy link

woofyzhao commented Mar 2, 2019

Hi, I believe the specific switch and loop order in the code to deal with the problem of incorrectly canceling of other successive/concurrent requests on the same key you mentioned in comments maybe helps, but not sufficient.

For instance If goroutine A is executing its function then B and C follow up waiting for the ready event on the same key, after a while A cancels its request while B and C can only be left with the canceled result caused by A and have no chance to fix it. This is a problem because the done channel of B or C does not fire a cancel request. The memo server routine does no help in this case.

This may not pose a problem if each same key share the same cancel channel in the request but this is not necessarily true. One way I can think of to deal with it is to check and restart the request again if the result is incorrectly canceled by some previous request on the same key other than its own done channel.

Something like this:

func (memo *Memo) Get(key string, done <-chan struct{}) (interface{}, error) {
        ...
	select {
	case <-done:
		fmt.Println("get: queueing cancellation request")
		memo.cancels <- req
	default:
		// incorrectly canceled result set by others: restart request.
		if res.canceled {
			return Get(key, done)
		}
	}
	...

though it seems possible to cause some live lock problem in theory.

@rmq1992
Copy link

rmq1992 commented Feb 7, 2020

Totally agree !
my code like this, to avoid "Process all cancellations before requests".

select {
case _, ok := <-e.ready:
    if ok {
        memo.requests <- req
    } else {
        response <- e.res
    }
case <-done:
    memo.cancels <- req
}

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