Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
MrQueasy
Nov 15, 2005

Probiot-ICK
Anyone know a good way to do handle result paging with CompletableFuture without potentially infinite recursion or just arbitrarily checking the depth?

pseudocode:
code:
CompletableFuture<List<Result>> getResults() {
    var responseF = externalService.query().thenCompose(response -> {
	    if (response.hasNextPageToken()) {
		  return getResults(token, response.results)
            } else {
                  return completedFuture(List.of());
           }
 }  

CompletableFuture<List<Result>> getResults(Token token, List<Results> results) {
        var responseF = externalService.query(token).thenCompose(response -> {
	    if (response.hasNextPageToken()) {
		  return getResults(token, results + response.results)
            } else {
                  return completedFuture(results);
           }
}

Adbot
ADBOT LOVES YOU

MrQueasy
Nov 15, 2005

Probiot-ICK

Jabor posted:

The easy way would be to query a non-paging variant of the API. You're not "handling" the paging in any meaningful sense, just bypassing it.

Lets imagine for a second that we're dealing with an api that does NOT have a non-paging variant.


RandomBlue posted:

Why would you want to call an async method recursively? If recursion needs to be used instead of a simple loop (which is what I'd go with here) then move the recursive code into a synchronous method called from the async methods.

Can you clarify what you mean by this? I may be mistaken in how CompletedFuture works.

If I do this in the normal blocking while loop way, it will block until all N pages load (of which there are sadly arbitrarily many... probably less than 100?). I would like to start up other downloads (that operate similarly) while I wait for these calls to resolve.

The only way to tell if there are more pages is if there is a token. I can't just walk the pages and tell it to stop when it starts erroring.

(Ugh... I've been in clojure too long... this stuff is relatively straightforward with lazy loading or tail-call optimization)

MrQueasy
Nov 15, 2005

Probiot-ICK

Jabor posted:

Calling functions asynchronously like you're doing isn't going to blow out the thread stack, if that's what you're worried about. Each call to thenCompose() allocates a lambda on the heap with the current context, the thread stack never gets particularly deep unless the request somehow completes in between you calling query() and then calling thenCompose() on the result. If you're worried about that then you could call thenComposeAsync() instead.

Thank you, this has taken a load off of my mind... (despite sending me down a rabbit hole about how and when to use the *async methods)

MrQueasy
Nov 15, 2005

Probiot-ICK

Pedestrian Xing posted:

Anyone have strong opinions on getting the Oracle Java 17 cert? Is it worth it if I already have a strong resume (aiming for senior/principal level)? If anyone has taken it, how much study should I plan to do?

I'd vote that an Oracle Java cert is a net neutral at best for an early career, with perhaps a net negative IMO for senior+ types. But I'm idiosyncratic and really only respect the OSCP.

MrQueasy
Nov 15, 2005

Probiot-ICK

Ihmemies posted:

I have a problem deciding what is the least crap way of implementing choicebox values in javafx. Depending on user selections and choiceboxes, I need to have a variable_id (for API calls) associated with the choice, or a LineChart.class for example, so I know what kind of XYChart the user wants to draw.

I don't understand why you need to store a class here? Instantiating from a Class<?> value is not really done except when you're doing some really nasty reflection/bytecode manipulation fuckery.

Personally I would go with a similar way that in my brain looks cleaner (completely my preferences/biases though)
Java code:
    LINE_CHART("Line chart", () -> new LineChart<>(new NumberAxis(), new NumberAxis()),
    AREA_CHART("Area chart", () -> new AreaChart<>(new NumberAxis(), new NumberAxis());
    private final String label;
    private final Supplier<XYChart<Number, Number> createFn;

    ChartType(String label, Supplier<XYChart<Number, Number>> createFn) {
        this.label = label;
        this.createFn = createFn;
    }

    @Override
    public String toString() {
        return label;
    }

    public XYChart<Number, Number> createChart() {
        return createFn.get();
    }

    public static List<String> stringValues() {
        List<String> stringValues = new ArrayList<>();
        for (ChartType type : ChartType.values()) {
            stringValues.add(type.toString());
        }
        return stringValues;
    }
This is because I use 11 most of the time for work. If I could use 17+, then I'd probably use Sealed classes over enums for this particular use-case despite them being a bit clunky.

EDIT: Oh, JavaFX. hmm.

Adbot
ADBOT LOVES YOU

MrQueasy
Nov 15, 2005

Probiot-ICK
As always I must caution that rewriting isn’t necessarily fixing old bugs so much as it is trading them for new ones.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply