Skip to content

Commit 0e877dc

Browse files
committed
perf(sync): tune Spotify search concurrency
Start the opencode resolver while the Spotify playlist snapshot loads so matching can begin sooner. Raise the default search concurrency from 8 to 10 for better throughput while avoiding the rate limits seen at 20.
1 parent cab3fca commit 0e877dc

3 files changed

Lines changed: 39 additions & 23 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ Options:
121121
--opencode-variant <VARIANT> opencode variant
122122
--opencode-base-url <URL> Existing opencode server URL
123123
--dry-run Print planned Spotify mutations without applying them
124-
--concurrency <CONCURRENCY> Maximum concurrent Spotify search requests [default: 8]
124+
--concurrency <CONCURRENCY> Maximum tracks to search on Spotify at once [default: 10]
125125
--limit <LIMIT> Development/debug cap for tracks to process
126126
-h, --help Print help
127127
-V, --version Print version

src/cli.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use clap::Parser;
44

55
use crate::error::{AppError, Result};
66

7+
const DEFAULT_CONCURRENCY: usize = 10;
8+
79
#[derive(Debug, Parser)]
810
#[command(version, about = "Mirror a YouTube playlist to Spotify")]
911
pub struct Cli {
@@ -62,8 +64,8 @@ pub struct Cli {
6264
#[arg(long)]
6365
pub dry_run: bool,
6466

65-
/// Maximum number of concurrent Spotify search requests.
66-
#[arg(long, default_value_t = 8)]
67+
/// Maximum number of tracks to search on Spotify at once.
68+
#[arg(long, default_value_t = DEFAULT_CONCURRENCY)]
6769
pub concurrency: usize,
6870

6971
/// Development/debug cap for the number of YouTube tracks to process.

src/main.rs

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,21 @@ async fn run(cli: Cli) -> Result<()> {
4545
)?;
4646

4747
let playlist_name = explicit_name.as_deref().unwrap_or(&youtube_playlist.title);
48-
let mut spotify_state = load_spotify_playlist(
49-
&progress,
50-
spotify,
51-
playlist_name,
52-
cli.dry_run,
53-
explicit_name.is_none(),
54-
)
55-
.await?;
48+
progress.set_phase(if cli.use_opencode() {
49+
"loading Spotify playlist and opencode resolver"
50+
} else {
51+
"loading Spotify playlist"
52+
});
53+
let (mut spotify_state, opencode) = tokio::try_join!(
54+
load_spotify_playlist(
55+
&progress,
56+
spotify,
57+
playlist_name,
58+
cli.dry_run,
59+
explicit_name.is_none(),
60+
),
61+
connect_opencode(&cli, &progress)
62+
)?;
5663

5764
if !cli.dry_run && spotify_state.playlist_would_be_created {
5865
let (playlist, current, playlist_would_be_created) =
@@ -70,18 +77,6 @@ async fn run(cli: Cli) -> Result<()> {
7077
} = spotify_state;
7178

7279
progress.set_phase("searching and matching Spotify tracks");
73-
let opencode = if cli.use_opencode() {
74-
Some(
75-
opencode::OpencodeResolver::connect(opencode::OpencodeConfig::new(
76-
cli.opencode_base_url.clone(),
77-
cli.opencode_model.clone(),
78-
cli.opencode_variant.clone(),
79-
))
80-
.await?,
81-
)
82-
} else {
83-
None
84-
};
8580
let matches = matching::resolve_playlist(
8681
&spotify,
8782
&youtube_playlist.tracks,
@@ -200,6 +195,25 @@ async fn connect_spotify(cli: &Cli, progress: &Progress) -> Result<SpotifyClient
200195
spotify
201196
}
202197

198+
async fn connect_opencode(
199+
cli: &Cli,
200+
progress: &Progress,
201+
) -> Result<Option<opencode::OpencodeResolver>> {
202+
if !cli.use_opencode() {
203+
return Ok(None);
204+
}
205+
206+
let spinner = progress.spinner("connecting opencode resolver");
207+
let resolver = opencode::OpencodeResolver::connect(opencode::OpencodeConfig::new(
208+
cli.opencode_base_url.clone(),
209+
cli.opencode_model.clone(),
210+
cli.opencode_variant.clone(),
211+
))
212+
.await;
213+
spinner.finish_and_clear();
214+
resolver.map(Some)
215+
}
216+
203217
async fn load_spotify_playlist(
204218
progress: &Progress,
205219
spotify: SpotifyClient,

0 commit comments

Comments
 (0)