-
Notifications
You must be signed in to change notification settings - Fork 40
2023_03
In event-driven design, a function is executed when an event arrives.
There are three function execution strategies:
Strategy | Advantage | Disadvantage |
---|---|---|
Kernel threads | Highest performance in terms of operations per seconds |
Lower number of concurrent threads due to high context switching overheads |
Coroutine | Highest throughput in terms of concurrent users served by virtual threads concurrently |
Not suitable for long running tasks |
Suspend function | Synchronous "non-blocking" for RPC (request-response) that makes code easier to read and maintain |
Not suitable for long running tasks |
Java support preemptive multitasking natively. It leverages the multiple cores of CPU to execute application functions in parallel.
While preemptive multitasking fully utilizes the CPU, its context switching overheads may increase as the number of kernel threads grow. As a rule of thumb, you should control the maximum number of kernel threads to less than 200.
When you have more concurrent requests, your application may slow down because some functions are blocked when the number of concurrent kernel threads is reached.
Kernel threads are precious and finite resources. When your function is computational intensive or making external HTTP or database calls in a synchronous blocking manner, you may use it with a small number of worker instances.
To rapidly release kernel thread resources, you can write "asynchronous" code. i.e. for event-driven programming, you can use send event to another function asynchronously, and you can create a callback function to listen to responses.
Coroutines are executed in an event loop using a single kernel thread. As a result, the system can handle tens of thousands of coroutines running concurrently.
Since coroutine is running in a single thread, you must avoid writing "blocking" code because it would slow down the whole application significantly.
If your function can finish processing very quickly, coroutine is ideal.
A suspend function is a coroutine that can be suspended and resumed. The best use case for a suspend function is for handling of "sequential non-blocking" request-response. This is the same as "async/await" in node.js and other programming language.