Skip to content

No parallelism with extra scheduling overhead #21

@DXist

Description

@DXist

I noticed the signature signing and verification code uses futures::future::join_all, which helps to run IO-bound futures concurrently.

Signature signing/verification code is CPU-bound - for example, elliptic curve cryptography for ECDSA-P256 signatures could take 100-300 microseconds, which is an order of magnitude longer than tokio::task::spawn_blocking blocking thread handoff (~<10 microseconds).

Effectively, the current code runs sequentially, but adds join_all scheduling overhead.

My recommendations:

  • run CPU-bound code sequentially in a loop on an async worker thread by default (default-features = false), which is a pragmatic choice for single-signature per request use cases.
  • add support for a configurable limit of request signatures to control spent CPU resources. Reject requests exceeding the limit before signature verification. Allow at most one signature per request by default.
  • The default loop works well if offloaded to a dedicated rayon thread pool by the caller
  • For users, not managing custom thread pools introduce a runtime-agnostic trait for offloading CPU-bound work on a blocking thread or provide integrations for popular runtimes like Tokio. The risk is too high default parallelism (512) of the blocking pool, designed for offloading blocking IO.
    • allow sequential offload by default, which is good to control per-request resources. Add it as a feature dependency for the default feature.
    • optionally allow parallel offload of multiple request signatures to multiple blocking threads - not sure if anybody wants this setup, it's more suitable for trusted clients

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions