Hi Geoff, RESTEasy services are singletons, so we simply created an `AtomicReference` field and used `compareAndSet()`, something like this:
private final AtomicReference<WarmUpStatus> warmUpStatus = new AtomicReference<>(WarmUpStatus.EMPTY); @Override public Response warmUp() { if (warmUpStatus.compareAndSet(WarmUpStatus.EMPTY, WarmUpStatus.IN_PROGRESS)) { Regards, Dmitry On Tue, Nov 30, 2021 at 1:41 AM JumpStart < geoff.callender.jumpst...@gmail.com> wrote: > Hi Dmitry, > > That is spectacularly helpful! > > We’re about to write a headless smoke test anyway that will visit every > page. Do you see any downside to using that to do the warmup? > > Where do you keep your shared “warmup in progress” flag so that it is > rapidly accessible on every health check request? > > Cheers, > > Geoff > > > On 30 Nov 2021, at 6:35 am, Dmitry Gusev <dmitry.gu...@gmail.com> wrote: > > > > Hi Geoff, > > > > I don't think there's a simpler way, we're doing something similar. > > > > We created a REST endpoint with tynamo-resteasy which is effectively a > load > > balancer health check. > > On the first hit it starts the warmup process on the same request, > > following requests return an error instantly if the initial warmup > routine > > is still in progress. > > > > Our warmup logic is heavily based on tapestry internals & reflection, in > > conjunction with eager loading services as described here: > > https://gist.github.com/dmitrygusev/5562739 > > > > Warmup logic is a bit complicated, it's trying to: > > - "touch" each page using ComponentClassResolver.getPageNames() > > - recursively for each component with mixins on a page starting from root > > component, > >> find imported assets via reflection (fields with names starting as > > `importedAssets_`) > >> stream each asset via `StreamableResourceSource` into no-op consumer > > - find JS modules with `ModuleManager` and stream through no-op consumer > > - every JS stack returned from `JavaScriptStackSource` assemble with > > `JavaScriptStackAssembler` and stream through no-op consumer > > - repeat above for each locale/axis > > > > Entire process usually takes 3-5 minute in our setup. > > After it's done we return 200 to the load balancer and the first real > > request is handled with hot caches. > > > > Hope this helps, > > Dmitry > > > > On Mon, Nov 29, 2021 at 9:53 PM JumpStart < > > geoff.callender.jumpst...@gmail.com> wrote: > > > >> Any suggestions on best ways to write a “health check” page to be called > >> by load balancers? > >> > >> My app is getting big, and the traffic is big. If the app fails > (hopefully > >> never, but it’s a JVM) and the traffic is heavy enough, startup never > seems > >> to complete - every request times out, the app log goes quiet, and CPU > goes > >> to 100%. It appears to be due to race conditions possibly involving > asset > >> compression, minimising, and first time into the pages. > >> > >> I’m considering having a startup service crawl every page, in every > >> language, in every skinning, before setting a singleton flag that the > >> health check page will read to determine whether the app is ready to > >> receive traffic. > >> > >> Is there a simpler way? > >> > >> Geoff > >> --------------------------------------------------------------------- > >> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org > >> For additional commands, e-mail: users-h...@tapestry.apache.org > >> > >> > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org > For additional commands, e-mail: users-h...@tapestry.apache.org > > -- Dmitry Gusev AnjLab Team http://anjlab.com