SlideShare a Scribd company logo
1 of 63
Download to read offline
Asynchronous, yet readable, code
Kamil Witecki
November 16, 2016
Subject of discussion
(a) Callbacks
Subject of discussion
(a) Callbacks
(b) Promises
Subject of discussion
(a) Callbacks
(b) Promises
(c) Coroutines
Callbacks
Callbacks are simple but lacking. Do not use them.
Promises
Promises bring more control and structure to our code.
Coroutines
Coroutines provide best possible results and are our choice.
Writing code is easy
You write what you have on mind. And understand it.
https://en.wikipedia.org/wiki/Scribe#/media/File:Escribano.jpg
Maintenance is hell
https://en.wikipedia.org/wiki/Scribe#/media/File:Escribano.jpg [1]
Example
//avoid allocating temporary int
void countZeros ( std : : vector <void∗>& a , int ∗ out )
{
out = 0;
for ( auto i = begin ( a ) ; i != end ( a ) ; ++i ) {
i f (!∗ i ) ++out ;
}
}
Example
//avoid allocating temporary int
void countZeros ( std : : vector <void∗>& a , int ∗ out )
{
out = 0;
for ( auto i = begin ( a ) ; i != end ( a ) ; ++i ) {
i f (!∗ i ) ++out ;
}
}
template<typename Container >
auto c o u n t n u l l p t r s ( Container const& cont ) −>
std : : s i z e t
{
return count ( begin ( cont ) , end ( cont ) , n u l l p t r ) ;
}
Area of interest - asynchronous programming
Synchronous
Your code
Other code
Eg. kernel
Idle
Start operation
Complete operation
Start operation
Complete operation
Executes
other code
Operation results
wait for processing
Asynchronous
Your code
Other code
Eg. kernel
Case study: conversation I
We will focus on a example like:
e(d(c(b(a(params)))))
What in synchronous code gets as simple as:
e (d( c (b( a ( params ) ) ) ) )
Or:
resultFromA = a ( params )
resultFromB = b( resultFromA )
resultFromC = c ( resultFromB )
resultFromD = d( resultFromC )
resultFromE = e ( resultFromD )
Case study: conversation II
Case study: flow control
Next we will be looking into code that reads two files and compares content:
a = io.open ( ’a.txt’)
a data = a : read ( ’a’)
b = io.open ( ’b.txt’)
b data = b : read ( ’a’)
compare ( a data , b data )
Case study: debugging
Last but not least - we will be checking how errors are manifested.
Approach #1: callback
C++:
void r e a d h a n d l e r ( e r r o r c o d e const& ec ,
s i z e t bytes ) { . . . }
read ( . . . , r e a d h a n d l e r ) ;
Lua:
function r e a d h a n d l e r ( data ) end
socket : on ("data" , r e a d h a n d l e r )
JavaScript:
function r e a d h a n d l e r ( data ) {}
socket . on ("data" , r e a d h a n d l e r ) ;
Approach #1: pitfall
a ( params , function ( resultFromA , e r r )
i f ( ! e r r ) then return end
b( resultFromA , function ( resultFromB , e r r )
i f ( ! e r r ) then return end
c ( resultFromB , function ( resultFromC , e r r )
i f ( ! e r r ) then return end
d( resultFromC , function ( resultFromD , e r r )
i f ( ! e r r ) then return end
e ( resultFromD , function ( resultFromE , e r r )
// . .
end)
end)
end)
end)
end)
Approach #1: phony solution
a ( params , HandleResultsOfA ) ;
HandleResultsOfA ( resultFromA , e r r ) {
i f ( ! e r r ) return ;
b( resultFromA , HandleResultsOfB ) ;
}
HandleResultsOfB ( resultFromB , e r r ) {
i f ( ! e r r ) return ;
c ( resultFromB , HandleResultsOfC ) ;
}
HandleResultsOfC ( resultFromC , e r r ) {
i f ( ! e r r ) return ;
d( resultFromC , HandleResultsOfD ) ;
}
HandleResultsOfD ( resultFromD , e r r ) {
i f ( ! e r r ) return ;
Approach #1: how I see it
Approach #1: debugging I
1 f s . s t a t ("1.txt" , function () {
2 f s . s t a t ("2.txt" , function () {
3 //obvious error
4 f s . s t a t ( function (){} , function () {})
5 })
6 })
Approach #1: debugging II
Result is ok, error can be easily spotted:
>node t e s t . j s
f s . j s :783
binding . s t a t ( pathModule . makeLong ( path ) , req ) ;
ˆ
TypeError : path must be a s t r i n g
at TypeError ( n a t i v e )
at Object . f s . s t a t ( f s . j s :783:11)
at t e s t . j s : 4 : 8
at FSReqWrap . oncomplete ( f s . j s : 9 5 : 1 5 )
test.js:4 is:
f s . s t a t ( function (){} , function () {})
Approach #1: say goodbye to your stacktrace I
What if we use same function in multiple places?
1 var f s = r e q u i r e ( ’fs’ ) ;
2 function bug ( content , cont ) {
3 f s . w r i t e F i l e ("config.json" , content ,
4 function () { f s . s t a t ("config.json" , cont ) ;
5 } ) ;
6 }
7
8 bug ("{}" , "wrong")
Approach #1: say goodbye to your stacktrace II
Result:
>node t e s t . j s
throw new TypeError ( ’ c a l l b a c k must be a function ’ ) ;
TypeError : c a l l b a c k must be a f u n c t i o n
at makeCallback ( f s . j s : 7 8 : 1 1 )
at Object . f s . s t a t ( f s . j s :826:14)
at t e s t . j s : 4 : 2 0
at FSReqWrap . oncomplete ( f s . j s : 8 2 : 1 5 )
test.js:4 is:
function () { f s . s t a t ("config.json" , cont ) ;
While there error is in test.js:8:
bug ("{}" , "wrong")
Approach #1: What?
Approach #1: pros and cons
Pros
Easy to use,
Approach #1: pros and cons
Pros
Easy to use,
Integrated by default
Approach #1: pros and cons
Pros
Easy to use,
Integrated by default
Approach #1: pros and cons
Pros
Easy to use,
Integrated by default
Cons
Degrades to callback hell quickly
Approach #1: pros and cons
Pros
Easy to use,
Integrated by default
Cons
Degrades to callback hell quickly
Makes stacktraces unusable
Approach #1: pros and cons
Pros
Easy to use,
Integrated by default
Cons
Degrades to callback hell quickly
Makes stacktraces unusable
Does not address more complex flow control scenarios
Approach #1: pros and cons
Pros
Easy to use,
Integrated by default
Cons
Degrades to callback hell quickly
Makes stacktraces unusable
Does not address more complex flow control scenarios
Approach #1: pros and cons
Pros
Easy to use,
Integrated by default
Cons
Degrades to callback hell quickly
Makes stacktraces unusable
Does not address more complex flow control scenarios
Approach #2: Promises
Abstract model of asynchronous computation results.
Pending
.then(fulfillCallback,...)
.then(…, rejectCallback)
.catch()
Resolved
Rejected
Cancelled
OnValue
OnError
OnCancel
OnValue
OnError
(no actions)
(action)
(recovery)
(no recovery)
Approach #2: Case study I
Do you remember callback hell?
a ( params , function ( resultFromA , e r r )
i f ( ! e r r ) then return end
b( resultFromA , function ( resultFromB , e r r )
i f ( ! e r r ) then return end
c ( resultFromB , function ( resultFromC , e r r )
i f ( ! e r r ) then return end
d( resultFromC , function ( resultFromD , e r r )
i f ( ! e r r ) then return end
e ( resultFromD , function ( resultFromE , e r r )
// . .
end)
end)
end)
end)
end)
Approach #2: Case study II
Promises let you write it following way:
a ( params )
: next ( function ( resultFromA )
return b( resultFromA ) end)
: next ( function ( resultFromB )
return c ( resultFromB ) end)
: next ( function ( resultFromC )
return d( resultFromC ) end)
: next ( function ( resultFromD )
. . . end) .
Approach #2: Case study III
With a bit of imagination you can read it as:
a ( params )
--:next(function(resultFromA) return
b( resultFromA ) -- end)
--:next(function(resultFromB) return
c ( resultFromB ) -- end)
--:next(function(resultFromC) return
d( resultFromC ) -- end)
--:next(function(resultFromD)
. . . --end)
Approach #2: flow control
Promises are abstract model of computation. Therefore it is possible to build
flow control with them. For example:
c(a(paramsOfA), b(paramsOfB))
becomes:
l o c a l a = f s . readAsync ("a.txt")
l o c a l b = f s . readAsync ("b.txt")
d e f e r r e d . a l l ({a , b } ) : next ( function ( r e s u l t s )
return c ( r e s u l t s [ 0 ] , r e s u l t s [ 1 ] )
end )
Approach #2: What about callstacks? I
1 var Promise = r e q u i r e ("bluebird" ) ;
2 var f s = r e q u i r e ( ’fs’ ) ;
3 Promise . p r o m i s i f y A l l ( f s ) ;
4 function b( f i l e ) {return function ()
5 {return f s . statAsync ( f i l e )}}
6 f s . statAsync ("1.txt")
7 . then (b("2.txt" ))
8 . then (b( undefined ))
Approach #2: It’s a trap!
1 var Promise = r e q u i r e ("bluebird" ) ;
2 var f s = r e q u i r e ( ’fs’ ) ;
3 Promise . p r o m i s i f y A l l ( f s ) ;
4 function b( f i l e ) {return function ()
5 {return f s . statAsync ( f i l e )}}
6 f s . statAsync ("1.txt")
7 . then (b("2.txt" ))
8 . then (b( undefined ))
Approach #2: What about callstacks? II
Still not so good:
Unhandled r e j e c t i o n TypeError : path must be a s t r i n g
at TypeError ( n a t i v e )
at Object . f s . s t a t ( f s . j s : 7 8 3 : 1 1 )
at Object . t r y C a t c h e r ( node modules b l u e b i r d  j s  r e l e a s e  u t i l . j s : 1 6 : 2 3 )
at Object . r e t [ as statAsync ] ( e v a l at <anonymous> ( node modules b l u e b i r d  j s  r e l e a s e  p r o m i s i f y . j s : 1 8 4 : 1 2 ) , <a
at t e s t . j s : 5 : 1 3
at t r y C a t c h e r ( node modules b l u e b i r d  j s  r e l e a s e  u t i l . j s : 1 6 : 2 3 )
at Promise . settlePromiseFromHandler ( node modules b l u e b i r d  j s  r e l e a s e promise . j s : 5 0 9 : 3 1 )
at Promise . s e t t l e P r o m i s e ( node modules b l u e b i r d  j s  r e l e a s e promise . j s : 5 6 6 : 1 8 )
at Promise . s e t t l e P r o m i s e 0 ( node modules b l u e b i r d  j s  r e l e a s e promise . j s : 6 1 1 : 1 0 )
at Promise . s e t t l e P r o m i s e s ( node modules b l u e b i r d  j s  r e l e a s e promise . j s : 6 9 0 : 1 8 )
at Promise . f u l f i l l ( node modules b l u e b i r d  j s  r e l e a s e promise . j s : 6 3 5 : 1 8 )
at node modules b l u e b i r d  j s  r e l e a s e nodeback . j s : 4 2 : 2 1
at FSReqWrap . oncomplete ( f s . j s : 9 5 : 1 5 )
test.js:4-5
function b( f i l e ) { return function ()
{ return f s . statAsync ( f i l e )}}
Approach #2: pros and cons
Pros
Code structure and business logic are more coherent,
Approach #2: pros and cons
Pros
Code structure and business logic are more coherent,
Provide abstraction of flow control
Approach #2: pros and cons
Pros
Code structure and business logic are more coherent,
Provide abstraction of flow control
Approach #2: pros and cons
Pros
Code structure and business logic are more coherent,
Provide abstraction of flow control
Cons
Some boiler plate still needed for each call
Approach #2: pros and cons
Pros
Code structure and business logic are more coherent,
Provide abstraction of flow control
Cons
Some boiler plate still needed for each call
Makes stacktraces unusable
Approach #2: pros and cons
Pros
Code structure and business logic are more coherent,
Provide abstraction of flow control
Cons
Some boiler plate still needed for each call
Makes stacktraces unusable
Approach #2: pros and cons
Pros
Code structure and business logic are more coherent,
Provide abstraction of flow control
Cons
Some boiler plate still needed for each call
Makes stacktraces unusable
Approach #3: Coroutines
http://www.boost.org/doc/libs/1 60 0/libs/coroutine/doc/html/coroutine/intro.html [2]
Approach #3: Case study I
We will look, again, at e(d(c(b(a(params))))), now with coroutines!
coroutine.wrap ( function ()
resultFromA = a ( params )
resultFromB = b( resultFromA )
resultFromC = c ( resultFromB )
resultFromD = d( resultFromC )
resultFromE = e ( resultFromD )
end ) ( )
Approach #3: flow control
Coroutines allow to build flow control with them, too. For example:
c(a(paramsOfA), b(paramsOfB))
becomes:
coroutine.wrap ( function ()
a , b = c o r o s p l i t (
function () return f s. re ad As yn c ( ’a.txt’) end ,
function () return f s. re ad As yn c ( ’b.txt’) end)
c (a , b)
end ) ( )
Approach #3: What about callstacks? I
1 local f s = require ’coro-fs’
2 function bug ()
3 f s . s t a t ("2.txt")
4 return f s . s t a t ( function () print "x" end)
5 end
6 coroutine.wrap ( function () xpcall ( function ()
7 f s . s t a t ("1.txt")
8 bug ()
9 end ,
10 function ( e ) print ( debug.traceback ( e ) ) ; return e end)
11 end ) ( )
Approach #3: What about callstacks? II
> l u v i t . exe c o r o u t i n e s . lua
deps / coro−f s . lua : 4 4 : bad argument #1 to ’ f s s t a t ’
( s t r i n g expected , got f u n c t i o n )
stack traceback :
t e s t . lua : 1 0 : in f u n c t i o n <t e s t . lua :10>
[C ] : in f u n c t i o n ’ f s s t a t ’
deps / coro−f s . lua : 4 4 : in f u n c t i o n ’ bug ’
t e s t . lua : 4 : in f u n c t i o n ’ bug ’
t e s t . lua : 8 : in f u n c t i o n <t e s t . lua :6>
[C ] : in f u n c t i o n ’ x p c a l l ’
t e s t . lua : 6 : in f u n c t i o n <t e s t . lua :6>
coroutines.lua:6,8
coroutine.wrap ( function () xpcall ( function ()
bug ()
Approach #3: pros and cons
Pros
Resembles synchronous code,
Approach #3: pros and cons
Pros
Resembles synchronous code,
Provide abstraction of flow control,
Approach #3: pros and cons
Pros
Resembles synchronous code,
Provide abstraction of flow control,
Keeps stack untouched!
Approach #3: pros and cons
Pros
Resembles synchronous code,
Provide abstraction of flow control,
Keeps stack untouched!
Approach #3: pros and cons
Pros
Resembles synchronous code,
Provide abstraction of flow control,
Keeps stack untouched!
Cons
Some boiler plate still needed for each flow
Approach #3: pros and cons
Pros
Resembles synchronous code,
Provide abstraction of flow control,
Keeps stack untouched!
Cons
Some boiler plate still needed for each flow
Summary
(a) Callbacks
(b) Promises
(c) Coroutines
And the winner is!
Coroutine
Question and Answers
Bibliograpy I
B. Fisher.
Indiana jones and the temple of doom.
https://www.flickr.com/photos/7thstreettheatre/16587334520, 2015.
Cropped out ticket and release details. See licence:
https://creativecommons.org/licenses/by/2.0/ (Attribution 2.0 Generic (CC
BY 2.0)).
Oliver Kowalke.
http://www.boost.org/doc/libs/1 61 0/libs/coroutine/doc/html/coroutine/intro.ht
Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE 1 0.txt or copy at
http://www.boost.org/LICENSE 1 0.txt).

More Related Content

What's hot

C Sharp Jn (3)
C Sharp Jn (3)C Sharp Jn (3)
C Sharp Jn (3)
jahanullah
 
Network lab manual
Network lab manualNetwork lab manual
Network lab manual
Prabhu D
 
Network lap pgms 7th semester
Network lap pgms 7th semesterNetwork lap pgms 7th semester
Network lap pgms 7th semester
DOSONKA Group
 
Unit 5
Unit 5Unit 5
Unit 5
siddr
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for Dummies
Elizabeth Smith
 
Hacking Go Compiler Internals / GoCon 2014 Autumn
Hacking Go Compiler Internals / GoCon 2014 AutumnHacking Go Compiler Internals / GoCon 2014 Autumn
Hacking Go Compiler Internals / GoCon 2014 Autumn
Moriyoshi Koizumi
 

What's hot (20)

The bytecode hocus pocus - JavaOne 2016
The bytecode hocus pocus - JavaOne 2016The bytecode hocus pocus - JavaOne 2016
The bytecode hocus pocus - JavaOne 2016
 
The bytecode mumbo-jumbo
The bytecode mumbo-jumboThe bytecode mumbo-jumbo
The bytecode mumbo-jumbo
 
C Sharp Jn (3)
C Sharp Jn (3)C Sharp Jn (3)
C Sharp Jn (3)
 
clang-intro
clang-introclang-intro
clang-intro
 
Network lab manual
Network lab manualNetwork lab manual
Network lab manual
 
Loops
LoopsLoops
Loops
 
Network lap pgms 7th semester
Network lap pgms 7th semesterNetwork lap pgms 7th semester
Network lap pgms 7th semester
 
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
 
Unit 5
Unit 5Unit 5
Unit 5
 
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for Dummies
 
CODEsign 2015
CODEsign 2015CODEsign 2015
CODEsign 2015
 
Hacking Go Compiler Internals / GoCon 2014 Autumn
Hacking Go Compiler Internals / GoCon 2014 AutumnHacking Go Compiler Internals / GoCon 2014 Autumn
Hacking Go Compiler Internals / GoCon 2014 Autumn
 
C++ idioms.pptx
C++ idioms.pptxC++ idioms.pptx
C++ idioms.pptx
 
Empty Base Class Optimisation, [[no_unique_address]] and other C++20 Attributes
Empty Base Class Optimisation, [[no_unique_address]] and other C++20 AttributesEmpty Base Class Optimisation, [[no_unique_address]] and other C++20 Attributes
Empty Base Class Optimisation, [[no_unique_address]] and other C++20 Attributes
 
One definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим житьOne definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим жить
 
Understand more about C
Understand more about CUnderstand more about C
Understand more about C
 
Tiramisu概要
Tiramisu概要Tiramisu概要
Tiramisu概要
 
Code GPU with CUDA - Applying optimization techniques
Code GPU with CUDA - Applying optimization techniquesCode GPU with CUDA - Applying optimization techniques
Code GPU with CUDA - Applying optimization techniques
 
C++ programming
C++ programmingC++ programming
C++ programming
 

Similar to Kamil witecki asynchronous, yet readable, code

COMM 166 Final Research Proposal GuidelinesThe proposal should.docx
COMM 166 Final Research Proposal GuidelinesThe proposal should.docxCOMM 166 Final Research Proposal GuidelinesThe proposal should.docx
COMM 166 Final Research Proposal GuidelinesThe proposal should.docx
cargillfilberto
 
COMM 166 Final Research Proposal GuidelinesThe proposal should.docx
COMM 166 Final Research Proposal GuidelinesThe proposal should.docxCOMM 166 Final Research Proposal GuidelinesThe proposal should.docx
COMM 166 Final Research Proposal GuidelinesThe proposal should.docx
drandy1
 
COMM 166 Final Research Proposal GuidelinesThe proposal should.docx
COMM 166 Final Research Proposal GuidelinesThe proposal should.docxCOMM 166 Final Research Proposal GuidelinesThe proposal should.docx
COMM 166 Final Research Proposal GuidelinesThe proposal should.docx
monicafrancis71118
 

Similar to Kamil witecki asynchronous, yet readable, code (20)

golang_getting_started.pptx
golang_getting_started.pptxgolang_getting_started.pptx
golang_getting_started.pptx
 
C Programming Homework Help
C Programming Homework HelpC Programming Homework Help
C Programming Homework Help
 
C programming language tutorial
C programming language tutorial C programming language tutorial
C programming language tutorial
 
Subtle Asynchrony by Jeff Hammond
Subtle Asynchrony by Jeff HammondSubtle Asynchrony by Jeff Hammond
Subtle Asynchrony by Jeff Hammond
 
Introduction to Compiler Development
Introduction to Compiler DevelopmentIntroduction to Compiler Development
Introduction to Compiler Development
 
Introduction to source{d} Engine and source{d} Lookout
Introduction to source{d} Engine and source{d} Lookout Introduction to source{d} Engine and source{d} Lookout
Introduction to source{d} Engine and source{d} Lookout
 
Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoGo 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX Go
 
C Programming Language Tutorial for beginners - JavaTpoint
C Programming Language Tutorial for beginners - JavaTpointC Programming Language Tutorial for beginners - JavaTpoint
C Programming Language Tutorial for beginners - JavaTpoint
 
Building resilient services in go
Building resilient services in goBuilding resilient services in go
Building resilient services in go
 
A CTF Hackers Toolbox
A CTF Hackers ToolboxA CTF Hackers Toolbox
A CTF Hackers Toolbox
 
Rooted 2010 ppp
Rooted 2010 pppRooted 2010 ppp
Rooted 2010 ppp
 
COMM 166 Final Research Proposal GuidelinesThe proposal should.docx
COMM 166 Final Research Proposal GuidelinesThe proposal should.docxCOMM 166 Final Research Proposal GuidelinesThe proposal should.docx
COMM 166 Final Research Proposal GuidelinesThe proposal should.docx
 
COMM 166 Final Research Proposal GuidelinesThe proposal should.docx
COMM 166 Final Research Proposal GuidelinesThe proposal should.docxCOMM 166 Final Research Proposal GuidelinesThe proposal should.docx
COMM 166 Final Research Proposal GuidelinesThe proposal should.docx
 
COMM 166 Final Research Proposal GuidelinesThe proposal should.docx
COMM 166 Final Research Proposal GuidelinesThe proposal should.docxCOMM 166 Final Research Proposal GuidelinesThe proposal should.docx
COMM 166 Final Research Proposal GuidelinesThe proposal should.docx
 
C Programming Interview Questions
C Programming Interview QuestionsC Programming Interview Questions
C Programming Interview Questions
 
7 functions
7  functions7  functions
7 functions
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
Go Says WAT?
Go Says WAT?Go Says WAT?
Go Says WAT?
 
Being functional in PHP (PHPDay Italy 2016)
Being functional in PHP (PHPDay Italy 2016)Being functional in PHP (PHPDay Italy 2016)
Being functional in PHP (PHPDay Italy 2016)
 
Writing Macros
Writing MacrosWriting Macros
Writing Macros
 

Recently uploaded

%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 

Recently uploaded (20)

Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 

Kamil witecki asynchronous, yet readable, code

  • 1. Asynchronous, yet readable, code Kamil Witecki November 16, 2016
  • 3. Subject of discussion (a) Callbacks (b) Promises
  • 4. Subject of discussion (a) Callbacks (b) Promises (c) Coroutines
  • 5. Callbacks Callbacks are simple but lacking. Do not use them.
  • 6. Promises Promises bring more control and structure to our code.
  • 7. Coroutines Coroutines provide best possible results and are our choice.
  • 8. Writing code is easy You write what you have on mind. And understand it. https://en.wikipedia.org/wiki/Scribe#/media/File:Escribano.jpg
  • 10. Example //avoid allocating temporary int void countZeros ( std : : vector <void∗>& a , int ∗ out ) { out = 0; for ( auto i = begin ( a ) ; i != end ( a ) ; ++i ) { i f (!∗ i ) ++out ; } }
  • 11. Example //avoid allocating temporary int void countZeros ( std : : vector <void∗>& a , int ∗ out ) { out = 0; for ( auto i = begin ( a ) ; i != end ( a ) ; ++i ) { i f (!∗ i ) ++out ; } } template<typename Container > auto c o u n t n u l l p t r s ( Container const& cont ) −> std : : s i z e t { return count ( begin ( cont ) , end ( cont ) , n u l l p t r ) ; }
  • 12. Area of interest - asynchronous programming Synchronous Your code Other code Eg. kernel Idle Start operation Complete operation Start operation Complete operation Executes other code Operation results wait for processing Asynchronous Your code Other code Eg. kernel
  • 13. Case study: conversation I We will focus on a example like: e(d(c(b(a(params))))) What in synchronous code gets as simple as: e (d( c (b( a ( params ) ) ) ) ) Or: resultFromA = a ( params ) resultFromB = b( resultFromA ) resultFromC = c ( resultFromB ) resultFromD = d( resultFromC ) resultFromE = e ( resultFromD )
  • 15. Case study: flow control Next we will be looking into code that reads two files and compares content: a = io.open ( ’a.txt’) a data = a : read ( ’a’) b = io.open ( ’b.txt’) b data = b : read ( ’a’) compare ( a data , b data )
  • 16. Case study: debugging Last but not least - we will be checking how errors are manifested.
  • 17. Approach #1: callback C++: void r e a d h a n d l e r ( e r r o r c o d e const& ec , s i z e t bytes ) { . . . } read ( . . . , r e a d h a n d l e r ) ; Lua: function r e a d h a n d l e r ( data ) end socket : on ("data" , r e a d h a n d l e r ) JavaScript: function r e a d h a n d l e r ( data ) {} socket . on ("data" , r e a d h a n d l e r ) ;
  • 18. Approach #1: pitfall a ( params , function ( resultFromA , e r r ) i f ( ! e r r ) then return end b( resultFromA , function ( resultFromB , e r r ) i f ( ! e r r ) then return end c ( resultFromB , function ( resultFromC , e r r ) i f ( ! e r r ) then return end d( resultFromC , function ( resultFromD , e r r ) i f ( ! e r r ) then return end e ( resultFromD , function ( resultFromE , e r r ) // . . end) end) end) end) end)
  • 19. Approach #1: phony solution a ( params , HandleResultsOfA ) ; HandleResultsOfA ( resultFromA , e r r ) { i f ( ! e r r ) return ; b( resultFromA , HandleResultsOfB ) ; } HandleResultsOfB ( resultFromB , e r r ) { i f ( ! e r r ) return ; c ( resultFromB , HandleResultsOfC ) ; } HandleResultsOfC ( resultFromC , e r r ) { i f ( ! e r r ) return ; d( resultFromC , HandleResultsOfD ) ; } HandleResultsOfD ( resultFromD , e r r ) { i f ( ! e r r ) return ;
  • 20. Approach #1: how I see it
  • 21. Approach #1: debugging I 1 f s . s t a t ("1.txt" , function () { 2 f s . s t a t ("2.txt" , function () { 3 //obvious error 4 f s . s t a t ( function (){} , function () {}) 5 }) 6 })
  • 22. Approach #1: debugging II Result is ok, error can be easily spotted: >node t e s t . j s f s . j s :783 binding . s t a t ( pathModule . makeLong ( path ) , req ) ; ˆ TypeError : path must be a s t r i n g at TypeError ( n a t i v e ) at Object . f s . s t a t ( f s . j s :783:11) at t e s t . j s : 4 : 8 at FSReqWrap . oncomplete ( f s . j s : 9 5 : 1 5 ) test.js:4 is: f s . s t a t ( function (){} , function () {})
  • 23. Approach #1: say goodbye to your stacktrace I What if we use same function in multiple places? 1 var f s = r e q u i r e ( ’fs’ ) ; 2 function bug ( content , cont ) { 3 f s . w r i t e F i l e ("config.json" , content , 4 function () { f s . s t a t ("config.json" , cont ) ; 5 } ) ; 6 } 7 8 bug ("{}" , "wrong")
  • 24. Approach #1: say goodbye to your stacktrace II Result: >node t e s t . j s throw new TypeError ( ’ c a l l b a c k must be a function ’ ) ; TypeError : c a l l b a c k must be a f u n c t i o n at makeCallback ( f s . j s : 7 8 : 1 1 ) at Object . f s . s t a t ( f s . j s :826:14) at t e s t . j s : 4 : 2 0 at FSReqWrap . oncomplete ( f s . j s : 8 2 : 1 5 ) test.js:4 is: function () { f s . s t a t ("config.json" , cont ) ; While there error is in test.js:8: bug ("{}" , "wrong")
  • 26. Approach #1: pros and cons Pros Easy to use,
  • 27. Approach #1: pros and cons Pros Easy to use, Integrated by default
  • 28. Approach #1: pros and cons Pros Easy to use, Integrated by default
  • 29. Approach #1: pros and cons Pros Easy to use, Integrated by default Cons Degrades to callback hell quickly
  • 30. Approach #1: pros and cons Pros Easy to use, Integrated by default Cons Degrades to callback hell quickly Makes stacktraces unusable
  • 31. Approach #1: pros and cons Pros Easy to use, Integrated by default Cons Degrades to callback hell quickly Makes stacktraces unusable Does not address more complex flow control scenarios
  • 32. Approach #1: pros and cons Pros Easy to use, Integrated by default Cons Degrades to callback hell quickly Makes stacktraces unusable Does not address more complex flow control scenarios
  • 33. Approach #1: pros and cons Pros Easy to use, Integrated by default Cons Degrades to callback hell quickly Makes stacktraces unusable Does not address more complex flow control scenarios
  • 34. Approach #2: Promises Abstract model of asynchronous computation results. Pending .then(fulfillCallback,...) .then(…, rejectCallback) .catch() Resolved Rejected Cancelled OnValue OnError OnCancel OnValue OnError (no actions) (action) (recovery) (no recovery)
  • 35. Approach #2: Case study I Do you remember callback hell? a ( params , function ( resultFromA , e r r ) i f ( ! e r r ) then return end b( resultFromA , function ( resultFromB , e r r ) i f ( ! e r r ) then return end c ( resultFromB , function ( resultFromC , e r r ) i f ( ! e r r ) then return end d( resultFromC , function ( resultFromD , e r r ) i f ( ! e r r ) then return end e ( resultFromD , function ( resultFromE , e r r ) // . . end) end) end) end) end)
  • 36. Approach #2: Case study II Promises let you write it following way: a ( params ) : next ( function ( resultFromA ) return b( resultFromA ) end) : next ( function ( resultFromB ) return c ( resultFromB ) end) : next ( function ( resultFromC ) return d( resultFromC ) end) : next ( function ( resultFromD ) . . . end) .
  • 37. Approach #2: Case study III With a bit of imagination you can read it as: a ( params ) --:next(function(resultFromA) return b( resultFromA ) -- end) --:next(function(resultFromB) return c ( resultFromB ) -- end) --:next(function(resultFromC) return d( resultFromC ) -- end) --:next(function(resultFromD) . . . --end)
  • 38. Approach #2: flow control Promises are abstract model of computation. Therefore it is possible to build flow control with them. For example: c(a(paramsOfA), b(paramsOfB)) becomes: l o c a l a = f s . readAsync ("a.txt") l o c a l b = f s . readAsync ("b.txt") d e f e r r e d . a l l ({a , b } ) : next ( function ( r e s u l t s ) return c ( r e s u l t s [ 0 ] , r e s u l t s [ 1 ] ) end )
  • 39. Approach #2: What about callstacks? I 1 var Promise = r e q u i r e ("bluebird" ) ; 2 var f s = r e q u i r e ( ’fs’ ) ; 3 Promise . p r o m i s i f y A l l ( f s ) ; 4 function b( f i l e ) {return function () 5 {return f s . statAsync ( f i l e )}} 6 f s . statAsync ("1.txt") 7 . then (b("2.txt" )) 8 . then (b( undefined ))
  • 40. Approach #2: It’s a trap! 1 var Promise = r e q u i r e ("bluebird" ) ; 2 var f s = r e q u i r e ( ’fs’ ) ; 3 Promise . p r o m i s i f y A l l ( f s ) ; 4 function b( f i l e ) {return function () 5 {return f s . statAsync ( f i l e )}} 6 f s . statAsync ("1.txt") 7 . then (b("2.txt" )) 8 . then (b( undefined ))
  • 41. Approach #2: What about callstacks? II Still not so good: Unhandled r e j e c t i o n TypeError : path must be a s t r i n g at TypeError ( n a t i v e ) at Object . f s . s t a t ( f s . j s : 7 8 3 : 1 1 ) at Object . t r y C a t c h e r ( node modules b l u e b i r d j s r e l e a s e u t i l . j s : 1 6 : 2 3 ) at Object . r e t [ as statAsync ] ( e v a l at <anonymous> ( node modules b l u e b i r d j s r e l e a s e p r o m i s i f y . j s : 1 8 4 : 1 2 ) , <a at t e s t . j s : 5 : 1 3 at t r y C a t c h e r ( node modules b l u e b i r d j s r e l e a s e u t i l . j s : 1 6 : 2 3 ) at Promise . settlePromiseFromHandler ( node modules b l u e b i r d j s r e l e a s e promise . j s : 5 0 9 : 3 1 ) at Promise . s e t t l e P r o m i s e ( node modules b l u e b i r d j s r e l e a s e promise . j s : 5 6 6 : 1 8 ) at Promise . s e t t l e P r o m i s e 0 ( node modules b l u e b i r d j s r e l e a s e promise . j s : 6 1 1 : 1 0 ) at Promise . s e t t l e P r o m i s e s ( node modules b l u e b i r d j s r e l e a s e promise . j s : 6 9 0 : 1 8 ) at Promise . f u l f i l l ( node modules b l u e b i r d j s r e l e a s e promise . j s : 6 3 5 : 1 8 ) at node modules b l u e b i r d j s r e l e a s e nodeback . j s : 4 2 : 2 1 at FSReqWrap . oncomplete ( f s . j s : 9 5 : 1 5 ) test.js:4-5 function b( f i l e ) { return function () { return f s . statAsync ( f i l e )}}
  • 42. Approach #2: pros and cons Pros Code structure and business logic are more coherent,
  • 43. Approach #2: pros and cons Pros Code structure and business logic are more coherent, Provide abstraction of flow control
  • 44. Approach #2: pros and cons Pros Code structure and business logic are more coherent, Provide abstraction of flow control
  • 45. Approach #2: pros and cons Pros Code structure and business logic are more coherent, Provide abstraction of flow control Cons Some boiler plate still needed for each call
  • 46. Approach #2: pros and cons Pros Code structure and business logic are more coherent, Provide abstraction of flow control Cons Some boiler plate still needed for each call Makes stacktraces unusable
  • 47. Approach #2: pros and cons Pros Code structure and business logic are more coherent, Provide abstraction of flow control Cons Some boiler plate still needed for each call Makes stacktraces unusable
  • 48. Approach #2: pros and cons Pros Code structure and business logic are more coherent, Provide abstraction of flow control Cons Some boiler plate still needed for each call Makes stacktraces unusable
  • 49. Approach #3: Coroutines http://www.boost.org/doc/libs/1 60 0/libs/coroutine/doc/html/coroutine/intro.html [2]
  • 50. Approach #3: Case study I We will look, again, at e(d(c(b(a(params))))), now with coroutines! coroutine.wrap ( function () resultFromA = a ( params ) resultFromB = b( resultFromA ) resultFromC = c ( resultFromB ) resultFromD = d( resultFromC ) resultFromE = e ( resultFromD ) end ) ( )
  • 51. Approach #3: flow control Coroutines allow to build flow control with them, too. For example: c(a(paramsOfA), b(paramsOfB)) becomes: coroutine.wrap ( function () a , b = c o r o s p l i t ( function () return f s. re ad As yn c ( ’a.txt’) end , function () return f s. re ad As yn c ( ’b.txt’) end) c (a , b) end ) ( )
  • 52. Approach #3: What about callstacks? I 1 local f s = require ’coro-fs’ 2 function bug () 3 f s . s t a t ("2.txt") 4 return f s . s t a t ( function () print "x" end) 5 end 6 coroutine.wrap ( function () xpcall ( function () 7 f s . s t a t ("1.txt") 8 bug () 9 end , 10 function ( e ) print ( debug.traceback ( e ) ) ; return e end) 11 end ) ( )
  • 53. Approach #3: What about callstacks? II > l u v i t . exe c o r o u t i n e s . lua deps / coro−f s . lua : 4 4 : bad argument #1 to ’ f s s t a t ’ ( s t r i n g expected , got f u n c t i o n ) stack traceback : t e s t . lua : 1 0 : in f u n c t i o n <t e s t . lua :10> [C ] : in f u n c t i o n ’ f s s t a t ’ deps / coro−f s . lua : 4 4 : in f u n c t i o n ’ bug ’ t e s t . lua : 4 : in f u n c t i o n ’ bug ’ t e s t . lua : 8 : in f u n c t i o n <t e s t . lua :6> [C ] : in f u n c t i o n ’ x p c a l l ’ t e s t . lua : 6 : in f u n c t i o n <t e s t . lua :6> coroutines.lua:6,8 coroutine.wrap ( function () xpcall ( function () bug ()
  • 54. Approach #3: pros and cons Pros Resembles synchronous code,
  • 55. Approach #3: pros and cons Pros Resembles synchronous code, Provide abstraction of flow control,
  • 56. Approach #3: pros and cons Pros Resembles synchronous code, Provide abstraction of flow control, Keeps stack untouched!
  • 57. Approach #3: pros and cons Pros Resembles synchronous code, Provide abstraction of flow control, Keeps stack untouched!
  • 58. Approach #3: pros and cons Pros Resembles synchronous code, Provide abstraction of flow control, Keeps stack untouched! Cons Some boiler plate still needed for each flow
  • 59. Approach #3: pros and cons Pros Resembles synchronous code, Provide abstraction of flow control, Keeps stack untouched! Cons Some boiler plate still needed for each flow
  • 61. And the winner is! Coroutine
  • 63. Bibliograpy I B. Fisher. Indiana jones and the temple of doom. https://www.flickr.com/photos/7thstreettheatre/16587334520, 2015. Cropped out ticket and release details. See licence: https://creativecommons.org/licenses/by/2.0/ (Attribution 2.0 Generic (CC BY 2.0)). Oliver Kowalke. http://www.boost.org/doc/libs/1 61 0/libs/coroutine/doc/html/coroutine/intro.ht Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE 1 0.txt or copy at http://www.boost.org/LICENSE 1 0.txt).