QtCS2024 QFuture/QPromise

From Qt Wiki
Jump to navigation Jump to search

Session Summary

In the scope of Qt OPC UA¹, which is inherently asynchronous, we’re investigating the use of QFuture/QPromise to make the APIs more convenient.

This discussion session is about setting standards for QFuture/QPromise-based APIs throughout Qt to ensure consistent naming and error handling before their use within Qt expands further.

¹) OPC Unified Architecture (OPC UA) is a cross-platform, open-source, IEC62541 standard for data exchange from sensors to cloud applications

Session Owners

Kai Uwe Broulik <kai.uwe.broulik@basyskom.com>

Notes

  • should be discussed hand in hand with the discussion on error handling
    • QFuture needs to be evolved
  • overhead: can we as a library afford the futures (or should this remain a privilege of the users of the library s.a. QFuture::connect()).
    • would like to see rough benchmarking how much memory/qobjects are allocated.

Feedback from Qt WebEngine / Alan

  • QFuture is not worth it in context of Web Engine, they just use callbacks

Solutions for the naming

  • use the same name but overload (without context object/callback for example)
  • “async” or “future” postfix (addNode vs addNodeFuture)
  • OpcUaClientFuture as a special class wouldn’t work

Issues

  • waitForFinished API trap,
    • might deadlock if future is executed in the same thread, std::future wait similarly bad
  • How to have methods that throw exceptions in the context of a continuation and do other error handling in the context of normal usage?
  • QPermission API originally had QFuture-based interface but was refactored to use callback.

Discussion

https://codereview.qt-project.org/c/qt/qtopcua/+/570819

  • Naming, connectToHostAsync, connectToHost2, …
    • particularly when retrofitting
  • Error handling
    • canceled future, exception?
  • throw vs setException
    • what if I have a function that I want to be usable both from a continuation and not

Co-Routines

The elephant in the room ;)

How do we avoid yet another “new style API” when Co-routines come around? Can we make existing QFuture awaitable?

https://qcoro.dvratil.cz/

Other ideas

  • Async QMimeData / Clipboard
  • Async file IO
    • In general many Qt APIs are convenient and innocent-looking and then block your program because it’s all synchronous

Precedent (pretty much exhaustive)

qtbase

  • runOnAndroidMainThread
  • requestPermission in QtAndroidPrivate »Requests the permission and returns a QFuture representing the result of the request.« Does this mean it gets fulfilled and cancelled when not?

qtdeclarative

  • QQmlXmlListModelQueryRunnable::future

qtmultimedia

  • QFFmpegMediaPlayer::m_loadMedia
  • QGstreamerImageCapture::m_pendingFutures from saveBufferToImage
  • QQnxImageCapture::decodeFrame

qttools

  • QHelpEngineCore::requestContentForCurrentFilter with QFuture<std::shared_ptr<QHelpContentItem>>