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

PollingControlProxy #1717

Merged
merged 2 commits into from
Jul 31, 2022
Merged

PollingControlProxy #1717

merged 2 commits into from
Jul 31, 2022

Conversation

daschuer
Copy link
Member

@daschuer daschuer commented Jun 20, 2018

This is a light weight version of ControlProxy, not inheriting QObject.
It can be used whenever no signals are required and the value is polled.

I wan't to use it to replace ControlObject::getControl, which returns an unsave pointer that can become invalid during shut down and lead to a crash.

The new object is finally just a PIMPL smart pointer and should not be much more expensive compared to ControlObject::getControl

This is now on top of #4229

@Be-ing Be-ing added this to the 2.3.0 milestone Jun 23, 2018
@rryan
Copy link
Member

rryan commented Sep 30, 2018

can ControlProxy inherit ControlProxyLt to prevent the code duplication?

@daschuer
Copy link
Member Author

Yes, I have not done it to avoid double inheritance. Should I change it?

@daschuer
Copy link
Member Author

@rryan can we merge this as it is?

@daschuer
Copy link
Member Author

I have just tried to inherit ControlProxy from ControlProxyLt, but that does not work well, because the inherited functions are slots in ControlProxy, so we need to override them anyway. This feels like clutter.

@Be-ing Be-ing modified the milestones: 2.3.0, 2.4.0 Feb 7, 2019
@daschuer
Copy link
Member Author

Now it is even more improved by using a default CO instead of all the null checks.

@Be-ing
Copy link
Contributor

Be-ing commented Nov 26, 2019

Can you elaborate on the use case for this class? What advantage does it have over ControlProxy? I think it would help demonstrate if you modified some existing code to use this new class.

@daschuer
Copy link
Member Author

Yes I can do. I had already a branch that unfortunately does not merge anymore.
daschuer@368e5fc

The main use case was to document "I will not receive Value Change Signals".
The side effect is that this class will be optimized almost entirely away by the compiler.
It is useful to replace the control object pointer passing in the engine.
In theory it should also speed up Mixxx start ... negligible.

After the refactoring we will have a clear view which CO needs to receive a signal from the engine.

@Be-ing
Copy link
Contributor

Be-ing commented Nov 27, 2019

What is the importance of not receiving signals? The ControlDoublePrivate still must emit the valueChanged signal.

@daschuer
Copy link
Member Author

Yes, it is mainly a refactoring for readability.

I am planning to remove QT's signal slot connections from the engine and therefore it is nice to know which object actually receives signals.

The main driver was to deprecate ControlObject::getControl(). Passing a control objects around is insafe and block further refactorings.
However this is difficult, because using this omits the signals from the owner. All proxies are signaled but not the owner.

Later I realized that the Lt variant allows to simplify memory management a lot and saves some CPU cycles.

@Holzhaus
Copy link
Member

Can we use a more descriptive name? To me it's not immediately apparent what ControlProxyLt does. Maybe PollingControlProxy?

@daschuer
Copy link
Member Author

Ok.

@uklotzde
Copy link
Contributor

uklotzde commented Nov 28, 2019

ADC'19 Recordings:
Real-time 101 - Part I: Investigating the real-time problem space
Real-time 101 - Part II: The real-time audio developer’s toolbox

@daschuer
Copy link
Member Author

Thank you for the videos. I hope I find time to watch them completely at the weekend.

Is this PR Ok so far?
I am considering to swap the names to
ControlProxy and ControlWatcher, but this will add hundreds of new changed lines.

If you agree to the approach I would like to merge this with the preliminary name and do just the renaming in a separate PR.

What do you think?

@Be-ing
Copy link
Contributor

Be-ing commented Nov 28, 2019

I don't think "ControlWatcher" quite fits because that implies it is read only.

@daschuer
Copy link
Member Author

Alternatives?

I like to emphersise that one receives updates and the other not.

Later we may create one, that is connected to the cue out of the engine thread or alternatively automatically check for the source thread and use the queue or not.

@daschuer
Copy link
Member Author

PollingControlProxy works ok for me, however the other one can also poll and it is also not read only.

