SlideShare a Scribd company logo
Stackless Python in EVE Kristján Valur Jónsson [email_address] CCP Games inc.
EVE MMORPG Space game Client / server Single shard massive server 130.000 active players, >24.000 concurrent users World concurrency record on a shard 425,537 lines of Python code and growing. client: 158,656 server: 218,645 common: 48,236 Possible only because of Stackless Python
The Tranquility cluster 400 GHz CPU / 200 Gb RAM 2 Routers (CISCO Alteon) 14 Proxy servers (IBM Blade)  55 Sol servers (IBM x335) 2 DB servers (clustered, IBM Brick x445) FastT600 Fiber,  56 x FC 15k disks, DS4300 + 3*EXP700 Windows 2000, MS SQL Server Currently being upgraded AMD x64 IBM Blade RAMSAN gizmo 64 bit binaries
EVE Architecture COM-like basic architecture Python tightly integrated at an early stage Home-grown wrapping of BLUE objects
Stackless in EVE BLUE foundation: robust, but cumbersome RAD Stackless Python:  Python and so much more EVE is inconceivable without Stackless Everyone is a programmer Interactive development. Files reloaded automatically Classes updated with new methods Demo:
Stackless Python Tasklets Threads of execution.  Not OS threads Lightweight No pre-emption No memory fragmentation due to stacks Channels Tasklet rendezvous point Data passing Scheduling Synchronization
Stackless? No C stack Python stack in linked frame objects Tasklet switching by swapping frame chain Compromise stackless where possible. C stack whisked away if necessary
Channels
Channel semantics Send on a channel with no receiver blocks tasklet. Send on a channel with a (blocked) receiver, suspends tasklet and runs receiver immediately.  Sender runs again in due course. Symmetric behaviour. “ Balance”, can have a queue of readers or writers. Conceptually similar to Unix pipes
Channel semantics, cont. Scheduling semantics are precise: A blocked tasklet is run immediately Usable as a building block: semaphores mutex critical section condition variables
The main loop Establish stackless context int WinMain(...)  { PyObject *myApp = new EveApp(); PyObject *r = PyStackless_CallMethod_Main(myApp,    “WinMain”, 0); return PyInt_AsLong( r );
Regular Windows message loop Runs in Stackless context The  “Main Tasklet” The main loop cont. PyObject* EveApp::WinMain(PyObject *self, PyObject *args) { while(!mExit) { PyOS->ExecFile("script:/sys/autoexec.py");  MSG msg; while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){ TranslateMessage(&msg); DispatchMessage(&msg); } for (TickIt i = mTickers.begin(; i !=  mTickers.end(); i++) i->mCb-> OnTick (mTime, (void*)taskname); } }
Autoexec.py import blue def Startup(): import service srvMng = service.ServiceManager() run = ["dataconfig", "godma", “ui", …] srvMng.Run(run) #Start up the client in a tasklet! if CheckDXVersion(): import blue blue.pyos. CreateTasklet (Startup, (), {})
Tickers Tickers are BLUE modules: Trinity (the renderer) Netclient DB (on the server) Audio PyOS (special python services) …
The PyOS tick: Runs fresh tasklets (sleepers awoken elsewhere) Tick() { … mSynchro->Tick() PyObject *watchdogResult; do { watchdogResult =  PyStackless_RunWatchdog(20000000); if (!watchdogResult) PyFlushError("PumpPython::Watchdog"); Py_XDECREF(watchdogresult); } while (!watchdogResult);
blue.pyos.synchro Synchro: Provides Thread-like tasklet utilities: Sleep(ms) Yield() BeNice()
Sleep:  A python script makes the call  blue.pyos.Sleep(200) C++ code runs: Main tasklet check sleeper = New Sleeper(); mSleepers.insert(sleeper); PyObject *r = PyChannel_Receive(sleeper->mChannel); Another tasklet runs blue.pyos.synchro cont.
blue.pyos.synchro, ctd. Main tasklet in windows loop enters PyOS::Tick() mSleepers are examined for all that are due we do: mSleepers.remove(sleeper); PyChannel_Send(sleepers.mChannel,  Py_NONE); Main tasklet is suspended (but runnable), sleeper runs.
Points to note: A tasklet goes to sleep by calling  PyChannel_Receive()  on a channel which has no pending sender. It will sleep there (block) until someone sends Typically the main tasklet does this, doing  PyChannel_Send()  on a channel with a reader Ergo: The main tasklet may not block
Socket Receive Use Windows asynchronous file API Provide a synchronous python API.  A python script calls Read(). Tasklet may be blocked for a long time, (many frames) other tasklets continue running. Do this using channels.
Receive, cont. Python script runs: data = socket.Read() C code executes the request: Request *r = new Request(this); WSAReceive(mSocket, …); mRequests->insert( r ); PyChannel_Receive(r->mChannel); Tasklet is blocked
Receive, cont. Socket server is ticked from main loop For all requests that are marked completed, it transfers the data to the sleeping tasklets: PyObject *r = PyString_FromStringAndSize(req->mData,  req->mDataLen); PyChannel_Send(req->mChannel, r); Py_DECREF(data); delete req; The sleeping tasklet wakes up, main tasklet is suspended (but runnable)
Receive completed
Main Tasklet The one running the windows loop Can be suspended, allowing other tasklets to run Can be blocked, as long as there is another tasklet to unblock it (dangerous) Is responsible for waking up Sleepers, Yielders, IO tasklets, etc. therefore cannot be one of them Is flagged as non-blockable ( stackless.get_current().block_trap = True )
Channel magic Channels perform the stackless context switch. If there is a C stack in the call chain, it will  magically  swap the stacks. Your entire C stack (with C and python invocations) is whisked away and stored, to be replaced with a new one. This allows stackless to simulate cooperative multi-threading
Co-operative multitasking Context is switched only at known points. In Stackless, this is channel.send() and channel.receive() Also synchro.Yield(), synchro.Sleep(), BeNice(), socket and DB ops, etc. (all boil down to send() and receive() ) No unexpected context switches Almost no race conditions Program like you are single-threaded Very few exceptions. This extends to C state too!
Tasklets Tasklets are cheap 70,000 on a server node Used liberally to reduce perceived lag UI events forked out to tasklets A click can have heavy consequences. Heavy logic DB Access Networks access special rendering tasks forked out to tasklets. controlling an audio track “ tasklet it out” Use blue.pyos.synchro.BeNice() in large loops
Example: UI Event: Main tasklet receives window messages such as WM_LBUTTONUP Trinity invokes handler on UI elements or global handler Handler “tasklets out” any action to allow main thread to continue immediately. def OnGlobalUp(self, *args): mo = eve.triapp.uilib.mouseOver if mo in self.children: uthread.new(mo._OnClick) class Action(xtriui.QuickDeco): def _OnClick(self, *args): pass
What we don’t understand: Why isn’t everyone using Stackless Python?
That’s all For more info: http://www.ccpgames.com http://www.eve-online.com http://www.stackless.com [email_address]

More Related Content

PDF
I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
PPT
Stackless Python In Eve
PDF
Netty: asynchronous data transfer
KEY
Non blocking io with netty
PDF
Reactive server with netty
PDF
Asynchronous, Event-driven Network Application Development with Netty
PDF
Counter Wars (JEEConf 2016)
PPTX
epoll() - The I/O Hero
I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
Stackless Python In Eve
Netty: asynchronous data transfer
Non blocking io with netty
Reactive server with netty
Asynchronous, Event-driven Network Application Development with Netty
Counter Wars (JEEConf 2016)
epoll() - The I/O Hero

What's hot (20)

PDF
The future of async i/o in Python
PDF
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
PPT
Epoll - from the kernel side
PPTX
Introduction to TPL
ODP
Linux multiplexing
PDF
Java fork join
KEY
Distributed app development with nodejs and zeromq
PDF
maXbox Starter 42 Multiprocessing Programming
PDF
Tips on High Performance Server Programming
PDF
Python twisted
PDF
Asynchronous programming intro
PDF
Using zone.js
PDF
Coroutines in Kotlin
PDF
Non Blocking I/O for Everyone with RxJava
PDF
Windows IOCP vs Linux EPOLL Performance Comparison
PDF
Coroutines in Kotlin. UA Mobile 2017.
PDF
Concurrency: Rubies, plural
PDF
Concurrency: Rubies, Plural
PDF
Building scalable network applications with Netty (as presented on NLJUG JFal...
PDF
Qt everywhere a c++ abstraction platform
The future of async i/o in Python
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Epoll - from the kernel side
Introduction to TPL
Linux multiplexing
Java fork join
Distributed app development with nodejs and zeromq
maXbox Starter 42 Multiprocessing Programming
Tips on High Performance Server Programming
Python twisted
Asynchronous programming intro
Using zone.js
Coroutines in Kotlin
Non Blocking I/O for Everyone with RxJava
Windows IOCP vs Linux EPOLL Performance Comparison
Coroutines in Kotlin. UA Mobile 2017.
Concurrency: Rubies, plural
Concurrency: Rubies, Plural
Building scalable network applications with Netty (as presented on NLJUG JFal...
Qt everywhere a c++ abstraction platform
Ad

Viewers also liked (15)

PPS
O Mundo E O Mal. Jr Cordeiro.
PPTX
τα έθιμα στην τάξη μας
PPTX
Actividad 2.portafolio de trabajo 001
DOCX
DOCX
Ejecucion de los contratos admi.
ODP
Ayudas audio visuales
PDF
Abdel, la expropiacion
PPTX
DOCX
Actividad 10
PDF
Freelance tools
PDF
Tamaulipas
PDF
آموزش روش های حل روابط بازگشتی - بخش دوم
PDF
Formocresol cátedra1.key
DOCX
Contratos administrativos
PPTX
Microbial Fuel Cell Applications in Dehradun
O Mundo E O Mal. Jr Cordeiro.
τα έθιμα στην τάξη μας
Actividad 2.portafolio de trabajo 001
Ejecucion de los contratos admi.
Ayudas audio visuales
Abdel, la expropiacion
Actividad 10
Freelance tools
Tamaulipas
آموزش روش های حل روابط بازگشتی - بخش دوم
Formocresol cátedra1.key
Contratos administrativos
Microbial Fuel Cell Applications in Dehradun
Ad

Similar to Stackless Python In Eve (20)

ODP
Stackless Python 101
PDF
Python concurrency: libraries overview
PDF
Multiprocessing with python
PDF
Concurrency in Python
KEY
Gevent what's the point
PDF
Async I/O in Python
PDF
How do event loops work in Python?
PDF
Introduction to asyncio
PDF
Python, do you even async?
PPT
Server and its both type concurrent and iterattive.ppt
PDF
Twisted
PPTX
MQTT enabling the smallest things
PDF
Elegant concurrency
PDF
M|18 Architectural Overview: MariaDB MaxScale
ODP
Inter-Process/Task Communication With Message Queues
PDF
A deep dive into PEP-3156 and the new asyncio module
PDF
MultiThreading in Python
PDF
Kamaelia-ACCU-20050422
PDF
Livio slides-libflexsc-usenix-atc11
PDF
Global Interpreter Lock: Episode I - Break the Seal
Stackless Python 101
Python concurrency: libraries overview
Multiprocessing with python
Concurrency in Python
Gevent what's the point
Async I/O in Python
How do event loops work in Python?
Introduction to asyncio
Python, do you even async?
Server and its both type concurrent and iterattive.ppt
Twisted
MQTT enabling the smallest things
Elegant concurrency
M|18 Architectural Overview: MariaDB MaxScale
Inter-Process/Task Communication With Message Queues
A deep dive into PEP-3156 and the new asyncio module
MultiThreading in Python
Kamaelia-ACCU-20050422
Livio slides-libflexsc-usenix-atc11
Global Interpreter Lock: Episode I - Break the Seal

Recently uploaded (20)

PDF
KodekX | Application Modernization Development
PDF
Approach and Philosophy of On baking technology
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPTX
Cloud computing and distributed systems.
PDF
Electronic commerce courselecture one. Pdf
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Encapsulation theory and applications.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPTX
sap open course for s4hana steps from ECC to s4
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Machine learning based COVID-19 study performance prediction
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
cuic standard and advanced reporting.pdf
KodekX | Application Modernization Development
Approach and Philosophy of On baking technology
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Cloud computing and distributed systems.
Electronic commerce courselecture one. Pdf
MYSQL Presentation for SQL database connectivity
Encapsulation theory and applications.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
sap open course for s4hana steps from ECC to s4
MIND Revenue Release Quarter 2 2025 Press Release
NewMind AI Weekly Chronicles - August'25 Week I
Machine learning based COVID-19 study performance prediction
Mobile App Security Testing_ A Comprehensive Guide.pdf
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
20250228 LYD VKU AI Blended-Learning.pptx
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Encapsulation_ Review paper, used for researhc scholars
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
cuic standard and advanced reporting.pdf

Stackless Python In Eve

  • 1. Stackless Python in EVE Kristján Valur Jónsson [email_address] CCP Games inc.
  • 2. EVE MMORPG Space game Client / server Single shard massive server 130.000 active players, >24.000 concurrent users World concurrency record on a shard 425,537 lines of Python code and growing. client: 158,656 server: 218,645 common: 48,236 Possible only because of Stackless Python
  • 3. The Tranquility cluster 400 GHz CPU / 200 Gb RAM 2 Routers (CISCO Alteon) 14 Proxy servers (IBM Blade) 55 Sol servers (IBM x335) 2 DB servers (clustered, IBM Brick x445) FastT600 Fiber, 56 x FC 15k disks, DS4300 + 3*EXP700 Windows 2000, MS SQL Server Currently being upgraded AMD x64 IBM Blade RAMSAN gizmo 64 bit binaries
  • 4. EVE Architecture COM-like basic architecture Python tightly integrated at an early stage Home-grown wrapping of BLUE objects
  • 5. Stackless in EVE BLUE foundation: robust, but cumbersome RAD Stackless Python: Python and so much more EVE is inconceivable without Stackless Everyone is a programmer Interactive development. Files reloaded automatically Classes updated with new methods Demo:
  • 6. Stackless Python Tasklets Threads of execution. Not OS threads Lightweight No pre-emption No memory fragmentation due to stacks Channels Tasklet rendezvous point Data passing Scheduling Synchronization
  • 7. Stackless? No C stack Python stack in linked frame objects Tasklet switching by swapping frame chain Compromise stackless where possible. C stack whisked away if necessary
  • 9. Channel semantics Send on a channel with no receiver blocks tasklet. Send on a channel with a (blocked) receiver, suspends tasklet and runs receiver immediately. Sender runs again in due course. Symmetric behaviour. “ Balance”, can have a queue of readers or writers. Conceptually similar to Unix pipes
  • 10. Channel semantics, cont. Scheduling semantics are precise: A blocked tasklet is run immediately Usable as a building block: semaphores mutex critical section condition variables
  • 11. The main loop Establish stackless context int WinMain(...) { PyObject *myApp = new EveApp(); PyObject *r = PyStackless_CallMethod_Main(myApp, “WinMain”, 0); return PyInt_AsLong( r );
  • 12. Regular Windows message loop Runs in Stackless context The “Main Tasklet” The main loop cont. PyObject* EveApp::WinMain(PyObject *self, PyObject *args) { while(!mExit) { PyOS->ExecFile("script:/sys/autoexec.py"); MSG msg; while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){ TranslateMessage(&msg); DispatchMessage(&msg); } for (TickIt i = mTickers.begin(; i != mTickers.end(); i++) i->mCb-> OnTick (mTime, (void*)taskname); } }
  • 13. Autoexec.py import blue def Startup(): import service srvMng = service.ServiceManager() run = ["dataconfig", "godma", “ui", …] srvMng.Run(run) #Start up the client in a tasklet! if CheckDXVersion(): import blue blue.pyos. CreateTasklet (Startup, (), {})
  • 14. Tickers Tickers are BLUE modules: Trinity (the renderer) Netclient DB (on the server) Audio PyOS (special python services) …
  • 15. The PyOS tick: Runs fresh tasklets (sleepers awoken elsewhere) Tick() { … mSynchro->Tick() PyObject *watchdogResult; do { watchdogResult = PyStackless_RunWatchdog(20000000); if (!watchdogResult) PyFlushError("PumpPython::Watchdog"); Py_XDECREF(watchdogresult); } while (!watchdogResult);
  • 16. blue.pyos.synchro Synchro: Provides Thread-like tasklet utilities: Sleep(ms) Yield() BeNice()
  • 17. Sleep: A python script makes the call blue.pyos.Sleep(200) C++ code runs: Main tasklet check sleeper = New Sleeper(); mSleepers.insert(sleeper); PyObject *r = PyChannel_Receive(sleeper->mChannel); Another tasklet runs blue.pyos.synchro cont.
  • 18. blue.pyos.synchro, ctd. Main tasklet in windows loop enters PyOS::Tick() mSleepers are examined for all that are due we do: mSleepers.remove(sleeper); PyChannel_Send(sleepers.mChannel, Py_NONE); Main tasklet is suspended (but runnable), sleeper runs.
  • 19. Points to note: A tasklet goes to sleep by calling PyChannel_Receive() on a channel which has no pending sender. It will sleep there (block) until someone sends Typically the main tasklet does this, doing PyChannel_Send() on a channel with a reader Ergo: The main tasklet may not block
  • 20. Socket Receive Use Windows asynchronous file API Provide a synchronous python API. A python script calls Read(). Tasklet may be blocked for a long time, (many frames) other tasklets continue running. Do this using channels.
  • 21. Receive, cont. Python script runs: data = socket.Read() C code executes the request: Request *r = new Request(this); WSAReceive(mSocket, …); mRequests->insert( r ); PyChannel_Receive(r->mChannel); Tasklet is blocked
  • 22. Receive, cont. Socket server is ticked from main loop For all requests that are marked completed, it transfers the data to the sleeping tasklets: PyObject *r = PyString_FromStringAndSize(req->mData, req->mDataLen); PyChannel_Send(req->mChannel, r); Py_DECREF(data); delete req; The sleeping tasklet wakes up, main tasklet is suspended (but runnable)
  • 24. Main Tasklet The one running the windows loop Can be suspended, allowing other tasklets to run Can be blocked, as long as there is another tasklet to unblock it (dangerous) Is responsible for waking up Sleepers, Yielders, IO tasklets, etc. therefore cannot be one of them Is flagged as non-blockable ( stackless.get_current().block_trap = True )
  • 25. Channel magic Channels perform the stackless context switch. If there is a C stack in the call chain, it will magically swap the stacks. Your entire C stack (with C and python invocations) is whisked away and stored, to be replaced with a new one. This allows stackless to simulate cooperative multi-threading
  • 26. Co-operative multitasking Context is switched only at known points. In Stackless, this is channel.send() and channel.receive() Also synchro.Yield(), synchro.Sleep(), BeNice(), socket and DB ops, etc. (all boil down to send() and receive() ) No unexpected context switches Almost no race conditions Program like you are single-threaded Very few exceptions. This extends to C state too!
  • 27. Tasklets Tasklets are cheap 70,000 on a server node Used liberally to reduce perceived lag UI events forked out to tasklets A click can have heavy consequences. Heavy logic DB Access Networks access special rendering tasks forked out to tasklets. controlling an audio track “ tasklet it out” Use blue.pyos.synchro.BeNice() in large loops
  • 28. Example: UI Event: Main tasklet receives window messages such as WM_LBUTTONUP Trinity invokes handler on UI elements or global handler Handler “tasklets out” any action to allow main thread to continue immediately. def OnGlobalUp(self, *args): mo = eve.triapp.uilib.mouseOver if mo in self.children: uthread.new(mo._OnClick) class Action(xtriui.QuickDeco): def _OnClick(self, *args): pass
  • 29. What we don’t understand: Why isn’t everyone using Stackless Python?
  • 30. That’s all For more info: http://www.ccpgames.com http://www.eve-online.com http://www.stackless.com [email_address]