Skip to content

Avoid race condition in lazy dispatch registration#9545

Merged
jrbourbeau merged 2 commits intodask:mainfrom
jrbourbeau:dispatch-race
Oct 14, 2022
Merged

Avoid race condition in lazy dispatch registration#9545
jrbourbeau merged 2 commits intodask:mainfrom
jrbourbeau:dispatch-race

Conversation

@jrbourbeau
Copy link
Copy Markdown
Member

@jrbourbeau jrbourbeau commented Oct 5, 2022

This makes it so we delete the toplevel entry from the _lazy lookup dictionary only after we're registered the corresponding dispatch method

Closes #9181, closes dask/distributed#7061

Copy link
Copy Markdown
Member Author

@jrbourbeau jrbourbeau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zklaus I'm curious if this fixes the issue you were encountering

@zklaus
Copy link
Copy Markdown

zklaus commented Oct 6, 2022

I'll give it a try and get back to you.

Co-authored-by: Klaus Zimmermann <klaus.zimmermann@smhi.se>
Comment on lines 625 to +631
try:
register = self._lazy.pop(toplevel)
register = self._lazy[toplevel]
except KeyError:
pass
else:
register()
self._lazy.pop(toplevel, None)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonder if we could actually simplify this a bit

Suggested change
try:
register = self._lazy.pop(toplevel)
register = self._lazy[toplevel]
except KeyError:
pass
else:
register()
self._lazy.pop(toplevel, None)
register = self._lazy.get(toplevel)
if register is not None:
register()
self._lazy.pop(toplevel, None)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though I agree this suggestion is equivalent to the current state of this PR, I actually find the try/except to be a bit more clear as catching a KeyError is more explicit in saying "this thing doesn't have this key" than get + is not None (as there could be a key with a value of None). Regardless, this isn't a big deal either way. If this is a blocking comment, then I'm happy to update accordingly.

Copy link
Copy Markdown
Member

@jakirkham jakirkham Oct 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are other ways to do this if we don't want to rely on None (though I don't know how None would work as an intentional value given we need to call it like a function later, which would break).

Suggested change
try:
register = self._lazy.pop(toplevel)
register = self._lazy[toplevel]
except KeyError:
pass
else:
register()
self._lazy.pop(toplevel, None)
missing = object()
register = self._lazy.get(toplevel, missing)
if register is not missing:
register()
self._lazy.pop(toplevel, None)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but I still find the try/except KeyError: more clear over defining a separate missing object. Again, this is a subjective point and probably not a big deal either way. Is this update needed to get this PR in? If so, happy to update

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No I don't think it matters. Have just been bitten by unexpected else behavior in try clauses. This combined with the race condition was what motivated the attempt to simplify. That said, given the existing code works for users, would prefer getting the fix in.

@jrbourbeau
Copy link
Copy Markdown
Member Author

Thanks for trying this out @zklaus and for reviewing @jakirkham

@jrbourbeau jrbourbeau merged commit 107a042 into dask:main Oct 14, 2022
@jrbourbeau jrbourbeau deleted the dispatch-race branch October 14, 2022 02:43
@jakirkham
Copy link
Copy Markdown
Member

Thanks for working on this James! 🙏

@zklaus zklaus mentioned this pull request Oct 14, 2022
3 tasks
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

Successfully merging this pull request may close these issues.

No dispatch for <class 'numpy.ndarray'> Possible race condition in dask.utils:Dispatch.dispatch

3 participants