item service: process pending lookups in order

I think the current system causes starvation for item checking
This commit is contained in:
Adam
2018-03-04 17:09:01 -05:00
parent 451f13a424
commit 4620de3ded
2 changed files with 97 additions and 64 deletions

View File

@@ -84,9 +84,7 @@ public class ItemService
private static final int MAX_PENDING = 512;
private final Sql2o sql2o;
private final ConcurrentLinkedQueue<Integer> pendingPriceLookups = new ConcurrentLinkedQueue<>();
private final ConcurrentLinkedQueue<String> pendingSearches = new ConcurrentLinkedQueue<>();
private final ConcurrentLinkedQueue<Integer> pendingItems = new ConcurrentLinkedQueue<>();
private final ConcurrentLinkedQueue<PendingLookup> pendingLookups = new ConcurrentLinkedQueue<PendingLookup>();
@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;
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* 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;
}
}