us icon indicating copy to clipboard operation
us copied to clipboard

HostSet.Close forgets releasing locks

Open jkawamoto opened this issue 3 years ago • 5 comments

lh.mu needs to be released.

https://github.com/lukechampine/us/blob/36e1081712379a6af2b3f49ca4aadfb1b1786625/renter/renterutil/hostset.go#L102-L112

jkawamoto avatar Apr 15 '21 03:04 jkawamoto

This was intentional. It prevents the HostSet from being used after Close is called. Is this causing problems?

lukechampine avatar Apr 15 '21 15:04 lukechampine

Yes. It blocks the goroutine in acquireCtx.

jkawamoto avatar Apr 15 '21 16:04 jkawamoto

It's also not a good idea to block goroutines to prevent the HostSet from being used after Close is called. Users are hard to find the problem. It should return a proper error instead.

jkawamoto avatar Apr 15 '21 17:04 jkawamoto

I wrote it this way to catch developer errors, and it did: calling acquire after calling Closeshould be a developer error. I agree that deadlocking isn't ideal, but it was very simple to implement and was guaranteed to work. Anyway, now we have acquireCtx, whose goroutine outlives its parent, so we can't treat it as a developer error anymore. Maybe eventually I'll fix acquireCtx and then I can turn this into a panic instead.

lukechampine avatar Apr 16 '21 01:04 lukechampine

Even if it's a developer error, how do people know there is an error? They need a core dump to find there is a goroutine that tries to acquire a session after HostSet is closed. Such a goroutine never returns, and you might expect people can find it. However, in reality, if a goroutine doesn't return for a long time, the upper context times out or gets cancelled, and the whole application keeps running. As a result, people cannot know there is a goroutine waiting for a lock.

panic isn't also a good idea. panic should be used only for unrecoverable run-time errors: https://golang.org/doc/effective_go#panic. If this is a developer error, it simply should return an error. They say

Real library functions should avoid panic. If the problem can be masked or worked around, it's always better to let things continue to run rather than taking down the whole program.

Actually, how can we avoid acquiring sessions after the host set is closed? Ideally, we need to check if all corresponding goroutines finish before closing the host set. But, it's not practical. For example, we don't know when the goroutine in acquireCtx ends. Another solution would be to add a reference counter and close the host set only if the counter becomes zero. But, such a counter should be implemented in HostSet if necessary.

I think simply returning an error is enough in this case.

jkawamoto avatar Apr 16 '21 05:04 jkawamoto