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

Add a NamedHandler, as well as the ability to remove handlers by their name. #47

Merged
merged 11 commits into from
Sep 2, 2023

Conversation

PaulSonOfLars
Copy link
Owner

@PaulSonOfLars PaulSonOfLars commented May 2, 2022

What

Add a NamedHandler handler, which wraps existing handlers and exposes a stable name to remove them by.

With that, add methods to remove handlers.

And finally... Add some tests to make sure they all work as expected!

Impact

  • Are your changes backwards compatible? Yes
  • Have you included documentation, or updated existing documentation? Yes
  • Do errors and log messages provide enough context? N/A

@celestix
Copy link
Contributor

celestix commented May 10, 2022

💕 UwU

Nice! I've finally got some stuff to play with once my exams get over 😀

@PaulSonOfLars
Copy link
Owner Author

I've put this on hold for now, because I'm not satisfied with the fact these methods aren't thread-safe.

On the other hand, I'm also not a fan of putting everything behind a RWMutex - I worry this would slow down update processing for many, when only a select few actually need to remove handlers.

In my mind, if you need to "remove" handlers, you should use a custom handler and build logic into the CheckUpdate methods to skip handlers which are "disabled", rather than actually remove them and risk concurrency issues. Difficult choices :)

Let me know here if you have any thoughts!

@ALiwoto
Copy link
Contributor

ALiwoto commented Jan 6, 2023

@PaulSonOfLars you are right, this way it does have costs for both people who want the feature, and the ones who don't.
So how about adding a boolean field to config when we want to create the bot value then? 🤔

A boolean config var indicating whether the user wants the feature to be enabled or not; how does it sound like?
Those who want it, will accept the fact that a RWMutex is being used ( == slower update proccessing, remove handlers feature); but those who don't, simply won't suffer from it.

Let me know if this idea (or something like this) can solve the problem or not! (or, if there is a main problem behind it, other than this)

@PaulSonOfLars
Copy link
Owner Author

So how about adding a boolean field to config when we want to create the bot value then? 🤔

A boolean config var indicating whether the user wants the feature to be enabled or not; how does it sound like? Those who want it, will accept the fact that a RWMutex is being used ( == slower update proccessing, remove handlers feature); but those who don't, simply won't suffer from it.

I had a think about this, and the reason I didn't go with it is because that really smells of poorly designed code 😅 And would make it much easier to accidentally forget to use the right locks in the future.

I see another option; make the Dispatcher an interface, and implement it twice. One has removals and mutexes, and the other doesn't. All it needs are Start(...) and Stop() methods. Even allows for others to implement their own if they want to get their hands dirty!

What do you think?

@ALiwoto
Copy link
Contributor

ALiwoto commented Jan 6, 2023

@PaulSonOfLars wow this sounds like a really really good option!
Not even it will fix out our current problem, but it will give end-users way way more flexibility by allowing them to even design their own dispatcher!
I totally agree with this way :)

@vassilit
Copy link
Contributor

vassilit commented Jan 7, 2023

RWMutex - I worry this would slow down [...]
make the Dispatcher an interface

Converting to an interface will induce some overhead (allocation).

Also, there are alternatives to RWMutexes:

  • atomic.Value (see the two examples): read are fast, write are very slow (must copy the entire map)
  • sync.Mutex: if read contention is low, Mutex.Lock() is faster than RWMutex.RLock()
  • sync.Map: if read contention is very high, might be faster than sync.RWMutex

@PaulSonOfLars PaulSonOfLars force-pushed the paul/removing-handlers branch 3 times, most recently from 34f3202 to 276e400 Compare August 23, 2023 14:28
Copy link

@rusq rusq left a comment

Choose a reason for hiding this comment

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

LGTM


// Only one item left, so just delete the group entirely.
if len(currHandlers) == 1 {
m.handlerGroups = append(m.handlerGroups[:group], m.handlerGroups[group+1:]...)
Copy link

Choose a reason for hiding this comment

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

Maybe, once the lib is updated to go1.21, the delete element operations could be replaced with https://pkg.go.dev/slices#Delete. Easy to make a fatal slip with these 😂

This one seems fine, no fatal slips.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Absolutely agree - I was also uncertain about the thread safety of this, but the writemutex should ensure that we don't hit any weirdness here. Will wait a couple of months before moving to 1.21 and will make sure to add this when we do :)

continue
}

m.handlerGroups = append(m.handlerGroups[:j], m.handlerGroups[j+1:]...)
Copy link

Choose a reason for hiding this comment

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

I always feel uneasy when I have to modify the slice I'm iterating on. But I guess in this case it's ok, as you're returning immediately.

@PaulSonOfLars PaulSonOfLars merged commit f87f4f7 into v2 Sep 2, 2023
3 checks passed
@PaulSonOfLars PaulSonOfLars deleted the paul/removing-handlers branch September 2, 2023 15:12
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.

None yet

5 participants