Re: Best practice for health check URL?

2021-12-07 Thread Thiago H. de Paula Figueiredo
On Mon, Dec 6, 2021 at 1:25 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.
>

Yes, my mental plan is to have it configurable, probably on by default,
just like production mode is.


> 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.
>

I suppose we would need to make some changes to Tapestry and Tapestry-IoC
internals to offer the option to preload everything, plus maybe provide
some hook for user code to preload itself (although contributions to
RegistryStartup may be enough for that, but I haven't investigated yet).

-- 
Thiago


Re: Best practice for health check URL?

2021-12-06 Thread Dmitry Gusev
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 
> 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 

Re: Best practice for health check URL?

2021-12-06 Thread JumpStart
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  
> 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  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



Re: Best practice for health check URL?

2021-12-03 Thread Thiago H. de Paula Figueiredo
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  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


Re: Best practice for health check URL?

2021-11-30 Thread JumpStart
Hi Ben,

This is all truly great to know. I think I may draw ideas from both yours and 
Dmitry’s response.

Thank you,

Geoff

> On 30 Nov 2021, at 4:40 pm, Ben Weidig  wrote:
> 
> Hi Geoff,
> 
> we have a multi-tenant/-domain multi-language site that required pre-heated
> servers after deployment, so we created a WarmupTaskRunner to run at
> startup, which gets contributed different kinds of tasks.
> They can either be blocking or just run in the background, depending on
> what they do (e.g., pre-heating caches/assets, ensuring indices in MongoDB
> are set in dynamic collections, ...).
> 
> In our case, we just call the index pages for all relevant domains with
> Apache HttpClient instead of creating the pages and components in Tapestry
> itself.
> But Dmitry's way is more thoroughly than our method.
> 
> The WarmupTaskRunner is combined with the health checks for HAProxy.
> An HttpServletFilter checks for things like "warmup finished" by asking the
> WarmupTaskRunner, and "mysql connection pool available", "mongodb
> available", etc., and returns an appropriate HTTP status code to HAProxy.
> If not 200 is returned, HAProxy takes the server out of rotation.
> 
> Cheers,
> Ben
> 
> 
> On Tue, Nov 30, 2021 at 2: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  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
>> 
>> 


-
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org



Re: Best practice for health check URL?

2021-11-30 Thread Dmitry Gusev
Hi Geoff,

RESTEasy services are singletons, so we simply created an `AtomicReference`
field and used `compareAndSet()`,
something like this:

private final AtomicReference 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  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


Re: Best practice for health check URL?

2021-11-30 Thread Ben Weidig
Hi Geoff,

we have a multi-tenant/-domain multi-language site that required pre-heated
servers after deployment, so we created a WarmupTaskRunner to run at
startup, which gets contributed different kinds of tasks.
They can either be blocking or just run in the background, depending on
what they do (e.g., pre-heating caches/assets, ensuring indices in MongoDB
are set in dynamic collections, ...).

In our case, we just call the index pages for all relevant domains with
Apache HttpClient instead of creating the pages and components in Tapestry
itself.
But Dmitry's way is more thoroughly than our method.

The WarmupTaskRunner is combined with the health checks for HAProxy.
An HttpServletFilter checks for things like "warmup finished" by asking the
WarmupTaskRunner, and "mysql connection pool available", "mongodb
available", etc., and returns an appropriate HTTP status code to HAProxy.
If not 200 is returned, HAProxy takes the server out of rotation.

Cheers,
Ben


On Tue, Nov 30, 2021 at 2: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  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
>
>


Re: Best practice for health check URL?

2021-11-29 Thread JumpStart
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  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



Re: Best practice for health check URL?

2021-11-29 Thread Dmitry Gusev
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
>
>