item service: process pending lookups in order
I think the current system causes starvation for item checking
This commit is contained in:
@@ -84,9 +84,7 @@ public class ItemService
|
|||||||
private static final int MAX_PENDING = 512;
|
private static final int MAX_PENDING = 512;
|
||||||
|
|
||||||
private final Sql2o sql2o;
|
private final Sql2o sql2o;
|
||||||
private final ConcurrentLinkedQueue<Integer> pendingPriceLookups = new ConcurrentLinkedQueue<>();
|
private final ConcurrentLinkedQueue<PendingLookup> pendingLookups = new ConcurrentLinkedQueue<PendingLookup>();
|
||||||
private final ConcurrentLinkedQueue<String> pendingSearches = new ConcurrentLinkedQueue<>();
|
|
||||||
private final ConcurrentLinkedQueue<Integer> pendingItems = new ConcurrentLinkedQueue<>();
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ItemService(@Qualifier("Runelite SQL2O") Sql2o sql2o)
|
public ItemService(@Qualifier("Runelite SQL2O") Sql2o sql2o)
|
||||||
@@ -365,91 +363,70 @@ public class ItemService
|
|||||||
|
|
||||||
public void queuePriceLookup(int itemId)
|
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)
|
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)
|
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)
|
@Scheduled(fixedDelay = 5000)
|
||||||
public void check()
|
public void check()
|
||||||
{
|
{
|
||||||
if (checkPrices())
|
PendingLookup pendingLookup = pendingLookups.poll();
|
||||||
|
if (pendingLookup == null)
|
||||||
{
|
{
|
||||||
return;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user