how to Clean Code in asynchronous programs. Helge Betzinger CTO - - PowerPoint PPT Presentation

how to clean code in
SMART_READER_LITE
LIVE PREVIEW

how to Clean Code in asynchronous programs. Helge Betzinger CTO - - PowerPoint PPT Presentation

Developer Days 2014 Write Event-based programs again sequentially or how to Clean Code in asynchronous programs. Helge Betzinger CTO pcvisit Software AG Developer Age genda da Days 2014 What is the problem and how to escape?


slide-1
SLIDE 1 Developer Days 2014

Write Event-based programs again sequentially

  • r

how to Clean Code in asynchronous programs.

Helge Betzinger CTO pcvisit Software AG

slide-2
SLIDE 2 Developer Days 2014

Age genda da

  • What is the problem and how to escape?
  • coasync4cpp let you program TODAY without

callbacks!

  • Where to go from here?
  • No more Callbacks!
slide-3
SLIDE 3 Developer Days 2014

A typical requirement for a application these days…

What is is the prob

  • blem

em and how to to escap cape?

If the user clicks the button, than replace the image within his clipboard by a URL with a copy of this image within the cloud.

slide-4
SLIDE 4 Developer Days 2014

A A typic ical al requir irement ement for a a applic icati ation

  • n these days…

What is is the prob

  • blem

em and how to to escap cape?

If the user clicks the button, than replace the image within his clipboard by a URL with a copy of this image within the cloud.

please wait for the next slide clicking won’t make it come any faster

slide-5
SLIDE 5 Developer Days 2014

A A typic ical al requir irement ement for a a applic icati ation

  • n these days…

What is the problem and how to escape?

If the user clicks the button, than replace the image within his clipboard by a URL with a copy of this image within the cloud. The UI must stay responsive all the time.

slide-6
SLIDE 6 Developer Days 2014

What is the problem and how to escape?

Async becoming the norm!

slide-7
SLIDE 7 Developer Days 2014
slide-8
SLIDE 8 Developer Days 2014

Example: Concurrent waiting with signals

