item service: always use last known price, and queue price updates instead

This commit is contained in:
Adam
2018-02-16 23:28:03 -05:00
parent 4bcfdc5360
commit 77a3f48627
4 changed files with 51 additions and 15 deletions

View File

@@ -44,11 +44,13 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.sql2o.Sql2o;
import org.sql2o.converters.Converter;
import org.sql2o.quirks.NoQuirks;
@SpringBootApplication
@EnableScheduling
@Slf4j
public class SpringBootWebApplication extends SpringBootServletInitializer
{

View File

@@ -176,25 +176,30 @@ public class ItemController
.build();
}
}
else if (priceEntry == null)
{
// Price is unknown
List<PriceEntry> prices = itemService.fetchPrice(itemId);
if (prices == null || prices.isEmpty())
{
cachedEmpty.put(itemId, itemId);
return ResponseEntity.notFound()
.header(RUNELITE_CACHE, "MISS")
.build();
}
// Get the most recent price
priceEntry = prices.get(prices.size() - 1);
hit = false;
}
else
{
Instant cacheTime = now.minus(CACHE_DUATION);
if (priceEntry == null || priceEntry.getFetched_time().isBefore(cacheTime))
if (priceEntry.getFetched_time().isBefore(cacheTime))
{
// Price is unknown, or was fetched too long ago
List<PriceEntry> prices = itemService.fetchPrice(itemId);
if (prices == null || prices.isEmpty())
{
cachedEmpty.put(itemId, itemId);
return ResponseEntity.notFound()
.header(RUNELITE_CACHE, "MISS")
.build();
}
// Get the most recent price
priceEntry = prices.get(prices.size() - 1);
hit = false;
// Queue a check for the price
itemService.queueLookup(itemId);
}
}

View File

@@ -32,6 +32,7 @@ import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI;
import net.runelite.http.api.item.ItemType;
@@ -40,6 +41,7 @@ import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.sql2o.Connection;
import org.sql2o.Query;
@@ -78,7 +80,10 @@ public class ItemService
private static final String CREATE_PRICES_FK = "ALTER TABLE `prices`\n"
+ " ADD CONSTRAINT `item` FOREIGN KEY (`item`) REFERENCES `items` (`id`);";
private static final int MAX_PENDING_LOOKUPS = 512;
private final Sql2o sql2o;
private final ConcurrentLinkedQueue<Integer> pendingPriceLookups = new ConcurrentLinkedQueue<>();
@Autowired
public ItemService(@Qualifier("Runelite SQL2O") Sql2o sql2o)
@@ -339,4 +344,26 @@ public class ItemService
return response.body().bytes();
}
}
public void queueLookup(int itemId)
{
if (pendingPriceLookups.size() >= MAX_PENDING_LOOKUPS)
{
return;
}
pendingPriceLookups.add(itemId);
}
@Scheduled(fixedDelay = 5000)
public void checkPrices()
{
Integer itemId = pendingPriceLookups.poll();
if (itemId == null)
{
return;
}
fetchPrice(itemId);
}
}