Hi Geoff,

I extracted all the important bits from our implementation into this gist:

https://gist.github.com/dmitrygusev/486ad56174450299b94cc364d3630b28

I'd start exploring it from here:

https://gist.github.com/dmitrygusev/486ad56174450299b94cc364d3630b28#file-eagerloadresourceimpl-java-L94

In the gist you'll find full implementation, but configuration will likely
be different depending on your project setup.

You can find some examples in `TapestryEagerLoadModule` for how you can
contribute variations to the warmup, e.g.:
  -- different locales, or other behaviours that can prepare a request
thread for serving custom responses
  -- an example of contributing warmup logic as one of the health checks to
the Dropwizard's healthcheck registry
  -- contributions to the `SkipEagerLoadForPatterns` to ignore certain
files from direct access during warmup
  -- etc.

Any questions or suggestions, please let me know.

Regards,
Dmitry



On Mon, Dec 6, 2021 at 4:24 PM JumpStart <
geoff.callender.jumpst...@gmail.com> wrote:

> I think you’d want to make it a configuration option, so that development
> can still come up quickly, but that sounds great for production.
>
> I’ve spent some time bouncing between Dmitry and Ben’s approaches. With
> the latter I simplified it with Jsoup, but there are considerable
> limitations to what can be preloaded that way.
>
> Dmitry, I have tried to flesh out what you’ve done, but I think my
> knowledge of Tapestry internals is holding me back. You seem to have taken
> a really deep dive! Is there any code that you’d feel comfortable sharing?
>
> Cheers,
>
> Geoff
>
> > On 4 Dec 2021, at 6:00 am, Thiago H. de Paula Figueiredo <
> thiag...@gmail.com> wrote:
> >
> > Hi!
> >
> > Today I started wondering about how we could get Tapestry to run under
> > Quarkus.io, including generating a native executable. Of course, this
> won't
> > include bytecode generated in runtime, something many libraries and
> > frameworks do, Tapestry very much included. Then I researched a bit and
> > found this:
> https://quarkus.io/guides/writing-extensions#bytecode-recording.
> > Basically, it's a hook for you to run the code that will generate
> bytecode
> > while the hook records everything (if I got it right). So, to write an
> > extension for Tapestry, we would need to have every page and and every
> > service (and maybe some other stuff too) fully realized, since
> Tapestry-IoC
> > and Tapestry load mostly everything in a lazy manner. This is something
> > that could also solve Geoff's question: if we can somehow force Tapestry
> to
> > preload everything, then the app is ready and (at least mostly) warm when
> > the first request is properly served.
> >
> > With the code Dmitry shared here, I wonder if you want to collaborate on
> > implementing this preload feature on Tapestry itself out-of-the-box,
> > avoiding some ugly workarounds needed since there's no actual support for
> > that. :)
> >
> > Cheers!
> >
> > On Mon, Nov 29, 2021 at 7:36 PM 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
> >>>
> >>>
> >>
> >
> >
> > --
> > Thiago
>
>
> ---------------------------------------------------------------------
> 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

Reply via email to