java - Way to prioritize specific API calls with multithreads or priority queue? -
in application, servlet(running on tomcat) takes in dopost request, , returns initial value of api call user presentation , ton of data analysis in lot more other api calls. data analysis goes mongodb. problem arises when want start process before bulk api calls finished. there many calls need @ least 20 seconds. don't want user wait 20 seconds initial data display, want data analysis pause let new request call initial api display.
here's general structure of function after dopost(async'd in runnable). it's bit long abbreviated easier read:
private void postmatches(servletrequest req, servletresponse res) { ... getting necessary fields req ... /* read in values arrays */ string rankqueue = generatequerystringarray("rankedqueues=", "rankedqueues", info); string season = generatequerystringarray("seasons=", "seasons", info); string champion = generatequerystringarray("championids=", "championids", info); /* first api call, "return" , start analysis */ jsonobject recentmatches = caller.callriotmatchhistory(region, "" + playerid); try { printwriter out = res.getwriter(); out.write((new gson()).tojson(recentmatches)); out.close(); } catch (ioexception e) { e.printstacktrace(); } /* use array values send more api calls */ jsonobject matchlist = caller.callriotmatchlist(playerid, region, rankqueue, season, champion); ... ton more api calls matchlist's id's... }
so 1 of ideas
have 2 threads per client.
that way, there 1 thread calling single api call, , other thread calling rest 999 api calls. way, single api calling thread wait until dopost same client come , call api immediately, , bulk api calls come appended other thread. doing this, 2 threads compute in parallel.
have priority queue, put initial call on high priority
this way, every url passed through queue , can chose compareto of specific url's greater(maybe wrap in bean). however, i'm not sure how api caller able distinguish call which, because once url's added queue loses identity. there way fix that? know callbacks aren't available in java, it's kind of hard that.
are either of these 2 ideas possible? no need code, appreciated!
ps: i'm using jersey api calls.
the best bet seems using "two threads per client" solution. or rather variation of it.
i figure api you're calling have rate-limiting in place, significant amounts of calls automatically blocked. that's problematic since limit can trivially reached few requests process simultaneously.
additionally may hit i/o-limits rather sooner later, depending on how timeintensive calculations are. means should have intrinsic limit background api calls, initial request should fine without inherent limiting. such fixed-size threadpool seems perfect solution. exposing static executorservice in service should simplest solution.
as such i'd propose expose static service, takes matchlist parameter , "does it's thing".
it looks this:
public class matchprocessor { private static final executorservice service = executors.newfixedthreadpool(threads); public static void processmatchlist(final jsonobject matchlist) { service.submit(() -> runanalysis(matchlist)); } private static void runanalysis(final jsonobject matchlist) { //processing goes here } }
sidenote: code uses java 8, should simple convert submitted lambda runnable, if you're on java 7
Comments
Post a Comment