From 4620de3ded71eefed7792b8576dc84c85d38dcae Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 4 Mar 2018 17:09:01 -0500 Subject: [PATCH] item service: process pending lookups in order I think the current system causes starvation for item checking --- .../http/service/item/ItemService.java | 105 +++++++----------- .../http/service/item/PendingLookup.java | 56 ++++++++++ 2 files changed, 97 insertions(+), 64 deletions(-) create mode 100644 http-service/src/main/java/net/runelite/http/service/item/PendingLookup.java diff --git a/http-service/src/main/java/net/runelite/http/service/item/ItemService.java b/http-service/src/main/java/net/runelite/http/service/item/ItemService.java index 9f05e049eb..c6e4dced5a 100644 --- a/http-service/src/main/java/net/runelite/http/service/item/ItemService.java +++ b/http-service/src/main/java/net/runelite/http/service/item/ItemService.java @@ -84,9 +84,7 @@ public class ItemService private static final int MAX_PENDING = 512; private final Sql2o sql2o; - private final ConcurrentLinkedQueue pendingPriceLookups = new ConcurrentLinkedQueue<>(); - private final ConcurrentLinkedQueue pendingSearches = new ConcurrentLinkedQueue<>(); - private final ConcurrentLinkedQueue pendingItems = new ConcurrentLinkedQueue<>(); + private final ConcurrentLinkedQueue pendingLookups = new ConcurrentLinkedQueue(); @Autowired public ItemService(@Qualifier("Runelite SQL2O") Sql2o sql2o) @@ -365,91 +363,70 @@ public class ItemService public void queuePriceLookup(int itemId) { - if (pendingPriceLookups.size() >= MAX_PENDING) + if (pendingLookups.size() < MAX_PENDING) { - return; + pendingLookups.add(new PendingLookup(itemId, PendingLookup.Type.PRICE)); + } + else + { + log.warn("Dropping pending price lookup for {}", itemId); } - - pendingPriceLookups.add(itemId); } public void queueSearch(String search) { - if (pendingSearches.size() >= MAX_PENDING) + if (pendingLookups.size() < MAX_PENDING) { - return; + pendingLookups.add(new PendingLookup(search, PendingLookup.Type.SEARCH)); + } + else + { + log.warn("Dropping pending search for {}", search); } - - pendingSearches.add(search); } public void queueItem(int itemId) { - if (pendingItems.size() >= MAX_PENDING) + if (pendingLookups.size() < MAX_PENDING) { - return; + pendingLookups.add(new PendingLookup(itemId, PendingLookup.Type.ITEM)); + } + else + { + log.warn("Dropping pending item lookup for {}", itemId); } - - pendingItems.add(itemId); } @Scheduled(fixedDelay = 5000) public void check() { - if (checkPrices()) + PendingLookup pendingLookup = pendingLookups.poll(); + if (pendingLookup == null) { return; } - if (checkSearches()) + + switch (pendingLookup.getType()) { - return; + case PRICE: + fetchPrice(pendingLookup.getItemId()); + break; + case SEARCH: + try + { + RSSearch reSearch = fetchRSSearch(pendingLookup.getSearch()); + + batchInsertItems(reSearch); + } + catch (IOException ex) + { + log.warn("error while searching items", ex); + } + break; + case ITEM: + fetchItem(pendingLookup.getItemId()); + break; } - checkItems(); } - private boolean checkPrices() - { - Integer itemId = pendingPriceLookups.poll(); - if (itemId == null) - { - return false; - } - - fetchPrice(itemId); - return true; - } - - private boolean checkSearches() - { - String search = pendingSearches.poll(); - if (search == null) - { - return false; - } - - try - { - RSSearch reSearch = fetchRSSearch(search); - - batchInsertItems(reSearch); - } - catch (IOException ex) - { - log.warn("error while searching items", ex); - } - - return true; - } - - private boolean checkItems() - { - Integer itemId = pendingItems.poll(); - if (itemId == null) - { - return false; - } - - fetchItem(itemId); - return true; - } } diff --git a/http-service/src/main/java/net/runelite/http/service/item/PendingLookup.java b/http-service/src/main/java/net/runelite/http/service/item/PendingLookup.java new file mode 100644 index 0000000000..4e0e224868 --- /dev/null +++ b/http-service/src/main/java/net/runelite/http/service/item/PendingLookup.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.service.item; + +import lombok.Value; + +@Value +class PendingLookup +{ + enum Type + { + PRICE, + SEARCH, + ITEM; + } + + private final int itemId; + private final String search; + private final Type type; + + public PendingLookup(int itemId, Type type) + { + this.itemId = itemId; + this.search = null; + this.type = type; + } + + public PendingLookup(String search, Type type) + { + this.itemId = -1; + this.search = search; + this.type = type; + } +}