Abstract

Usage of asynchronous Rust gives Iroha as a highly I/O bounded application greats benefits in usage of system resources.

At the same time when we have more asynchronous tasks ready to be executed then workers able to execute them, we may have undesirable issues and potential violation of SLA.

On the start of the project we made a decision to use `futures` API directly, while having `async-std` only as a runtime. While project matures we are ready to make a final decision and start using runtime API directly, still do not forcing clients to do so.

Async-std looks like a better choice in terms of support, simplicity and alignment with our needs.

Introduction

Working with `client_add_asset_quantity_to_existing_asset_should_increase_asset_amount_on_another_peer` test we found that time to propagate block between peers is unpredictable while usage of resources suffer from `loop` and `thread::sleep` inside asynchronous tasks.

Methods and Materials

We already have benchmarks for the solution based on `futures` API (Mutex, ThreadPool, etc) and interest for usage of `async-std` API (indirect Pools, Multiple Producers Multiple Consumers, RwLocks).

Threads Pooling

Because `async-std` hides tasks scheduling across workers inside it's internals (https://docs.rs/async-std/1.5.0/src/async_std/task/executor/pool.rs.html#27) we assume that our code will be cleaner without direct usage and passing of ThreadPool clones:

  7 pub struct Torii {         
  8     url: String,           
  9     pool_ref: ThreadPool,  
 10     world_state_view: Arc<Mutex<WorldStateView>>,
 11     transaction_sender: Arc<Mutex<TransactionSender>>,
 12     message_sender: Arc<Mutex<MessageSender>>,
 13 }
...
 37         let state = ToriiState {        
 38             pool: self.pool_ref.clone(),   
...

Using https://docs.rs/async-std/1.5.0/async_std/task/fn.spawn.html instead: `task::spawn(async {`

Channels

`futures` API provides only MPSC channels, while `async-std` can give us MPMC channels: https://docs.rs/async-std/1.5.0/async_std/sync/fn.channel.html 

Locks

While `futures` provide Mutex, `async-std` gives an ability to use ReadWriteLock

Results

Usage of async-std with the same code does not affect the performance. So we decided to move onto async-std to get other benefits.

  • No labels

2 Comments

  1. Based on votes - we will give it a try.

  2. Benchmarks:

      1 query-reqeuests/query   time:   [487.17 us 491.89 us 496.74 us]
      2                         thrpt:  [64.876 KiB/s 65.516 KiB/s 66.151 KiB/s]
      3                  change:
      4                         time:   [-5.1375% -3.0467% -1.0593%] (p = 0.00 < 0.05)
      5                         thrpt:  [+1.0706% +3.1424% +5.4157%]
      6 channel size 100
      7 query-reqeuests/query   time:   [483.98 us 489.87 us 495.88 us]
      8                         thrpt:  [64.988 KiB/s 65.786 KiB/s 66.587 KiB/s]
      9                  change:
     10                         time:   [-2.6205% -0.8214% +1.0506%] (p = 0.39 > 0.05)
     11                         thrpt:  [-1.0397% +0.8282% +2.6910%]
     12 channel size 10
     13 query-reqeuests/query   time:   [491.90 us 499.11 us 507.16 us]
     14                         thrpt:  [63.543 KiB/s 64.568 KiB/s 65.515 KiB/s]
     15                  change:
     16                         time:   [+0.0494% +2.5830% +5.0515%] (p = 0.04 < 0.05)
     17                         thrpt:  [-4.8086% -2.5180% -0.0494%]
     18 channel size 1000
     19 query-reqeuests/query   time:   [487.45 us 492.44 us 497.76 us]
     20                         thrpt:  [64.743 KiB/s 65.442 KiB/s 66.113 KiB/s]
     21                  change:
     22                         time:   [-2.8600% -0.9175% +1.1164%] (p = 0.38 > 0.05)
     23                         thrpt:  [-1.1041% +0.9260% +2.9443%]
     24                         No change in performance detected.
     25 channel size 10000
     26 query-reqeuests/query   time:   [485.94 us 490.92 us 495.83 us]
     27                         thrpt:  [64.996 KiB/s 65.645 KiB/s 66.318 KiB/s]
     28                  change:
     29                         time:   [-0.9862% +1.2005% +3.6131%] (p = 0.33 > 0.05)
     30                         thrpt:  [-3.4871% -1.1862% +0.9960%]
     31                         No change in performance detected.
     32 futures