Recompiling of .less file triggered in prod unexpectedly

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Recompiling of .less file triggered in prod unexpectedly

JumpStart
I’m observing that after startup, and then after every 20 minutes or so - actually, it seems to be quite variable - the first page after login will take 20 or more seconds to be displayed. The rest of the time it is almost instantaneous.

I’ve run a sampler over it during one of these 20+ sec periods and it seems to be spending all its time in the Less compiler. The page is using @Import:

@Import(stylesheet = { "css/client.less" })
public class Home extends LoggedIn {

I’m using tapestry-webresources-5.4.3.jar.

I was expecting this to be a one-time event, on first visit to the page after startup. Under what circumstances would you expect it to happen more than once?

Regards,

Geoff
Reply | Threaded
Open this post in threaded view
|

Re: Recompiling of .less file triggered in prod unexpectedly

Cezary Biernacki
Tapestry caches compiled files in memory using SoftReference<> so it is
possible for the garbage collector to remove them (see
org.apache.tapestry5.internal.services.assets.SRSCachingInterceptor). In
the development mode Tapestry also caches compilations in a temporary
directory, but unfortunately this mechanism is disabled in the production
mode
(see org.apache.tapestry5.internal.webresources.ResourceTransformerFactoryImpl#createCompiler).

Cezary


On Thu, Oct 24, 2019 at 2:57 AM JumpStart <
[hidden email]> wrote:

> I’m observing that after startup, and then after every 20 minutes or so -
> actually, it seems to be quite variable - the first page after login will
> take 20 or more seconds to be displayed. The rest of the time it is almost
> instantaneous.
>
> I’ve run a sampler over it during one of these 20+ sec periods and it
> seems to be spending all its time in the Less compiler. The page is using
> @Import:
>
> @Import(stylesheet = { "css/client.less" })
> public class Home extends LoggedIn {
>
> I’m using tapestry-webresources-5.4.3.jar.
>
> I was expecting this to be a one-time event, on first visit to the page
> after startup. Under what circumstances would you expect it to happen more
> than once?
>
> Regards,
>
> Geoff
Reply | Threaded
Open this post in threaded view
|

Re: Recompiling of .less file triggered in prod unexpectedly

JumpStart
That’s great information. So is the solution to precompile them for production, or to override SRSCachingInterceptor, or something else altogether?

> On 24 Oct 2019, at 11:09 pm, Cezary Biernacki <[hidden email]> wrote:
>
> Tapestry caches compiled files in memory using SoftReference<> so it is
> possible for the garbage collector to remove them (see
> org.apache.tapestry5.internal.services.assets.SRSCachingInterceptor). In
> the development mode Tapestry also caches compilations in a temporary
> directory, but unfortunately this mechanism is disabled in the production
> mode
> (see org.apache.tapestry5.internal.webresources.ResourceTransformerFactoryImpl#createCompiler).
>
> Cezary
>
>
> On Thu, Oct 24, 2019 at 2:57 AM JumpStart <
> [hidden email]> wrote:
>
>> I’m observing that after startup, and then after every 20 minutes or so -
>> actually, it seems to be quite variable - the first page after login will
>> take 20 or more seconds to be displayed. The rest of the time it is almost
>> instantaneous.
>>
>> I’ve run a sampler over it during one of these 20+ sec periods and it
>> seems to be spending all its time in the Less compiler. The page is using
>> @Import:
>>
>> @Import(stylesheet = { "css/client.less" })
>> public class Home extends LoggedIn {
>>
>> I’m using tapestry-webresources-5.4.3.jar.
>>
>> I was expecting this to be a one-time event, on first visit to the page
>> after startup. Under what circumstances would you expect it to happen more
>> than once?
>>
>> Regards,
>>
>> Geoff


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Recompiling of .less file triggered in prod unexpectedly

Cezary Biernacki
Assuming that my suggestion is correct, the simplest solution would be to
give more heap space to JVM if there is enough RAM on machines you are
deploying.

Otherwise, I would attempt to create a StreamableResourceSource decorator
that would cache only selected resources that are heavy to compute (e.g.
less files in your case), but otherwise not very memory consuming in a
ConcurrentMap using normal references (i.e. not SoftReference). As there is
already a stack of decorators for SRS (see
org.apache.tapestry5.modules.AssetsModule) you should be careful how to
order that new decorator. Try @Order("before:GZIpCompression",
"after:CacheCompressed").

But in longer term, some way to precompile files for the production would
be more sustainable. I would a consider a solution that adds
another StreamableResourceSource decorator (or a ResourceTransformerFactory
decorator) which works in two modes, In the first mode it saves streamable
resources to a specified directory on the file system, in the second mode
it retrieves cached data from a JAR (using Java's Resource). During the
build process a script would start the application in the first mode,
trigger compilation of key assets, and finally pack it to a JAR. In the
production the second mode could be be used.

Best regards,
Cezary



On Thu, Oct 24, 2019 at 11:18 PM JumpStart <
[hidden email]> wrote:

> That’s great information. So is the solution to precompile them for
> production, or to override SRSCachingInterceptor, or something else
> altogether?
>
> > On 24 Oct 2019, at 11:09 pm, Cezary Biernacki <[hidden email]>
> wrote:
> >
> > Tapestry caches compiled files in memory using SoftReference<> so it is
> > possible for the garbage collector to remove them (see
> > org.apache.tapestry5.internal.services.assets.SRSCachingInterceptor). In
> > the development mode Tapestry also caches compilations in a temporary
> > directory, but unfortunately this mechanism is disabled in the production
> > mode
> > (see
> org.apache.tapestry5.internal.webresources.ResourceTransformerFactoryImpl#createCompiler).
> >
> > Cezary
> >
> >
> > On Thu, Oct 24, 2019 at 2:57 AM JumpStart <
> > [hidden email]> wrote:
> >
> >> I’m observing that after startup, and then after every 20 minutes or so
> -
> >> actually, it seems to be quite variable - the first page after login
> will
> >> take 20 or more seconds to be displayed. The rest of the time it is
> almost
> >> instantaneous.
> >>
> >> I’ve run a sampler over it during one of these 20+ sec periods and it
> >> seems to be spending all its time in the Less compiler. The page is
> using
> >> @Import:
> >>
> >> @Import(stylesheet = { "css/client.less" })
> >> public class Home extends LoggedIn {
> >>
> >> I’m using tapestry-webresources-5.4.3.jar.
> >>
> >> I was expecting this to be a one-time event, on first visit to the page
> >> after startup. Under what circumstances would you expect it to happen
> more
> >> than once?
> >>
> >> Regards,
> >>
> >> Geoff
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Recompiling of .less file triggered in prod unexpectedly

JumpStart
Thank you Cezary. This is invaluable. As a first step I’ve added some logging of the caching to see whether this is the culprit.

Geoff

> On 25 Oct 2019, at 7:38 am, Cezary Biernacki <[hidden email]> wrote:
>
> Assuming that my suggestion is correct, the simplest solution would be to
> give more heap space to JVM if there is enough RAM on machines you are
> deploying.
>
> Otherwise, I would attempt to create a StreamableResourceSource decorator
> that would cache only selected resources that are heavy to compute (e.g.
> less files in your case), but otherwise not very memory consuming in a
> ConcurrentMap using normal references (i.e. not SoftReference). As there is
> already a stack of decorators for SRS (see
> org.apache.tapestry5.modules.AssetsModule) you should be careful how to
> order that new decorator. Try @Order("before:GZIpCompression",
> "after:CacheCompressed").
>
> But in longer term, some way to precompile files for the production would
> be more sustainable. I would a consider a solution that adds
> another StreamableResourceSource decorator (or a ResourceTransformerFactory
> decorator) which works in two modes, In the first mode it saves streamable
> resources to a specified directory on the file system, in the second mode
> it retrieves cached data from a JAR (using Java's Resource). During the
> build process a script would start the application in the first mode,
> trigger compilation of key assets, and finally pack it to a JAR. In the
> production the second mode could be be used.
>
> Best regards,
> Cezary
>
>
>
> On Thu, Oct 24, 2019 at 11:18 PM JumpStart <
> [hidden email]> wrote:
>
>> That’s great information. So is the solution to precompile them for
>> production, or to override SRSCachingInterceptor, or something else
>> altogether?
>>
>>> On 24 Oct 2019, at 11:09 pm, Cezary Biernacki <[hidden email]>
>> wrote:
>>>
>>> Tapestry caches compiled files in memory using SoftReference<> so it is
>>> possible for the garbage collector to remove them (see
>>> org.apache.tapestry5.internal.services.assets.SRSCachingInterceptor). In
>>> the development mode Tapestry also caches compilations in a temporary
>>> directory, but unfortunately this mechanism is disabled in the production
>>> mode
>>> (see
>> org.apache.tapestry5.internal.webresources.ResourceTransformerFactoryImpl#createCompiler).
>>>
>>> Cezary
>>>
>>>
>>> On Thu, Oct 24, 2019 at 2:57 AM JumpStart <
>>> [hidden email]> wrote:
>>>
>>>> I’m observing that after startup, and then after every 20 minutes or so
>> -
>>>> actually, it seems to be quite variable - the first page after login
>> will
>>>> take 20 or more seconds to be displayed. The rest of the time it is
>> almost
>>>> instantaneous.
>>>>
>>>> I’ve run a sampler over it during one of these 20+ sec periods and it
>>>> seems to be spending all its time in the Less compiler. The page is
>> using
>>>> @Import:
>>>>
>>>> @Import(stylesheet = { "css/client.less" })
>>>> public class Home extends LoggedIn {
>>>>
>>>> I’m using tapestry-webresources-5.4.3.jar.
>>>>
>>>> I was expecting this to be a one-time event, on first visit to the page
>>>> after startup. Under what circumstances would you expect it to happen
>> more
>>>> than once?
>>>>
>>>> Regards,
>>>>
>>>> Geoff
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [hidden email]
>> For additional commands, e-mail: [hidden email]
>>
>>


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Recompiling of .less file triggered in prod unexpectedly

JumpStart
Yep, that was the solution. I now cache hard references to the .less resources instead of SoftReferences. The page that uses the .less file no longer lags (except the first time after startup).

In fact, I’m considering doing it for all assets, because I’m not clear on there being any benefit to having the GC repeatedly undoing the good work of the Tapestry asset cache.

Geoff

> On 25 Oct 2019, at 5:02 pm, JumpStart <[hidden email]> wrote:
>
> Thank you Cezary. This is invaluable. As a first step I’ve added some logging of the caching to see whether this is the culprit.
>
> Geoff
>
>> On 25 Oct 2019, at 7:38 am, Cezary Biernacki <[hidden email]> wrote:
>>
>> Assuming that my suggestion is correct, the simplest solution would be to
>> give more heap space to JVM if there is enough RAM on machines you are
>> deploying.
>>
>> Otherwise, I would attempt to create a StreamableResourceSource decorator
>> that would cache only selected resources that are heavy to compute (e.g.
>> less files in your case), but otherwise not very memory consuming in a
>> ConcurrentMap using normal references (i.e. not SoftReference). As there is
>> already a stack of decorators for SRS (see
>> org.apache.tapestry5.modules.AssetsModule) you should be careful how to
>> order that new decorator. Try @Order("before:GZIpCompression",
>> "after:CacheCompressed").
>>
>> But in longer term, some way to precompile files for the production would
>> be more sustainable. I would a consider a solution that adds
>> another StreamableResourceSource decorator (or a ResourceTransformerFactory
>> decorator) which works in two modes, In the first mode it saves streamable
>> resources to a specified directory on the file system, in the second mode
>> it retrieves cached data from a JAR (using Java's Resource). During the
>> build process a script would start the application in the first mode,
>> trigger compilation of key assets, and finally pack it to a JAR. In the
>> production the second mode could be be used.
>>
>> Best regards,
>> Cezary
>>
>>
>>
>> On Thu, Oct 24, 2019 at 11:18 PM JumpStart <
>> [hidden email]> wrote:
>>
>>> That’s great information. So is the solution to precompile them for
>>> production, or to override SRSCachingInterceptor, or something else
>>> altogether?
>>>
>>>> On 24 Oct 2019, at 11:09 pm, Cezary Biernacki <[hidden email]>
>>> wrote:
>>>>
>>>> Tapestry caches compiled files in memory using SoftReference<> so it is
>>>> possible for the garbage collector to remove them (see
>>>> org.apache.tapestry5.internal.services.assets.SRSCachingInterceptor). In
>>>> the development mode Tapestry also caches compilations in a temporary
>>>> directory, but unfortunately this mechanism is disabled in the production
>>>> mode
>>>> (see
>>> org.apache.tapestry5.internal.webresources.ResourceTransformerFactoryImpl#createCompiler).
>>>>
>>>> Cezary
>>>>
>>>>
>>>> On Thu, Oct 24, 2019 at 2:57 AM JumpStart <
>>>> [hidden email]> wrote:
>>>>
>>>>> I’m observing that after startup, and then after every 20 minutes or so
>>> -
>>>>> actually, it seems to be quite variable - the first page after login
>>> will
>>>>> take 20 or more seconds to be displayed. The rest of the time it is
>>> almost
>>>>> instantaneous.
>>>>>
>>>>> I’ve run a sampler over it during one of these 20+ sec periods and it
>>>>> seems to be spending all its time in the Less compiler. The page is
>>> using
>>>>> @Import:
>>>>>
>>>>> @Import(stylesheet = { "css/client.less" })
>>>>> public class Home extends LoggedIn {
>>>>>
>>>>> I’m using tapestry-webresources-5.4.3.jar.
>>>>>
>>>>> I was expecting this to be a one-time event, on first visit to the page
>>>>> after startup. Under what circumstances would you expect it to happen
>>> more
>>>>> than once?
>>>>>
>>>>> Regards,
>>>>>
>>>>> Geoff
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: [hidden email]
>>> For additional commands, e-mail: [hidden email]
>>>
>>>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]