@cenkalti 
1. use lock, but might be tricky(the function will be called sometimes already got the lock, sometimes without the lock). 
2. Instead of directly call the cancel function, send the cancellation message to the watchHub. And let the watchHub receive the message and do the removal. In this way, all the snyc related stuff can be done inside the package itself. But you have to do the select default to avoid the deadlock.