public ProgressEvent done()

in src/main/java/software/amazon/cloudformation/proxy/AmazonWebServicesClientProxy.java [352:427]


                        public ProgressEvent<ModelT, CallbackT> done(Callback<RequestT, ResponseT, ClientT, ModelT, CallbackT,
                            ProgressEvent<ModelT, CallbackT>> callback) {
                            //
                            // StdCallbackContext memoization wrappers for request, response, and
                            // stabilization
                            // lambdas. This ensures that we call demux as necessary.
                            //
                            final String callGraph = generator.callGraph(CallContext.this.callGraph, model, maker,
                                client.client(), context);
                            Delay delay = override.getDelay(callGraph, CallContext.this.delay);
                            Function<ModelT, RequestT> reqMaker = context.request(callGraph, maker);
                            BiFunction<RequestT, ProxyClient<ClientT>, ResponseT> resMaker = context.response(callGraph, caller);
                            if (waitFor != null) {
                                waitFor = context.stabilize(callGraph, waitFor);
                            }
                            int attempt = context.attempts(callGraph);
                            RequestT req = null;
                            ResponseT res = null;
                            ProgressEvent<ModelT, CallbackT> event = null;
                            Callback<? super RequestT, Exception, ClientT, ModelT, CallbackT,
                                ProgressEvent<ModelT, CallbackT>> exceptionHandler = getExceptionHandler(
                                    AmazonWebServicesClientProxy.this::defaultHandler);
                            try {
                                for (;;) {
                                    Instant now = Instant.now();
                                    try {
                                        req = req == null ? reqMaker.apply(model) : req;
                                        res = res == null ? resMaker.apply(req, client) : res;
                                        if (waitFor != null) {
                                            if (waitFor.invoke(req, res, client, model, context)) {
                                                event = callback.invoke(req, res, client, model, context);
                                            }
                                        } else {
                                            event = callback.invoke(req, res, client, model, context);
                                        }
                                    } catch (BaseHandlerException e) {
                                        throw e;
                                    } catch (Exception e) {
                                        event = exceptionHandler.invoke(req, e, client, model, context);
                                    }

                                    if (event != null) {
                                        return event;
                                    }

                                    //
                                    // The logic to wait is if next delay + 2 * time to run the operation sequence +
                                    // 100ms
                                    // is less than time remaining time to run inside Lambda then we locally wait
                                    // else we bail out. Assuming 3 DAYS for a DB to restore, that would be total of
                                    // 3 x 24 x 60 x 60 x 1000 ms, fits in 32 bit int.
                                    //
                                    Instant opTime = Instant.now();
                                    long elapsed = ChronoUnit.MILLIS.between(now, opTime);
                                    Duration next = delay.nextDelay(attempt++);
                                    context.attempts(callGraph, attempt);
                                    if (next == Duration.ZERO) {
                                        return ProgressEvent.failed(model, context, HandlerErrorCode.NotStabilized,
                                            "Exceeded attempts to wait");
                                    }
                                    event = AmazonWebServicesClientProxy.this.waitStrategy.await(elapsed, next, context, model);
                                    if (event != null) {
                                        return event;
                                    }
                                }
                            } finally {
                                //
                                // only set request if response was successful. Otherwise we will remember the
                                // the original failed request in the callback. So when we fix and resume from
                                // the error with callback, we will replay the wrong one
                                //
                                if (res == null) {
                                    context.evictRequestRecord(callGraph);
                                }
                            }
                        }