SlideShare a Scribd company logo
1 of 13
Download to read offline
Non-Blocking Python
By Tao Zhu
Tao
Near 10 years exp as
“full-stack”
!
Lead Developer, Perform
Group Plc
Repeated Stories

PM: Why slow?
System Admin: Seems
only slow during peak
hour?
Developer: Seems
only slow for login?
DevOps: It is slow in
the login process as
there are many
concurrent write ops
into db and db starts
lock row.
“DevOps” is killing
Developers?
Rise of “full-stack”?
How to think like a
“full-stack”?
Developing beyond big O
Developer: I have
implemented a binary-
tree algo that is O(log
n)
System Admin: I have
implemented B+ tree
index that is better
than O(log n)
DevOps:
1. The single table is
just too big. Time to
break down into
smaller tables?
2. Is your web server
blocking
Blocking? What is that?
A blocking web-server is similar to a
phone call.
!
You need to wait on-line to get a response
and continue
A blocking server
Django Server Process
Django Server Process
Django Server Process
Django Server Process
DB
Django Server Process
= context switching (via kernel)
O(logn)
Non-blocking server
Tornado Server Process DB
= epoll (via kernel)
O(1)
Event loop
How to write Non-block
server?
Call Backs
Coroutine (Decorator)
Yield (Lazy Eval)
def wait_for_messages(self, callback, cursor=None):
if cursor:
new_count = 0
for msg in reversed(self.cache):
if msg["id"] == cursor:
break
new_count += 1
if new_count:
callback(self.cache[-new_count:])
return
self.waiters.add(callback)
!
def cancel_wait(self, callback):
self.waiters.remove(callback)
!
class MessageNewHandler(BaseHandler):
@tornado.web.authenticated
@gen.coroutine
def post(self):
message = {
"id": str(uuid.uuid4()),
"from": self.current_user["first_name"],
"body": self.get_argument("body"),
}
!
cursor = collection.find({'$or': [{'teamA': self.get_argument("body")},{'teamB'
new_message = [self.get_argument("body"),"Matches:"]
withMatch = False
while (yield cursor.fetch_next):
document = cursor.next_object()
withMatch = True
try:
matchDatetime = document.get('data').get('prematch').get('match').get('
except:
try:
matchDatetime = document.get('data').get('match').get('start_time')
except:
pass
!
print matchDatetime
msg_str = matchDatetime+':'+document.get('teamA','')+' v '+ document.get('t
if isinstance(document.get('goalA'), int ):
msg_str = msg_str+' '+str(document.get('goalA',''))+' : '+ str(document
new_message.append(msg_str)
!
Non-blocking DB Driver
Non-blocking through out the “Full Stack”
PyMongo? No, it is blocking
Use Motor
Demo - World Cup Genie
Take-aways
How to think like a “Full-stack”?
Look beyond coding and big(O)
Blocking vs Non-Blocking
Tornado Programming Essentials
Callbacks,Coroutines, Yield
Non-blocking Full Stack - Motor
Contact
Blog: Tzu’s {Code of Geeks}
http://geektzu.wordpress.com/author/geektzu/
Email: software-engineer@outlook.com
Github: https://github.com/geektzu/worldcupgenie

More Related Content

What's hot

Moving Pictures - Web 2.0 Expo NYC
Moving Pictures - Web 2.0 Expo NYCMoving Pictures - Web 2.0 Expo NYC
Moving Pictures - Web 2.0 Expo NYC
Cal Henderson
 
Os Fitzpatrick Sussman Swp
Os Fitzpatrick Sussman SwpOs Fitzpatrick Sussman Swp
Os Fitzpatrick Sussman Swp
oscon2007
 
Browser controller testing for webapps (in Windows environment)
Browser controller testing for webapps (in Windows environment)Browser controller testing for webapps (in Windows environment)
Browser controller testing for webapps (in Windows environment)
Adrian Spinei
 
Documenting apps ti confnyc
Documenting apps   ti confnycDocumenting apps   ti confnyc
Documenting apps ti confnyc
Jamil Spain
 

What's hot (20)

Bp106 Worst Practices Final
Bp106   Worst Practices FinalBp106   Worst Practices Final
Bp106 Worst Practices Final
 
WordPress Speed & Performance from Pagely's CTO
WordPress Speed & Performance from Pagely's CTOWordPress Speed & Performance from Pagely's CTO
WordPress Speed & Performance from Pagely's CTO
 
Real-time Ruby for the Real-time Web
Real-time Ruby for the Real-time WebReal-time Ruby for the Real-time Web
Real-time Ruby for the Real-time Web
 
Moving Pictures - Web 2.0 Expo NYC
Moving Pictures - Web 2.0 Expo NYCMoving Pictures - Web 2.0 Expo NYC
Moving Pictures - Web 2.0 Expo NYC
 
Os Fitzpatrick Sussman Swp
Os Fitzpatrick Sussman SwpOs Fitzpatrick Sussman Swp
Os Fitzpatrick Sussman Swp
 
scaling compiled applications - highload 2013
scaling compiled applications - highload 2013scaling compiled applications - highload 2013
scaling compiled applications - highload 2013
 
Brief Introduction to Concurrent Programming
Brief Introduction to Concurrent ProgrammingBrief Introduction to Concurrent Programming
Brief Introduction to Concurrent Programming
 
Realtime web2012
Realtime web2012Realtime web2012
Realtime web2012
 
When it all goes wrong | PGConf EU 2019 | Will Leinweber
When it all goes wrong | PGConf EU 2019 | Will LeinweberWhen it all goes wrong | PGConf EU 2019 | Will Leinweber
When it all goes wrong | PGConf EU 2019 | Will Leinweber
 
Os Alrubaie
Os AlrubaieOs Alrubaie
Os Alrubaie
 
When it all goes wrong (with Postgres) | RailsConf 2019 | Will Leinweber
When it all goes wrong (with Postgres) | RailsConf 2019 | Will LeinweberWhen it all goes wrong (with Postgres) | RailsConf 2019 | Will Leinweber
When it all goes wrong (with Postgres) | RailsConf 2019 | Will Leinweber
 
REST in peace @ IPC 2012 in Mainz
REST in peace @ IPC 2012 in MainzREST in peace @ IPC 2012 in Mainz
REST in peace @ IPC 2012 in Mainz
 
Browser controller testing for webapps (in Windows environment)
Browser controller testing for webapps (in Windows environment)Browser controller testing for webapps (in Windows environment)
Browser controller testing for webapps (in Windows environment)
 
Documenting apps ti confnyc
Documenting apps   ti confnycDocumenting apps   ti confnyc
Documenting apps ti confnyc
 
Zombilizing The Web Browser Via Flash Player 9
Zombilizing The Web Browser Via Flash Player 9Zombilizing The Web Browser Via Flash Player 9
Zombilizing The Web Browser Via Flash Player 9
 
Building Big on the Web
Building Big on the WebBuilding Big on the Web
Building Big on the Web
 
OSCon - Performance vs Scalability
OSCon - Performance vs ScalabilityOSCon - Performance vs Scalability
OSCon - Performance vs Scalability
 
WordCamp Ann Arbor 2014: Site Caching, From Nothing to Everything
WordCamp Ann Arbor 2014: Site Caching, From Nothing to EverythingWordCamp Ann Arbor 2014: Site Caching, From Nothing to Everything
WordCamp Ann Arbor 2014: Site Caching, From Nothing to Everything
 
tus.io – Resumable file uploads for web and mobile apps by Felix Geisendörfer
tus.io – Resumable file uploads for web and mobile apps by Felix Geisendörfertus.io – Resumable file uploads for web and mobile apps by Felix Geisendörfer
tus.io – Resumable file uploads for web and mobile apps by Felix Geisendörfer
 
Dmk Bo2 K7 Web
Dmk Bo2 K7 WebDmk Bo2 K7 Web
Dmk Bo2 K7 Web
 

Similar to Pycon 2014

T3CON09 - FLOW3-based Intranet – first Experiences
T3CON09 - FLOW3-based Intranet – first ExperiencesT3CON09 - FLOW3-based Intranet – first Experiences
T3CON09 - FLOW3-based Intranet – first Experiences
elementare teilchen GmbH
 
Rebol brainwasher
Rebol brainwasherRebol brainwasher
Rebol brainwasher
crazyaxe
 
Hadoop at Meebo: Lessons in the Real World
Hadoop at Meebo: Lessons in the Real WorldHadoop at Meebo: Lessons in the Real World
Hadoop at Meebo: Lessons in the Real World
voberoi
 
Search Lucene
Search LuceneSearch Lucene
Search Lucene
Jeremy Coates
 

Similar to Pycon 2014 (20)

T3CON09 - FLOW3-based Intranet – first Experiences
T3CON09 - FLOW3-based Intranet – first ExperiencesT3CON09 - FLOW3-based Intranet – first Experiences
T3CON09 - FLOW3-based Intranet – first Experiences
 
Rebol brainwasher
Rebol brainwasherRebol brainwasher
Rebol brainwasher
 
Debugging ZFS: From Illumos to Linux
Debugging ZFS: From Illumos to LinuxDebugging ZFS: From Illumos to Linux
Debugging ZFS: From Illumos to Linux
 
Jared Whitlock Open Source In The Enterprise Plone @ Novell
Jared Whitlock   Open Source In The Enterprise    Plone @ NovellJared Whitlock   Open Source In The Enterprise    Plone @ Novell
Jared Whitlock Open Source In The Enterprise Plone @ Novell
 
Hadoop at Meebo: Lessons in the Real World
Hadoop at Meebo: Lessons in the Real WorldHadoop at Meebo: Lessons in the Real World
Hadoop at Meebo: Lessons in the Real World
 
Glance rebol
Glance rebolGlance rebol
Glance rebol
 
Search Lucene
Search LuceneSearch Lucene
Search Lucene
 
X page developer
X page developerX page developer
X page developer
 
Lennart Regebro What Zope Did Wrong (And What To Do Instead)
Lennart Regebro   What Zope Did Wrong (And What To Do Instead)Lennart Regebro   What Zope Did Wrong (And What To Do Instead)
Lennart Regebro What Zope Did Wrong (And What To Do Instead)
 
Lennart Regebro What Zope Did Wrong (And What To Do Instead)
Lennart Regebro   What Zope Did Wrong (And What To Do Instead)Lennart Regebro   What Zope Did Wrong (And What To Do Instead)
Lennart Regebro What Zope Did Wrong (And What To Do Instead)
 
Google Protocol Buffers + gRPC
Google Protocol Buffers + gRPCGoogle Protocol Buffers + gRPC
Google Protocol Buffers + gRPC
 
Beyond the Hype: 4 Years of Go in Production
Beyond the Hype: 4 Years of Go in ProductionBeyond the Hype: 4 Years of Go in Production
Beyond the Hype: 4 Years of Go in Production
 
Version Control ThinkVitamin
Version Control ThinkVitaminVersion Control ThinkVitamin
Version Control ThinkVitamin
 
Rust's Journey to Async/await
Rust's Journey to Async/awaitRust's Journey to Async/await
Rust's Journey to Async/await
 
Netty @Apple: Large Scale Deployment/Connectivity
Netty @Apple: Large Scale Deployment/ConnectivityNetty @Apple: Large Scale Deployment/Connectivity
Netty @Apple: Large Scale Deployment/Connectivity
 
Modern web dev_taxonomy
Modern web dev_taxonomyModern web dev_taxonomy
Modern web dev_taxonomy
 
Google's Go Programming Language - Introduction
Google's Go Programming Language - Introduction Google's Go Programming Language - Introduction
Google's Go Programming Language - Introduction
 
A First Look at Google's Go Programming Language
A First Look at Google's Go Programming LanguageA First Look at Google's Go Programming Language
A First Look at Google's Go Programming Language
 
Continuous operations in AWS
Continuous operations in AWSContinuous operations in AWS
Continuous operations in AWS
 
Go After 4 Years in Production - QCon 2015
Go After 4 Years in Production - QCon 2015Go After 4 Years in Production - QCon 2015
Go After 4 Years in Production - QCon 2015
 

Recently uploaded

Indian Escort in Abu DHabi 0508644382 Abu Dhabi Escorts
Indian Escort in Abu DHabi 0508644382 Abu Dhabi EscortsIndian Escort in Abu DHabi 0508644382 Abu Dhabi Escorts
Indian Escort in Abu DHabi 0508644382 Abu Dhabi Escorts
Monica Sydney
 
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
gajnagarg
 
75539-Cyber Security Challenges PPT.pptx
75539-Cyber Security Challenges PPT.pptx75539-Cyber Security Challenges PPT.pptx
75539-Cyber Security Challenges PPT.pptx
Asmae Rabhi
 
pdfcoffee.com_business-ethics-q3m7-pdf-free.pdf
pdfcoffee.com_business-ethics-q3m7-pdf-free.pdfpdfcoffee.com_business-ethics-q3m7-pdf-free.pdf
pdfcoffee.com_business-ethics-q3m7-pdf-free.pdf
JOHNBEBONYAP1
 
Russian Escort Abu Dhabi 0503464457 Abu DHabi Escorts
Russian Escort Abu Dhabi 0503464457 Abu DHabi EscortsRussian Escort Abu Dhabi 0503464457 Abu DHabi Escorts
Russian Escort Abu Dhabi 0503464457 Abu DHabi Escorts
Monica Sydney
 
原版制作美国爱荷华大学毕业证(iowa毕业证书)学位证网上存档可查
原版制作美国爱荷华大学毕业证(iowa毕业证书)学位证网上存档可查原版制作美国爱荷华大学毕业证(iowa毕业证书)学位证网上存档可查
原版制作美国爱荷华大学毕业证(iowa毕业证书)学位证网上存档可查
ydyuyu
 
一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制
一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制
一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制
pxcywzqs
 
在线制作约克大学毕业证(yu毕业证)在读证明认证可查
在线制作约克大学毕业证(yu毕业证)在读证明认证可查在线制作约克大学毕业证(yu毕业证)在读证明认证可查
在线制作约克大学毕业证(yu毕业证)在读证明认证可查
ydyuyu
 
PowerDirector Explination Process...pptx
PowerDirector Explination Process...pptxPowerDirector Explination Process...pptx
PowerDirector Explination Process...pptx
galaxypingy
 
一比一原版(Flinders毕业证书)弗林德斯大学毕业证原件一模一样
一比一原版(Flinders毕业证书)弗林德斯大学毕业证原件一模一样一比一原版(Flinders毕业证书)弗林德斯大学毕业证原件一模一样
一比一原版(Flinders毕业证书)弗林德斯大学毕业证原件一模一样
ayvbos
 
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
ydyuyu
 
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girlsRussian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Monica Sydney
 

Recently uploaded (20)

Indian Escort in Abu DHabi 0508644382 Abu Dhabi Escorts
Indian Escort in Abu DHabi 0508644382 Abu Dhabi EscortsIndian Escort in Abu DHabi 0508644382 Abu Dhabi Escorts
Indian Escort in Abu DHabi 0508644382 Abu Dhabi Escorts
 
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
 
75539-Cyber Security Challenges PPT.pptx
75539-Cyber Security Challenges PPT.pptx75539-Cyber Security Challenges PPT.pptx
75539-Cyber Security Challenges PPT.pptx
 
Story Board.pptxrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
Story Board.pptxrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrStory Board.pptxrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
Story Board.pptxrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
 
pdfcoffee.com_business-ethics-q3m7-pdf-free.pdf
pdfcoffee.com_business-ethics-q3m7-pdf-free.pdfpdfcoffee.com_business-ethics-q3m7-pdf-free.pdf
pdfcoffee.com_business-ethics-q3m7-pdf-free.pdf
 
Russian Escort Abu Dhabi 0503464457 Abu DHabi Escorts
Russian Escort Abu Dhabi 0503464457 Abu DHabi EscortsRussian Escort Abu Dhabi 0503464457 Abu DHabi Escorts
Russian Escort Abu Dhabi 0503464457 Abu DHabi Escorts
 
2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs
2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs
2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs
 
"Boost Your Digital Presence: Partner with a Leading SEO Agency"
"Boost Your Digital Presence: Partner with a Leading SEO Agency""Boost Your Digital Presence: Partner with a Leading SEO Agency"
"Boost Your Digital Presence: Partner with a Leading SEO Agency"
 
Trump Diapers Over Dems t shirts Sweatshirt
Trump Diapers Over Dems t shirts SweatshirtTrump Diapers Over Dems t shirts Sweatshirt
Trump Diapers Over Dems t shirts Sweatshirt
 
Best SEO Services Company in Dallas | Best SEO Agency Dallas
Best SEO Services Company in Dallas | Best SEO Agency DallasBest SEO Services Company in Dallas | Best SEO Agency Dallas
Best SEO Services Company in Dallas | Best SEO Agency Dallas
 
原版制作美国爱荷华大学毕业证(iowa毕业证书)学位证网上存档可查
原版制作美国爱荷华大学毕业证(iowa毕业证书)学位证网上存档可查原版制作美国爱荷华大学毕业证(iowa毕业证书)学位证网上存档可查
原版制作美国爱荷华大学毕业证(iowa毕业证书)学位证网上存档可查
 
一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制
一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制
一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制
 
Nagercoil Escorts Service Girl ^ 9332606886, WhatsApp Anytime Nagercoil
Nagercoil Escorts Service Girl ^ 9332606886, WhatsApp Anytime NagercoilNagercoil Escorts Service Girl ^ 9332606886, WhatsApp Anytime Nagercoil
Nagercoil Escorts Service Girl ^ 9332606886, WhatsApp Anytime Nagercoil
 
在线制作约克大学毕业证(yu毕业证)在读证明认证可查
在线制作约克大学毕业证(yu毕业证)在读证明认证可查在线制作约克大学毕业证(yu毕业证)在读证明认证可查
在线制作约克大学毕业证(yu毕业证)在读证明认证可查
 
PowerDirector Explination Process...pptx
PowerDirector Explination Process...pptxPowerDirector Explination Process...pptx
PowerDirector Explination Process...pptx
 
一比一原版(Flinders毕业证书)弗林德斯大学毕业证原件一模一样
一比一原版(Flinders毕业证书)弗林德斯大学毕业证原件一模一样一比一原版(Flinders毕业证书)弗林德斯大学毕业证原件一模一样
一比一原版(Flinders毕业证书)弗林德斯大学毕业证原件一模一样
 
Microsoft Azure Arc Customer Deck Microsoft
Microsoft Azure Arc Customer Deck MicrosoftMicrosoft Azure Arc Customer Deck Microsoft
Microsoft Azure Arc Customer Deck Microsoft
 
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
 
Vip Firozabad Phone 8250092165 Escorts Service At 6k To 30k Along With Ac Room
Vip Firozabad Phone 8250092165 Escorts Service At 6k To 30k Along With Ac RoomVip Firozabad Phone 8250092165 Escorts Service At 6k To 30k Along With Ac Room
Vip Firozabad Phone 8250092165 Escorts Service At 6k To 30k Along With Ac Room
 
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girlsRussian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
 

Pycon 2014

  • 2. Tao Near 10 years exp as “full-stack” ! Lead Developer, Perform Group Plc
  • 3. Repeated Stories
 PM: Why slow? System Admin: Seems only slow during peak hour? Developer: Seems only slow for login? DevOps: It is slow in the login process as there are many concurrent write ops into db and db starts lock row.
  • 4. “DevOps” is killing Developers? Rise of “full-stack”? How to think like a “full-stack”?
  • 5. Developing beyond big O Developer: I have implemented a binary- tree algo that is O(log n) System Admin: I have implemented B+ tree index that is better than O(log n) DevOps: 1. The single table is just too big. Time to break down into smaller tables? 2. Is your web server blocking
  • 6. Blocking? What is that? A blocking web-server is similar to a phone call. ! You need to wait on-line to get a response and continue
  • 7. A blocking server Django Server Process Django Server Process Django Server Process Django Server Process DB Django Server Process = context switching (via kernel) O(logn)
  • 8. Non-blocking server Tornado Server Process DB = epoll (via kernel) O(1) Event loop
  • 9. How to write Non-block server? Call Backs Coroutine (Decorator) Yield (Lazy Eval) def wait_for_messages(self, callback, cursor=None): if cursor: new_count = 0 for msg in reversed(self.cache): if msg["id"] == cursor: break new_count += 1 if new_count: callback(self.cache[-new_count:]) return self.waiters.add(callback) ! def cancel_wait(self, callback): self.waiters.remove(callback) ! class MessageNewHandler(BaseHandler): @tornado.web.authenticated @gen.coroutine def post(self): message = { "id": str(uuid.uuid4()), "from": self.current_user["first_name"], "body": self.get_argument("body"), } ! cursor = collection.find({'$or': [{'teamA': self.get_argument("body")},{'teamB' new_message = [self.get_argument("body"),"Matches:"] withMatch = False while (yield cursor.fetch_next): document = cursor.next_object() withMatch = True try: matchDatetime = document.get('data').get('prematch').get('match').get(' except: try: matchDatetime = document.get('data').get('match').get('start_time') except: pass ! print matchDatetime msg_str = matchDatetime+':'+document.get('teamA','')+' v '+ document.get('t if isinstance(document.get('goalA'), int ): msg_str = msg_str+' '+str(document.get('goalA',''))+' : '+ str(document new_message.append(msg_str) !
  • 10. Non-blocking DB Driver Non-blocking through out the “Full Stack” PyMongo? No, it is blocking Use Motor
  • 11. Demo - World Cup Genie
  • 12. Take-aways How to think like a “Full-stack”? Look beyond coding and big(O) Blocking vs Non-Blocking Tornado Programming Essentials Callbacks,Coroutines, Yield Non-blocking Full Stack - Motor
  • 13. Contact Blog: Tzu’s {Code of Geeks} http://geektzu.wordpress.com/author/geektzu/ Email: software-engineer@outlook.com Github: https://github.com/geektzu/worldcupgenie