-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Event queue compressing proxy #4566
Conversation
6a40aae
to
7178182
Compare
…of superseded events. Use it in ControlObjectScript Implemented a unit test which tests the compressing behavior in ControlObjectScript
7178182
to
6d74436
Compare
2.) Added missing = default to deconstructor 3.) Renamed symbols of CompressingProxy more descriptive 4.) Added a text as comment, that explains how the recursive search works 5.) Fixed typos in comments
fc54e0b
to
a972322
Compare
@daschuer wrote:
I also thought about this. Such race conditions occur already nowadays. For example, if you use a function like engine.getValue, inside of a mapping function connected to an event. Than you don't know how long the event was already in the queue and how old this value is. The likelihood of these race conditions should be lower with this PR, because the events are not so long in the queue. I aggree that now a slightly different kind of race conditions can occur, but only if the event queue is filled with multiple events from the same CO but different values, and when the mapping relies on the new value of another CO event, which is in the queue at the same time. |
Changed the return type to a new self descriptive enumeration
Yes you are probably right. In the case of the engine -> controller connection, I cannot think of a condition where such race condition is a problem. However the engine.getValue() issue cannot be compared, because it is the call to get the current value. When you subscribe the change event you expect to receive ALL changes. From this it would be feel better to have this feature conditional. |
914cc0e
to
5391bc8
Compare
Use of std::unique_ptr
0dcbed4
to
7a0e616
Compare
Improved testcase
f229d91
to
684ef36
Compare
Please don't comment each and every change. This causes many disturbing e-mail notifications. Mark the comments as resolved and request re-review when done. |
@uklotzde Ok, I will resolve single changes without unecesarry comment in future! Sorry for spamming you! |
Code seems to be valid now. Not sure if the changed behavior could break controller scripts? |
Yes the code is OK. However I am unsure about the implications. In general I think this is a good solution and would like to merge this after we have clarified them. On one Hand this PR keep Mixxx going in a live situation by "just continuing". We assume that the issues due this PR re less important than the stalled controller, or a message cue overflow. I agree to that. On the other hand this is almost like the famous vba:
Once this code is committed we have no chance to recognize this cue overload situation and fix the root cause, the inefficient mapping. @JoergAtGithub Do you have a controller mapping where this code will take action regularly? Do you think it is a good idea to print debug messages in developer mode if this happens? Did you consider my comment #4566 (comment) |
73eff01
to
4245bb8
Compare
Added warning in case of skipping superseded events
b328620
to
9eab7d9
Compare
I implemented warnings, which reports when event compressing was done. I expect this occurs in the same way for other controls, which I don't use in my mapping - but only controls which are repeated in high rate are relevant here. Maybe a whitelist of control keys could be implemented and used in ControlObjectScript::addScriptConnection, to decide when the compressing proxy should be connected. Important to notice is, that a mapping developer might never see these warnings, if his computer is fast enough. But other users of the mapping might expirience an unusable lagging Mixxx (without this PR), with the same mapping. |
…e additional boolean argument skipSuperseded as true, to enable it. In case of multiple callback functions connected to the same CO, with contradicting state for skipSuperseded, the CompressingProxy will be disabled and an warning message is printed.
aba7730
to
4e48be0
Compare
I added an optional argument to the function makeConnection, that needs to be set to true, to enable the compressing proxy.
I will create a follow-up PR to mass-edit the makeConnections for the critical COs VuMeter, VuMeterL, VuMeterR and beat_active in all JS controller mappings. None of these COs should be used for application logic under normal circumstances. |
Wow, now this feature is complete, right? Thank you for going the extra mile. |
Yes, I think everything is done now! |
The code looks good. Just an idea: Maybe you should consider to replace the anonymous bool parameter by an overload function: |
I can do! |
… with additional argument
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much! LGTM
@JoergAtGithub Can you write up some docs on how and when to use the new method? |
@Swiftb0y I can do, but where? The closest place I found is this section: |
Ideally the Wiki, but that is currently read-only for non-coreteam-accounts because of spammers. I'd propose to just open a PR with a markdown file and we'll review that and then instead of merging, I'll copy it to where it belongs in the wiki. |
Ideally we'd have proper documentation how to create JavaScript controller mappings in our manual and reserve the wiki for stuff that is not directly related to Mixxx (e.g. How to set up your IDE, etc.) 😁 |
This PR implements a event queue compressing proxy, which skips the processing of superseded events. This is used in ControlObjectScript.
The PR also contains a unit test which checks the compressing behavior in ControlObjectScript.
What does this compressor solve:
-The compressor prevents unresponsive controllers in CPU overload conditions, when more signals are send from Mixxx, than the mapping can handle. This occurs with complex controllers (with many connected COs) and a not so powerful computer. Especially with signals that appear in high rate, like VU-Meter, Beat indication or Play position.
Behavior without this PR:
-Events are queued and processed as fast as the mapping (or the controller hardware) can
-Status LEDs on controler show oudated states from the queue
-Because controller input and output are handled in the same mapping thread. In overload conditions the mapping also queue the processing of the events send from the controller to the mapping.
Behavior with this PR:
-As long as no CPU overload occurs everything behaves as before
-When an CPU overload occurs, the compressing proxy recursive parse the event Qt event queue vor signals of the same connection. In case of multiple events only the latest is send to the JavaScript callback function in the mapping.
-Therefore status LEDs show always the latest state, and no superseded states from the event queue
-The input is not directly affected, but due to the limited load for the mapping thread, there is always time to process the input events and there are no noticeable delays anymore, between pressing a button and the response of Mixxx.