Skip to content

Commit

Permalink
Replaced BucketProvider.
Browse files Browse the repository at this point in the history
  • Loading branch information
FelixRilling committed Dec 26, 2023
1 parent fa32310 commit c30d51d
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 130 deletions.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ public LoggingBucketListener(String bucketName) {

@Override
public void onConsumed(long tokens) {
LOGGER.trace("Consumed {} tokens from bucket '{}'.", tokens, bucketName);
LOGGER.trace("Consumed {} token(s) from bucket '{}'.", tokens, bucketName);
}

@Override
public void onRejected(long tokens) {
LOGGER.trace("Rejected consumption of {} tokens from bucket '{}'.", tokens, bucketName);
LOGGER.trace("Rejected consumption of {} token(s) from bucket '{}'.", tokens, bucketName);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package dev.rilling.musicbrainzenricher.api.discogs;

import dev.rilling.musicbrainzenricher.api.LoggingBucketListener;
import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import net.jcip.annotations.ThreadSafe;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

import java.time.Duration;

@Configuration
@ThreadSafe
class DiscogsApiConfiguration {

@Bean("discogsBucket")
Bucket discogsBucket(Environment environment) {
boolean authenticated = environment.containsProperty("musicbrainz-enricher.discogs.token");

// See https://www.discogs.com/developers/#page:home,header:home-rate-limiting,
// further slowed down to adapt for network fluctuations.
int capacity = authenticated ? 60 : 25;
Bandwidth bandwidth = Bandwidth.simple(capacity, Duration.ofSeconds(90));

return Bucket.builder().addLimit(bandwidth).build().toListenable(new LoggingBucketListener("discogs"));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package dev.rilling.musicbrainzenricher.api.discogs;

import dev.rilling.musicbrainzenricher.api.BucketService;
import io.github.bucket4j.Bucket;
import net.jcip.annotations.ThreadSafe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
Expand All @@ -21,22 +22,19 @@ public class DiscogsQueryService {

private static final Logger LOGGER = LoggerFactory.getLogger(DiscogsQueryService.class);

private final DiscogsBucketProvider discogsBucketProvider;
private final BucketService bucketService;
private final Bucket bucket;
private final RestClient restClient;

DiscogsQueryService(Environment environment,
DiscogsBucketProvider discogsBucketProvider,
BucketService bucketService) {
this.discogsBucketProvider = discogsBucketProvider;
this.bucketService = bucketService;
@Qualifier("discogsBucket") Bucket bucket) {
this.bucket = bucket;

restClient = createRestClient(environment);
}


public Optional<DiscogsRelease> lookUpRelease( final String id) {
bucketService.consumeSingleBlocking(discogsBucketProvider.getBucket());
bucket.asBlocking().consumeUninterruptibly(1);

try {
return Optional.ofNullable(restClient.get().uri("/releases/{id}", Map.of("id", id)).accept().retrieve().body(DiscogsRelease.class));
Expand All @@ -48,7 +46,7 @@ public Optional<DiscogsRelease> lookUpRelease( final String id) {


public Optional<DiscogsMaster> lookUpMaster( final String id) {
bucketService.consumeSingleBlocking(discogsBucketProvider.getBucket());
bucket.asBlocking().consumeUninterruptibly(1);

try {
return Optional.ofNullable(restClient.get().uri("/masters/{id}", Map.of("id", id)).retrieve().body(DiscogsMaster.class));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package dev.rilling.musicbrainzenricher.api.spotify;

import dev.rilling.musicbrainzenricher.api.LoggingBucketListener;
import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import net.jcip.annotations.ThreadSafe;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;

@Configuration
@ThreadSafe
class SpotifyApiConfiguration {

@Bean("spotifyBucket")
Bucket spotifyBucket() {
// https://developer.spotify.com/documentation/web-api/guides/rate-limits/
// Spotify itself does not disclose an exact rate, this is only a guess to avoid running into it.
Bandwidth bandwidth = Bandwidth.simple(10, Duration.ofMinutes(1));

return Bucket.builder().addLimit(bandwidth).build().toListenable(new LoggingBucketListener("spotify"));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package dev.rilling.musicbrainzenricher.api.spotify;

import dev.rilling.musicbrainzenricher.api.BucketService;
import io.github.bucket4j.Bucket;
import jakarta.annotation.Nullable;
import net.jcip.annotations.GuardedBy;
import net.jcip.annotations.ThreadSafe;
import org.apache.hc.core5.http.ParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import se.michaelthelin.spotify.SpotifyApi;
Expand All @@ -27,8 +28,7 @@ public class SpotifyQueryService {

private static final Logger LOGGER = LoggerFactory.getLogger(SpotifyQueryService.class);

private final SpotifyBucketProvider spotifyBucketProvider;
private final BucketService bucketService;
private final Bucket bucket;

// May be null if no credentials exist.
// Note that getAuthorizedApiClient() should be used for access.
Expand All @@ -42,10 +42,8 @@ public class SpotifyQueryService {
private final Object reAuthLock = new Object();

SpotifyQueryService(Environment environment,
SpotifyBucketProvider spotifyBucketProvider,
BucketService bucketService) {
this.spotifyBucketProvider = spotifyBucketProvider;
this.bucketService = bucketService;
@Qualifier("spotifyBucket") Bucket bucket) {
this.bucket = bucket;

apiClient = createApiClient(environment);
}
Expand All @@ -57,7 +55,7 @@ public Optional<Album> lookUpRelease(final String id) {
return Optional.empty();
}

bucketService.consumeSingleBlocking(spotifyBucketProvider.getBucket());
bucket.asBlocking().consumeUninterruptibly(1);

try {
GetAlbumRequest request = getAuthorizedApiClient().getAlbum(id).build();
Expand Down

0 comments on commit c30d51d

Please sign in to comment.