@Holzhaus
Copy link
Member

Some ideas:

  • PollingControlProxy
  • NonReceivingControlProxy
  • ControlProxyWithoutSignals
  • SlotOnlyControlProxy
  • ManualControlProxy

@daschuer
Copy link
Member Author

daschuer commented Dec 1, 2019

Benchmarks for 1000 default constructed objects lifetime (create and destroy):
88 ms ControlProxyLt on stack
190 ms ControlProxyLt on heap
295 ms ControlProxy on stack
399 ms ControlProxy on heap manual delete
499 ms ControlProxy on heap with parent
617 ms ControlProxy on heap with parent and manual delete

I think we can learn a bit from this:

  • Don't use parented QObjects if not required
  • Don't manually delete parented QObjects manually
  • Avoid heap construction (new())

By the way: Mixxx has 64209 different CO objects and many proxy objects for each of it.

@github-actions
Copy link

This PR is marked as stale because it has been open 90 days with no activity.

@github-actions github-actions bot added the stale Stale issues that haven't been updated for a long time. label Oct 20, 2020
@Be-ing Be-ing changed the base branch from master to main October 23, 2020 23:50
@ronso0 ronso0 marked this pull request as draft November 20, 2020 10:21
@daschuer daschuer force-pushed the controlproxylt branch 2 times, most recently from 689e8dd to 2eb2d62 Compare December 16, 2020 07:55
@daschuer daschuer force-pushed the controlproxylt branch 2 times, most recently from e495f30 to 5eb0bd2 Compare December 16, 2020 11:57
@daschuer daschuer mentioned this pull request Aug 19, 2021
@daschuer daschuer changed the title ControlProxyLt PollingControlProxy Aug 19, 2021
@daschuer daschuer removed the stale Stale issues that haven't been updated for a long time. label Aug 19, 2021
@daschuer daschuer requested a review from Holzhaus August 19, 2021 08:00
@daschuer daschuer marked this pull request as ready for review August 19, 2021 08:01
@daschuer daschuer force-pushed the controlproxylt branch 2 times, most recently from 3b697cd to e9a3807 Compare August 19, 2021 15:37
@coveralls
Copy link

coveralls commented Aug 19, 2021

Pull Request Test Coverage Report for Build 1152198391

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • 9 unchanged lines in 1 file lost coverage.
  • Overall coverage decreased (-0.01%) to 25.949%

Files with Coverage Reduction New Missed Lines %
src/engine/cachingreader/cachingreader.cpp 9 71.38%
Totals Coverage Status
Change from base Build 1152021735: -0.01%
Covered Lines: 19993
Relevant Lines: 77047

💛 - Coveralls

@daschuer daschuer force-pushed the controlproxylt branch 3 times, most recently from bad9b60 to 43df092 Compare August 20, 2021 16:06
@daschuer
Copy link
Member Author

@Holzhaus this is ready to review/merge now. I think this can be a perfect base class for your ControlFramePosProxy()
In this case a PollingControlFramePosProxy() in #4227

@Holzhaus
Copy link
Member

Holzhaus commented Sep 2, 2021

Thanks, this looks okay to me. Could you add it to some locations where no signals are needed? Then we could benchmark the startup time to check if it's worth it.

@daschuer
Copy link
Member Author

daschuer commented Sep 7, 2021

I have already checked it and the is a performance benefit but it is negligible, compared to other log runners during start up.

The main driver for this was the documentation purpose. If we use that everywhere it is possible, we have a clear picture what to do to fix unsafe pointer access and the Qt locking issue when receiving updates.

@Be-ing Be-ing removed this from the 2.4.0 milestone Nov 14, 2021
@ferranpujolcamins
Copy link
Contributor

LGTM. I too would like to get rid of Control::getControl.

@daschuer
Copy link
Member Author

Thank you for review, and the positive responds :-)
Merge?

@Swiftb0y Swiftb0y merged commit 085a961 into mixxxdj:main Jul 31, 2022
@daschuer daschuer deleted the controlproxylt branch October 12, 2022 12:05
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.

8 participants