Btw, I also found that tynamo's implementation of JPATransactionManager
doesn't fit well when using DAO-level caching.
Assume I have AccountDAO interface:

public interface AccountDAO {
   @CommitAfter
   public Account getAccount();
}

AccountDAOImpl is an implementation of this interface that communicated to
datastore.

And also I have AccountDAOImplCache extending AccountDAOImpl which caches
database response in two levels: 1) local memory 2) memcache.

In order this to work in GAE I need @CommitAfter annotation (because in one
transaction I can't work with entities of different entity groups, and
normally you do have such code).

Now if AccountDAOImplCache can provide value from cache you wont use DB at
all, but JPATransactionManager will force to commit and begin new
transaction. This is heavy. Also if during request handling you don't have
any DB communications default JPATransactionManager implementation will
begin/rollback transaction around request, which is not required but by
design.

I had to rewrite this implementation and begin new transaction only if some
datastore query creating (I did a wrapper for EM).

This also saved me a lot response time.

On Tue, Jun 8, 2010 at 10:22, Dmitry Gusev <dmitry.gu...@gmail.com> wrote:

>
> On Mon, Jun 7, 2010 at 20:38, Howard Lewis Ship <hls...@gmail.com> wrote:
>
>> That's interesting, that GAE shuts down your instances.
>
>
> Yes, its a big issue for some projects, so now google is working to
> impoement support for dedicated JVMs:
>
> "The work is in the progress but we should wait for the results. Here is the 
> news from
> the Google I/O. See starting from 44:12
> http://code.google.com/events/io/2010/sessions/whats-hot-in-java-for-app-engine.html
>
>
> - Dedicated JVMs
> - Will cost money"
>
>
>
>>  There's a bit of
>> Tapestry based on the idea that the application is long running, so it's
>> OK
>> if it takes a moment to start up initially. Under GAE that's not the case
>> ... perhaps Tapestry under GAE should be even a bit lazier about loading
>> and
>> instantiating.
>>
>> When GAE shuts down the instance, is it undeploying the WAR?
>
>
> I don't know. I'm not even sure whether there is a WAR, actually.
> I can see in logs that sometime GAE starts a new JVM process, but sometimes
> I see just Tapestry initialization with building services through AppModule.
>
>
>>  All told, I
>> think the most significant amount of time spent starting up a T5 app is
>> the
>> initial load of all those classes. I can see these during the Selenium
>> integration tests, where the second test app to start up (all within the
>> same JVM) is much faster because all the framework classes have already
>> been
>> loaded.
>>
>>
> According to starting log request (see below), it takes ~13 seconds (from
> 11.00.02.201 to 11.00.15.399) for tapestry to build my services and render
> index page. Compare it to 236 milliseconds total (!) for the second request
> to the same page (when JMV is warm and caching is in scene).
>
> The other time (~ 4,8 seconds) is some generic infrastructure startup (from
> 10:59:57.418 to 11.00.02.201). This time is the same for non-tapestry
> starting requests.
>
> I just realized I've never turned on debug logging level for tapestry &
> google code in production, will do this and see.
>
>
>
>    1.  06-07 10:59PM 57.418 / 200 18215ms 20740cpu_ms 304api_cpu_ms 3kb 
> Mozilla/5.0
>    (Windows; U; Windows NT 6.0; ru; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (
>    .NET CLR 3.5.30729),gzip(gfe)
>
>    109.95.252.98 - dmitry.gusev [07/Jun/2010:23:00:15 -0700] "GET / HTTP/1.1" 
> 200 3763 "http://ping-service.appspot.com/"; "Mozilla/5.0 (Windows; U; Windows 
> NT 6.0; ru; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 
> 3.5.30729),gzip(gfe)"
>
>    2.  I 06-07 11:00PM 00.033 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S memcache.Get: ->24<-
>    dmitrygusev.tapestry5.gae.ProfilingDelegate.buildStackTrace:37 dm
>    3.  I 06-07 11:00PM 00.065 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S memcache.Get: ->21<-
>    dmitrygusev.tapestry5.gae.ProfilingDelegate.buildStackTrace:37 dm
>    4.  D 06-07 11:00PM 02.201 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'LazyJPATransactionManager'.
>    5.  D 06-07 11:00PM 03.220 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'TimingFilter'.
>    6.  D 06-07 11:00PM 03.225 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'Utf8Filter'.
>    7.  D 06-07 11:00PM 03.255 
> org.apache.tapestry5.ioc.internal.ServiceBuilderMethodInvoker
>    createObject: Invoking method
>    dmitrygusev.ping.services.AppModule.buildUtf8Filter(Reques
>    8.  D 06-07 11:00PM 03.261 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'Application'.
>    9.  D 06-07 11:00PM 03.263 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'ScheduleDAO'.
>    10.  D 06-07 11:00PM 03.318 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'AccountDAO'.
>    11.  D 06-07 11:00PM 03.342 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'JobDAO'.
>    12.  D 06-07 11:00PM 03.371 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'RefDAO'.
>    13.  D 06-07 11:00PM 03.423 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'JobResultDAO'.
>    14.  D 06-07 11:00PM 03.459 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'GAEHelper'.
>    15.  D 06-07 11:00PM 03.461 
> org.apache.tapestry5.ioc.internal.ServiceBuilderMethodInvoker
>    createObject: Invoking method
>    dmitrygusev.ping.services.AppModule.buildGAEHelper(Request
>    16.  D 06-07 11:00PM 03.472 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'JobExecutor'.
>    17.  D 06-07 11:00PM 03.477 
> org.apache.tapestry5.ioc.internal.ConstructorServiceCreator
>    createObject: Invoking constructor dmitrygusev.ping.services.JobExecutor()
>    (at JobExecutor
>    18.  D 06-07 11:00PM 03.479 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'Mailer'.
>    19.  D 06-07 11:00PM 03.489 
> org.apache.tapestry5.ioc.internal.ConstructorServiceCreator
>    createObject: Invoking constructor dmitrygusev.ping.services.Mailer() (at
>    Mailer.java:17)
>    20.  D 06-07 11:00PM 03.521 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'MemcacheService'.
>    21.  D 06-07 11:00PM 03.544 
> org.apache.tapestry5.ioc.internal.ServiceBuilderMethodInvoker
>    createObject: Invoking method
>    dmitrygusev.ping.services.AppModule.buildApplication(Sched
>    22.  D 06-07 11:00PM 03.544 
> org.apache.tapestry5.ioc.internal.ServiceBuilderMethodInvoker
>    createObject: Invoking method
>    dmitrygusev.ping.services.AppModule.buildTimingFilter(Logg
>    23.  D 06-07 11:00PM 03.553 
> org.apache.tapestry5.ioc.internal.ConstructorServiceCreator
>    createObject: Invoking constructor
>    dmitrygusev.ping.services.dao.impl.cache.AccountDAOImpl
>    24.  D 06-07 11:00PM 03.554 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'Cache'.
>    25.  D 06-07 11:00PM 03.593 
> org.apache.tapestry5.ioc.internal.AbstractMethodInvokingInstrumenter
>    invoke: Invoking method
>    dmitrygusev.ping.services.AppModule.adviseTransactions(JP
>    26.  D 06-07 11:00PM 03.689 
> org.apache.tapestry5.ioc.internal.ServiceBuilderMethodInvoker
>    createObject: Invoking method
>    dmitrygusev.ping.services.AppModule.buildCache(Logger) (at
>    27.  I 06-07 11:00PM 03.710 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S memcache.Get: ->19<- ...LocalMemorySoftCache.get:64
>    ...AccountDAOImplCache.getAccount:
>    28.  D 06-07 11:00PM 03.716 
> org.apache.tapestry5.ioc.internal.ServiceBuilderMethodInvoker
>    createObject: Invoking method
>    dmitrygusev.ping.services.AppModule.buildLazyJPATransactio
>    29.  I 06-07 11:00PM 03.977 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S datastore_v3.BeginTransaction: ->21<-
>    ...AppModule$3$1.assureTxBegin:279 ...AppModule$
>    30.  I 06-07 11:00PM 04.003 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S datastore_v3.Get: ->23<- ...AppModule$3$1.merge:309
>    ...AccountDAOImpl.update:65 ...Acc
>    31.  I 06-07 11:00PM 04.065 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S memcache.Set: ->22<- ...LocalMemorySoftCache.put:116
>    ...AccountDAOImplCache.update:54
>    32.  I 06-07 11:00PM 04.084 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S datastore_v3.Put: ->18<- ...AppModule$3.commit:413
>    ...Application.trackUserActivity:39
>    33.  I 06-07 11:00PM 04.128 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S datastore_v3.Commit: ->43<- ...AppModule$3.commit:413
>    ...Application.trackUserActivity
>    34.  D 06-07 11:00PM 04.175 org.apache.tapestry5.ioc.internal.ModuleImpl
>    create: Creating service 'AccessController'.
>    35.  D 06-07 11:00PM 04.175 
> org.apache.tapestry5.ioc.internal.ServiceBuilderMethodInvoker
>    createObject: Invoking method
>    dmitrygusev.ping.services.AppModule.buildAccessController(
>    36.  I 06-07 11:00PM 12.166 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S user.CreateLogoutURL: ->18<-
>    ...GAEHelper.createLogoutURL:53 ...TopBar.getLogoutURL:19
>    37.  D 06-07 11:00PM 12.317 
> org.apache.tapestry5.ioc.internal.ConstructorServiceCreator
>    createObject: Invoking constructor
>    dmitrygusev.ping.services.dao.impl.cache.RefDAOImplCach
>    38.  D 06-07 11:00PM 12.321 
> org.apache.tapestry5.ioc.internal.AbstractMethodInvokingInstrumenter
>    invoke: Invoking method
>    dmitrygusev.ping.services.AppModule.adviseTransactions(JP
>    39.  I 06-07 11:00PM 12.408 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S memcache.Get: ->23<- ...LocalMemorySoftCache.get:64
>    ...RefDAOImplCache.getRefs:67 ...A
>    40.  D 06-07 11:00PM 12.413 
> org.apache.tapestry5.ioc.internal.ConstructorServiceCreator
>    createObject: Invoking constructor
>    dmitrygusev.ping.services.dao.impl.cache.ScheduleDAOImp
>    41.  D 06-07 11:00PM 12.417 
> org.apache.tapestry5.ioc.internal.AbstractMethodInvokingInstrumenter
>    invoke: Invoking method
>    dmitrygusev.ping.services.AppModule.adviseTransactions(JP
>    42.  I 06-07 11:00PM 12.470 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S memcache.Get: ->27<- ...LocalMemorySoftCache.get:64
>    ...ScheduleDAOImplCache.find:42 ..
>    43.  I 06-07 11:00PM 12.492 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S datastore_v3.BeginTransaction: ->21<-
>    ...AppModule$3$1.assureTxBegin:279 ...AppModule$
>    44.  I 06-07 11:00PM 12.550 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S datastore_v3.Get: ->29<- ...AppModule$3$1.find:359
>    ...ScheduleDAOImpl.find:41 ...Sched
>    45.  I 06-07 11:00PM 13.819 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S datastore_v3.RunQuery: ->1172<-
>    ...AppModule$3$1.find:359 ...ScheduleDAOImpl.find:41 .
>    46.  I 06-07 11:00PM 14.000 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S datastore_v3.Commit: ->20<- ...AppModule$3.commit:413
>    ...Application.getAvailableJobs:
>    47.  I 06-07 11:00PM 15.048 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S memcache.Get: ->18<- ...LocalMemorySoftCache.get:64
>    ...RefDAOImplCache.getRefs:84 ...A
>    48.  I 06-07 11:00PM 15.072 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S memcache.Get: ->21<- ...LocalMemorySoftCache.get:64
>    ...AccountDAOImplCache.find:18 ...
>    49.  I 06-07 11:00PM 15.095 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S memcache.Get: ->22<- ...LocalMemorySoftCache.get:64
>    ...AccountDAOImplCache.find:18 ...
>    50.  I 06-07 11:00PM 15.118 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S memcache.Get: ->22<- ...LocalMemorySoftCache.get:64
>    ...AccountDAOImplCache.find:18 ...
>    51.  I 06-07 11:00PM 15.146 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S memcache.Get: ->27<- ...LocalMemorySoftCache.get:64
>    ...AccountDAOImplCache.find:18 ...
>    52.  I 06-07 11:00PM 15.180 dmitrygusev.tapestry5.gae.ProfilingDelegate
>    makeSyncCall: GAE/S memcache.Get: ->33<- ...LocalMemorySoftCache.get:64
>    ...AccountDAOImplCache.find:18 ...
>    53.  I 06-07 11:00PM 15.399 dmitrygusev.ping.services.AppModule$1
>    service: Request time: 11848 ms
>
>
>
> Second request:
>
>
>    1.
>       1.  06-07 11:19PM 08.651 / 200 266ms 345cpu_ms 73api_cpu_ms 3kb 
> Mozilla/5.0
>       (Windows; U; Windows NT 6.0; ru; rv:1.9.2.3) Gecko/20100401 
> Firefox/3.6.3 (
>       .NET CLR 3.5.30729),gzip(gfe)
>
>       109.95.252.98 - dmitry.gusev [07/Jun/2010:23:19:08 -0700] "GET / 
> HTTP/1.1" 200 3772 "http://ping-service.appspot.com/"; "Mozilla/5.0 (Windows; 
> U; Windows NT 6.0; ru; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 
> 3.5.30729),gzip(gfe)"
>
>       2.  I 06-07 11:19PM 08.678 dmitrygusev.tapestry5.gae.ProfilingDelegate
>       makeSyncCall: GAE/S memcache.Get: ->21<-
>       dmitrygusev.tapestry5.gae.ProfilingDelegate.buildStackTrace:37 dm
>       3.  I 06-07 11:19PM 08.702 dmitrygusev.tapestry5.gae.ProfilingDelegate
>       makeSyncCall: GAE/S memcache.Get: ->23<-
>       dmitrygusev.tapestry5.gae.ProfilingDelegate.buildStackTrace:37 dm
>       4.  I 06-07 11:19PM 08.818 dmitrygusev.ping.services.AppModule$1
>       service: Request time: 106 ms
>       5.  I 06-07 11:19PM 08.881 dmitrygusev.tapestry5.gae.ProfilingDelegate
>       makeSyncCall: GAE/S datastore_v3.Put: ->60<-
>       dmitrygusev.tapestry5.gae.ProfilingDelegate.buildStackTrace:3
>       6.  I 06-07 11:19PM 08.907 dmitrygusev.tapestry5.gae.ProfilingDelegate
>       makeSyncCall: GAE/S memcache.Set: ->24<-
>       dmitrygusev.tapestry5.gae.ProfilingDelegate.buildStackTrace:37 dm
>
>
>
>
>> On Mon, Jun 7, 2010 at 7:01 AM, Thiago H. de Paula Figueiredo <
>> thiag...@gmail.com> wrote:
>>
>> > On Mon, 07 Jun 2010 10:42:52 -0300, Dmitry Gusev <
>> dmitry.gu...@gmail.com>
>> > wrote:
>> >
>> >  This is exactly what I mean, I don't want tapestry to load even once
>> for
>> >> some requests. GAE shutdown/startup instances very often (one new
>> instance
>> >> per ~3 minues) and this consumes additional resources.
>> >>
>> >
>> > Oops, I forgot this GAE characteristic and what you said makes sense
>> now.
>> > :)
>> >
>> > --
>> > Thiago H. de Paula Figueiredo
>> > Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,
>> > and instructor
>> > Owner, Ars Machina Tecnologia da Informação Ltda.
>> > http://www.arsmachina.com.br
>> >
>> > ---------------------------------------------------------------------
>> > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>> > For additional commands, e-mail: users-h...@tapestry.apache.org
>> >
>> >
>>
>>
>> --
>> Howard M. Lewis Ship
>>
>> Creator of Apache Tapestry
>>
>> The source for Tapestry training, mentoring and support. Contact me to
>> learn
>> how I can get you up and productive in Tapestry fast!
>>
>> (971) 678-5210
>> http://howardlewisship.com
>>
>
>
>
> --
> Dmitry Gusev
>
> AnjLab Team
> http://anjlab.com
>



-- 
Dmitry Gusev

AnjLab Team
http://anjlab.com

Reply via email to