Though MAY is easy to use, but it does have some restrictions. And these restrictions are hard to remove. You must know them very well before writing any user coroutine code.
If you are not aware of them, your application will easily lost performance or even trigger undefined behaviors.
I will list 4 rules bellow
Don't call thread blocking APIs
This is obvious. Calling thread block version APIs in coroutine would halt the worker thread and can't schedule other ready coroutines. It will hurt the performance.
Those block version APIs includes:
- io block operation such as socket
- sync primitive APIs such as
- thread related APIs such as
- and functions that call those block version api internally, such as third party libraries
The solution is calling MAY API instead. And port necessary dependency libraries to May compatible version.
Don't use Thread Local Storage
Access TLS in coroutine would trigger undefined behavior and it will be hard to debug the issue.
There is a post already cover this topic. And the solution is using Coroutine Local Storage instead.
But if you are depending on a third party function that uses TLS you likely get hurt sooner or later. There is an issue that discuss this a bit.
libstd APIs is safe in MAY coroutines.
Don't run CPU bound tasks for long time
MAY scheduler runs coroutines cooperatively which means if a running coroutine doesn't yield out, it will occupy the running thread and other coroutines will not be scheduled on that thread.
MAY APIs will automatically yield out if necessary, so this is not a problem. But if you are running a long time CPU bound task in coroutine, you'd better call
coroutine::yield_now() manually at appropriate point.
Don't exceed the stack
MAY doesn't support automatic stack increasing. Each coroutine alloc a limited stack size for its own. If the coroutine exceeds it's stack size, it will trigger undefined behavior.
So that you should avoid calling recursive functions in coroutine. Recursive function calls would easily exhaust your stack.
And you also should avoid calling functions that internally use a big stack space like
may::config()::set_stack_size() can be used to set the default stack size for all coroutines. And you can use
may::coroutine::Builder to specify a single coroutine stack size.
For how to tune the coroutine stack size, please ref this
Develop a coroutine library in rust is not an easy task. MAY can't prevent users doing wrong things. So you should know those caveats clearly before using the library. I hope those restrictions will not prevent you from using the library