void MainView::uploadImageFromFile(const QString &filePath) { QJsonObject object; // configure object … EnginioReply *reply = mModel->append(object); connect( reply, &EnginioReply::finished, this, &MainView::beginUpload); } void MainView::beginUpload(EnginioReply *reply) { reply->deleteLater(); // use result/reply here .. } 1) Manage the control flow of the application 3) Business logic related code 2) Manage resources of the infrastructure

slide-9
SLIDE 9 Developer Days 2014

Example: Concurrent waiting with futures

File saveCliprdToDisk(); std::future<File> f = std::async(saveCliprdToDisk); f.get() ; // this blocks, until saveCliprdToDisk is done! // even the destructor of std::future blocks!

C++11

slide-10
SLIDE 10 Developer Days 2014

Example: Concurrent waiting with boost

boost::future<File> f = boost::async(saveCliprdToDisk); f.then( [] (boost:: future<File> savedF ) { // use result.get() here ... uploadImage( savedF.get()).then( [=] (future<Reply> uploadedFile) { requestUrl (uploadedFile.get()).then( ... ); } ); });

C++ standard proposal N3558, Boost.Thread 1.55.0

slide-11
SLIDE 11 Developer Days 2014

What is the problem and how to escape?

And what about Clean Code?

slide-12
SLIDE 12 Developer Days 2014

And what about Clean Code?

slide-13
SLIDE 13 Developer Days 2014
slide-14
SLIDE 14 Developer Days 2014

… how to escape?

Document number: N3721 Date: 2013-08-30 Reply-to: Niklas Gustafsson <niklas.gustafsson@microsoft.com> Artur Laksberg <arturl@microsoft.com> Herb Sutter <hsutter@microsoft.com> Sana Mithani <sanam@microsoft.com>

Improvements to std::future<T> and Related APIs

slide-15
SLIDE 15 Developer Days 2014

What is the problem and how to escape?

coasync4cpp let you do asynchronous programming without callbacks

slide-16
SLIDE 16 Developer Days 2014

Coasync4cpp - How it works

File saveCliprdToDisk(); std::future<File> f = std::async(saveCliprdToDisk); File f = f.get() ; // this blocks, until saveCliprdToDisk is done! File f = Task( boost::async( saveCliprdToDisk )); File f = await Task( boost::async( saveCliprdToDisk )); File f = await boost::async( saveCliprdToDisk );

slide-17
SLIDE 17 Developer Days 2014

Coasync4cpp - How it works

File saveCliprdToDisk(); std::future<File> f = std::async(saveCliprdToDisk); File f = f.get() ; // this blocks, until saveCliprdToDisk is done! File f = Task( boost::async( saveCliprdToDisk )); File f = await Task( boost::async( saveCliprdToDisk )); File f = await boost::async( saveCliprdToDisk );

slide-18
SLIDE 18 Developer Days 2014

Overview coasync4cpp

T ask<…>

Wrap around a awaitable to make code simpler Allows to use Task/await within a routine

slide-19
SLIDE 19 Developer Days 2014

Overview coasync4cpp

await

Unwraps value of a given awaitable without blocking your thread

slide-20
SLIDE 20 Developer Days 2014

bindAsTask(void Button_Click()) {

QUrl url = await clip2UrlAsync ());

url2clip(url); } Task<QUrl> clip2UrlAsync () { … return Task<QUrl>(); }

Click

Unde dersta stand ndin ing g async Tasks ks

Message Pump with TaskDispatcher

T ask

Url available..

slide-21
SLIDE 21 Developer Days 2014

Example using await

Button.connect( bindAsTask( &MainView::convertIntoUrl, this )); File saveCliprdToDisk(); QNetworkReply * uploadImage ( File ); QNetworkReply * requestUrl ( QNetworkReply * ); void put2clipboard(Qurl); void convertIntoUrl() { File tmpFile = await boost::async( saveCliprdToDisk()); QNetworkReply * uploadedFile = await uploadImage( tmpFile ); QNetworkReply * fileUrl = await ( requestUrl, uploadedFile ); put2clipboard( fileUrl->result()); }

slide-22
SLIDE 22 Developer Days 2014

Example using Task

Button.connect( bindAsTask( &MainView::convertIntoUrl, this )); Task<File> saveCliprdToDiskAsync(); Task<QNetworkReply * > uploadImageAsync( File ); Task<QUrl> requestUrlAsync(QNetworkReply * ); void put2clipboard(QUrl); void convertIntoUrl() { auto tmpFile = saveCliprdToDiskAsync(); auto uploadedFile = uploadImageAsync( tmpFile ); auto fileUrl = requestUrlAsync( uploadedFile ); put2clipboard(fileUrl); }

slide-23
SLIDE 23 Developer Days 2014

Task<> await

Task Factories Awaitables Task Dispatcher

creates from methods awaits empowers

slide-24
SLIDE 24 Developer Days 2014

Task Factories

make_task

Creates an Task<R> from anything, that is callable Starts the method immediatelly

bindAsT ask

Creates an std::function< Task<R> (…) > from anything, that is callable Start the method later, with invocation of the function object

slide-25
SLIDE 25 Developer Days 2014

Task Factories

taskify

auto taskify( method, placeholders::CALLBACK, Args…)

  • > Task< std::tuple< P… > > ;

Starts the method immediatelly Transforms the callback into an awaitable Task

Returns a Task with a std::tuple, containing the parameters of the CALLBACK. method can be anything, that is callable CALLBACK must be a function object. placeholders::EXCEPTION also supported

slide-26
SLIDE 26 Developer Days 2014

Awaitables

T ask<…> boost::future<R>

Operation is already running await directly Store and await later Create a Task from it and get result or await later

slide-27
SLIDE 27 Developer Days 2014

Helper: TaskDispatcher

T askDispatcher4StdThread T askDispatcher4QtThread ThreadWithT asks

Creates an dispatcher for Tasks within current thread or creates a new thread with a dispatcher in it Prerequisite to get Task<> working within a particallary thread!

slide-28
SLIDE 28 Developer Days 2014

Summary Usage

1. Instanciate suitable T askDispatcher in your thread 2. Call async method as T ask, using a T ask Factory 3. Use await/T ask with any Awaitable within this method

slide-29
SLIDE 29 Developer Days 2014

Example using Task

Button.connect( bindAsTask( &MainView::convertIntoUrl, this )); Task<File> saveCliprdToDiskAsync(); Task<QNetworkReply * > uploadImageAsync( File ); Task<QUrl> requestUrlAsync(QNetworkReply * ); void put2clipboard(QUrl); void convertIntoUrl() { auto tmpFile = saveCliprdToDiskAsync(); auto uploadedFile = uploadImageAsync( tmpFile ); auto fileUrl = requestUrlAsync( uploadedFile ); put2clipboard(fileUrl); }

slide-30
SLIDE 30 Developer Days 2014

What is the problem and how to escape?

coasync4cpp makes consuming async APIs simple

slide-31
SLIDE 31 Developer Days 2014

What is the problem and how to escape?

Where to go from here?

slide-32
SLIDE 32 Developer Days 2014

Where to go from here?

Play around with testcoasync4cpp and testcoasync4qt to understand

https://github.com/helgebetzinger/coasync4cpp

slide-33
SLIDE 33 Developer Days 2014

coasync4cpp

https://github.com/helgebetzinger/coasync4cpp

coasync4cpp coasync4qt

testcoasync4cpp testcoasync4qt

utilize test test

Googletest

Google C++ Testing Framwork

coroutine; threading depends on depends on

slide-34
SLIDE 34 Developer Days 2014

What can you expect from version 0.10?

Simple integration with legacy code

https://github.com/helgebetzinger/coasync4cpp

slide-35
SLIDE 35 Developer Days 2014

What can you expect from version 0.10?

More Awaitables

QFuture* QNetworkReply* EnginioReply*

More T ask Factories

taskifyQtSignal

More Msg-Dispatchers

https://github.com/helgebetzinger/coasync4cpp

slide-36
SLIDE 36 Developer Days 2014

What can you expect from version 0.10?

Extended build support

clang, cmake

https://github.com/helgebetzinger/coasync4cpp

slide-37
SLIDE 37 Developer Days 2014

What is the problem and how to escape? coasync4cpp@pcvisit.com https://github.com/helgebetzinger/coasync4cpp

Watch the project and stay tuned Comment and report issues and requirements Contribute added features

  • r fixed bugs
slide-38
SLIDE 38 Developer Days 2014

What is the problem and how to escape?

No more callbacks! Questions?

coasync4cpp@pcvisit.com https://github.com/helgebetzinger/coasync4cpp

slide-39
SLIDE 39 Developer Days 2014

What is the problem and how to escape? coasync4cpp@pcvisit.com https://github.com/helgebetzinger/coasync4cpp

slide-40
SLIDE 40 Developer Days 2014

What is the problem and how to escape?

Best Practices for App- developers

slide-41
SLIDE 41 Developer Days 2014

Future themes

Using it with legacy code Extension Points (Awaitables, T askDispatcher) Best Practices Interplay between sync and async code Async API Exception Subscribe the project on github Comment on feature request or bugs (instead of voting ;-)

slide-42
SLIDE 42 Developer Days 2014

Exceptions

Exceptions

slide-43
SLIDE 43 Developer Days 2014

Best Practices

Cannot await top level

slide-44
SLIDE 44 Developer Days 2014

Best Practices

Maximize parallelism for I/O bound work

slide-45
SLIDE 45 Developer Days 2014

Best Practices

Library methods should not lie

slide-46
SLIDE 46 Developer Days 2014

Best Practices

If your async void method has side effects, return T ask<void> anyway

slide-47
SLIDE 47 Developer Days 2014

Best Practices

Convert Signals into T asks

slide-48
SLIDE 48 Developer Days 2014

Best Practices

T ake care

  • f your locks!
slide-49
SLIDE 49 Developer Days 2014

Best Practices

Is it CPU Bound

  • r I/O Bound?
slide-50
SLIDE 50 Developer Days 2014

What is the problem and how to escape?

Archive

slide-51
SLIDE 51 Developer Days 2014

Task Factories

make_task taskify bindAsT ask

Creates an Task from anything, that is callable, an callback , event or signal. Starts the method immediatelly or later Adds an separate stack to your routine

slide-52
SLIDE 52 Developer Days 2014

Overview coasync4cpp

make_task

“makes your method asynchronous” lets you put awaits and Tasks in it

slide-53
SLIDE 53 Developer Days 2014

Helpers

bind2current bind2thread

slide-54
SLIDE 54 Developer Days 2014

Example: Concurrent waiting with QFutureWatcher

File saveCliprdToDisk(); QFuture<File> qfuture = QtConcurrent::run(saveCliprdToDisk); auto watcher = new QFutureWatcher<File>(); QObject::connect( watcher, &QFutureWatcherBase::finished, [=] { // use watcher->result() here ... watcher->deleteLater(); }); watcher->setFuture(qfuture);

slide-55
SLIDE 55 Developer Days 2014

Awaitables

T ask<R> boost::future<R>

Operation is already running await directly Store and await later Create a Task from it and get result or await later

slide-56
SLIDE 56 Developer Days 2014

Awaitables

QFuture* QNetworkReply* (impl. using taskifyQtSignal) EnginioReply* (impl. using taskifyQtSignal)

Operation is already running await directly Store and await later Create a Task from it and get result or await later

slide-57
SLIDE 57 Developer Days 2014

Task Factories

taskifyQtSignal

auto taskifyQtSignal( R(Args…), obj )

  • > Task< std::tuple< Args… > > ;

Starts an task immediatelly or later explicit Returns a Task with a std::tuple, containing the parameters of the signal.

slide-58
SLIDE 58 Developer Days 2014

coasync4cpp

https://github.com/helgebetzinger/coasync4cpp

Requirements design coasync4cpp library

  • Solve the problem!
  • Applicable on Legacy Code / Brownfield Code
  • Preferably Compatible with upcoming C++ Developments C++1xx
  • don’t hide the interfaces of used future implementation to prevent lock out of

existing tools around them

  • Enhancements points for smooth integration with other libraries, as Qt
slide-59
SLIDE 59 Developer Days 2014

What is the problem and how to escape? coasync4cpp@pcvisit.com https://github.com/helgebetzinger/coasync4cpp