Skip to content

Commit

Permalink
improve: rework VoiceModel (#830)
Browse files Browse the repository at this point in the history
* improve: rework `VoiceModel`

* diffを抑える工夫

* Minor refactor

* `.ref_map(…)` → `.each_ref().map(…)`

* `collect_results` → `collect`, `collect_future_results` → `join`

* `join`から`Result`の`collect`を分離

* fixup! diffを抑える工夫

* `blocking`版はblockingクレートに依存しない

* async_zip v0.0.17に備える

* `SmolBlocking` → `BlockingThreadPool`

* Minor refactor

* `futures_lite::future::block_on`を`.block_on()`として使えるようにする

* `join` → `join_all`

#830 (comment)

* `find_index` → `find_entry_index`

#830 (comment)

* "join"しない

* Minor refactor

* `crate::asyncs`にdoc

#830 (comment)

* `Unstoppable` → `SingleTasked`

#830 (comment)
https://chatgpt.com/share/cdae540e-5751-43a5-a1fb-ac1f17d6a1b8
  • Loading branch information
qryxip authored Sep 12, 2024
1 parent 088ef7e commit e07c795
Show file tree
Hide file tree
Showing 16 changed files with 726 additions and 340 deletions.
112 changes: 106 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ anstream = { version = "0.5.0", default-features = false }
anstyle-query = "1.0.0"
anyhow = "1.0.65"
assert_cmd = "2.0.8"
async-fs = "2.1.2"
async_zip = "=0.0.16"
bindgen = "0.69.4"
binstall-tar = "0.4.39"
Expand All @@ -33,10 +34,10 @@ enum-map = "3.0.0-beta.1"
eyre = "0.6.8"
flate2 = "1.0.25"
fs-err = "2.11.0"
futures = "0.3.26"
futures-core = "0.3.25"
futures-util = "0.3.25"
futures-lite = "2.2.0"
futures-io = "0.3.28"
heck = "0.4.1"
humansize = "2.1.2"
indexmap = "2.0.0"
Expand Down
7 changes: 4 additions & 3 deletions crates/voicevox_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ link-onnxruntime = []

[dependencies]
anyhow.workspace = true
async-fs.workspace = true
async_zip = { workspace = true, features = ["deflate"] }
camino.workspace = true
const_format.workspace = true
Expand All @@ -27,14 +28,15 @@ easy-ext.workspace = true
educe.workspace = true
enum-map.workspace = true
fs-err = { workspace = true, features = ["tokio"] }
futures.workspace = true
futures-io.workspace = true
futures-lite.workspace = true
futures-util = { workspace = true, features = ["io"] }
indexmap = { workspace = true, features = ["serde"] }
itertools.workspace = true
jlabel.workspace = true
ndarray.workspace = true
open_jtalk.workspace = true
ouroboros.workspace = true
rayon.workspace = true
ref-cast.workspace = true
regex.workspace = true
serde = { workspace = true, features = ["derive", "rc"] }
Expand All @@ -49,7 +51,6 @@ tracing.workspace = true
uuid = { workspace = true, features = ["v4", "serde"] }
voicevox-ort = { workspace = true, features = ["download-binaries", "__init-for-voicevox"] }
voicevox_core_macros = { path = "../voicevox_core_macros" }
zip.workspace = true

[dev-dependencies]
heck.workspace = true
Expand Down
82 changes: 82 additions & 0 deletions crates/voicevox_core/src/asyncs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! 非同期操作の実装の切り替えを行う。
//!
//! 「[ブロッキング版API]」と「[非同期版API]」との違いはここに集約される
//! …予定。現在は[`crate::voice_model`]のみで利用している。
//!
//! # Motivation
//!
//! [blocking]クレートで駆動する非同期処理はランタイムが無くても動作する。そのため非同期版APIを
//! もとにブロッキング版APIを構成することはできる。しかし将来WASMビルドすることを考えると、スレッド
//! がまともに扱えないため機能しなくなってしまう。そのためWASM化を見越したブロッキング版APIのため
//! に[`SingleTasked`]を用意している。
//!
//! [ブロッキング版API]: crate::blocking
//! [非同期版API]: crate::tokio
//! [blocking]: https://docs.rs/crate/blocking

use std::{
io::{self, Read as _, Seek as _, SeekFrom},
path::Path,
pin::Pin,
task::{self, Poll},
};

use futures_io::{AsyncRead, AsyncSeek};

pub(crate) trait Async: 'static {
async fn open_file(path: impl AsRef<Path>) -> io::Result<impl AsyncRead + AsyncSeek + Unpin>;
}

/// エグゼキュータが非同期タスクの並行実行をしないことを仮定する、[`Async`]の実装。
///
/// [ブロッキング版API]用。
///
/// # Performance
///
/// `async`の中でブロッキング操作を直接行う。そのためTokioやasync-stdのような通常の非同期ランタイム
/// 上で動くべきではない。
///
/// [ブロッキング版API]: crate::blocking
pub(crate) enum SingleTasked {}

impl Async for SingleTasked {
async fn open_file(path: impl AsRef<Path>) -> io::Result<impl AsyncRead + AsyncSeek + Unpin> {
return std::fs::File::open(path).map(BlockingFile);

struct BlockingFile(std::fs::File);

impl AsyncRead for BlockingFile {
fn poll_read(
mut self: Pin<&mut Self>,
_: &mut task::Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
Poll::Ready(self.0.read(buf))
}
}

impl AsyncSeek for BlockingFile {
fn poll_seek(
mut self: Pin<&mut Self>,
_: &mut task::Context<'_>,
pos: SeekFrom,
) -> Poll<io::Result<u64>> {
Poll::Ready(self.0.seek(pos))
}
}
}
}

/// [blocking]クレートで駆動する[`Async`]の実装。
///
/// [非同期版API]用。
///
/// [blocking]: https://docs.rs/crate/blocking
/// [非同期版API]: crate::tokio
pub(crate) enum BlockingThreadPool {}

impl Async for BlockingThreadPool {
async fn open_file(path: impl AsRef<Path>) -> io::Result<impl AsyncRead + AsyncSeek + Unpin> {
async_fs::File::open(path).await
}
}
16 changes: 16 additions & 0 deletions crates/voicevox_core/src/future.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use std::future::Future;

use easy_ext::ext;

/// `futures_lite::future::block_on`を、[pollster]のように`.block_on()`という形で使えるようにする。
///
/// [pollster]: https://docs.rs/crate/pollster
#[ext(FutureExt)]
impl<F: Future> F {
pub(crate) fn block_on(self) -> Self::Output
where
Self: Sized,
{
futures_lite::future::block_on(self)
}
}
Loading

0 comments on commit e07c795

Please sign in to comment.