Skip to content

refactor: use gstd::message_loop only for async ctors and service methods#939

Merged
techraed merged 19 commits intomasterfrom
st/issue-63
Jun 16, 2025
Merged

refactor: use gstd::message_loop only for async ctors and service methods#939
techraed merged 19 commits intomasterfrom
st/issue-63

Conversation

@techraed
Copy link
Contributor

@techraed techraed commented May 28, 2025

Resolves #63

The PR suggests not using async runtime from the gstd by default for any message sent to program. The separation between calls that require async runtime and sync execution was benched (see comments below) and it was concluded that the separation saves 100-200kk of gas. The changes in code generation are the following:

  1. InvocationIo trait now has ASYNC constant. service and program macros define the ASYNC value for each constructor and service method that implements InvocationIo.
  2. Service exposure now implements check_asyncness method that accepts encoded service method route and params and returns whether the method is async. Basically, returns ASYNC const of the InvocationIo implementor.
  3. service macro now generates 2 try_handle methods: try_handle and try_handle_async. The former invokes sync method, and the latter - async ones. Methods also call try_handle* methods of base services.
  4. Commands and Queries has ASYNC const in their impl items. By default, the ASYNC is false. If there are any commands and queries, their InvocationIo::ASYNC values will be used.
  5. ServiceMeta trait now also has ASYNC constant. The value is generated from Commands::ASYNC, Queries::ASYNC and ASYNC values of base services, which also implement the ServiceMeta trait.
  6. ConstructorsMeta now also has ASYNC constant in its impl item. The value of the constant is defined by InvocationIo::ASYNC of constructors (params structs).
  7. program macro never uses gstd::async_init or gstd::async_main. Instead generates plain init, handle, handle_reply and handle_signal.
  8. init method invokes constructors. If a constructor is an async, then gstd::message_loop will be used. Otherwise a simple sync constructor call will be generated.
  9. ProgramMeta trait now also has ASYNC constant. It's value is defined from ConstructorsMeta::ASYNC and ServiceMeta::ASYNC of programs services. All in all it's a logical operation where each operand is an ASYNC value for each constructor and service method (params struct)
  10. handle_signal is always generated except for cases when ethexe feature is on
  11. handle_reply is always generated. Both in handle_reply and handle_signal hooks from gstd are called only if ProgramMeta::ASYNC value is true. The latter means that there's somewhere in program gstd::message_loop is used for async methods execution. So due to the fact that async methods are from gstd and the wait/wake logic is already handled by hooks in gstd, these hooks must be used in handle_reply and handle_signal to implement proper async/await experience for developers.
  12. For ethexe feature there are several corresponding changes:
    • try_handle_solidity and try_handle_solidity_async are also implemented pretty same as try_handle*
    • match_ctor_solidity is now a sync function that in case the constructor is async, invokes it inside gstd::message_loop.

TODO:

  1. C̶h̶e̶c̶k̶ ̶c̶r̶o̶s̶s̶-̶p̶r̶o̶g̶r̶a̶m̶ ̶c̶o̶m̶m̶u̶n̶i̶c̶a̶t̶i̶o̶n̶ ̶i̶n̶ ̶̶e̶x̶a̶m̶p̶l̶e̶s̶̶ ̶(̶a̶n̶d̶ ̶̶e̶t̶h̶e̶x̶e̶̶)̶ (UPD: done)

@techraed techraed self-assigned this May 28, 2025
@techraed
Copy link
Contributor Author

By the b3eb14 it was agreed to implement sync try_handle, because it gives about 200-300 million gas surplus. This was measured both using computational heavy/light tasks

@techraed techraed changed the title refactor: use sync version of try_handle if service has no async methods refactor: use gstd::message_loop only for async ctors and service methods Jun 11, 2025
@techraed techraed merged commit 8281aca into master Jun 16, 2025
3 checks passed
@techraed techraed deleted the st/issue-63 branch June 16, 2025 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

macros: Avoid generating async methods when there are no ones in service impl

2 participants