[google-appengine] Re: A question about google app engine - thread id for performance profiling

2009-06-11 Thread Nick Johnson (Google)
Hi Liang Han,

(Replies inline)

On Thu, Jun 11, 2009 at 2:15 AM, Liang Han liang@gmail.com wrote:


 A simple application, which is running at the google app engine,
 visits the datastore, and uses the urlfetch service as well.I want
 to add the 6 hooks into the code to get the timestamp when code is
 running at that checkpoint, thus the transactions performance
 profiling can be done by calculating with the timestamps.

 Here's the flow in pseudo code:

 class MainPage(webapp.RequestHandler):
  def get(self):
-- 1. hook at program starting
do something ...
-- 2. hook before fetching url
result = urlfetch.fetch(url=http://...;)
-- 3. hook after fetching url
do something ...
-- 4. hook before visiting datastore
visit datastore
-- 5. hook after visiting datastore
do something
-- 6. finish hook

 Although it's straightforward to just add the hook code in the
 original code, however, in order to minimize the modification to
 existing code, I use the following approaches:

 1. Use apiproxy_stub_map.apiproxy.GetPreCallHooks().Append to add
 hooks to get data at checkpoint 2, 3, 4, 5.   I referenced the article
 http://code.google.com/appengine/articles/hooks.html

 2. Monkeypatch google.appengine.ext.webapp.WSGIApplication (assuming
 the original code is written with webapp framework) by overwritting
 def __call__(self, environ, start_response).  I just add my code
 before and after calling the real method.   Therefore, I can get data
 at checkpoint 1 and 6. The orignial code just need to modified to
 use the subclass of  WSGIApplication.


Cool stuff you're working on! Are you planning on releasing it for others to
use?




 Here's the problem I run into.
 Since multiple users might be visiting the same application at the
 sametime, in order not to mess up data from different users, we must
 be able to get a same id, such as thread id for the 6 checkpoints of
 each user.  However, I cannot achieve this.


App Engine apps run in a single-threaded environment. That is, a given
interpreter instance will only ever be processing one request at any given
time. Thus, you don't need to worry about concurrent invocations.

-Nick Johnson




 I have tried to use thread.get_ident(), but it always returns -1.  (I
 know google app engine doesn't allow create new thread, but it doesn't
 make any sense to return -1 for threads created by google engine
 itself ...)

 I tried to store some data at the thread local objects pool (just as I
 do with Java), but seems the thread.local is not the same with the one
 in Java.I'm not familiar with python anyway, maybe I miss
 something or misunderstand something.

 Do you guys have any idea about this?Thanks very much in advance!
 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Google App Engine group.
To post to this group, send email to google-appengine@googlegroups.com
To unsubscribe from this group, send email to 
google-appengine+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en
-~--~~~~--~~--~--~---



[google-appengine] Re: A question about google app engine - thread id for performance profiling

2009-06-11 Thread Andy Freeman

 While one instance has only one thread, there could be many instances
serving the same number of clients simultaneously.

Yes, and those separate instances are not threads, they're processes.
More important,
they may be running on different machines, so neither thread ids nor
process ids are guaranteed to be unique.  That's why using thread or
process ids as identifiers is guaranteed to be wrong in any system
that uses multiple machines, such as app engine.

Depending on how you're aggregating, one of the uuid variants might be
appropriate.

I tried to store some data at the thread local objects pool (just as I
   do with Java)

You're assuming persistence in an environment where persistence is
unlikely.

However, to the extent that there is persistence, you can simply store
stuff in memory because a given process may be used to run a number of
instances, one after another.  (Not simultaneously - simultaneous
instances run in different processes, possibly on different
machines.)  While an instance is running, it can see what other
instances that ran in the same process left in memory after they
finished.

However, said stuff in memory for a given process is only accessible
to the currently running instance.

On Jun 11, 6:58 am, Liang Han liang@gmail.com wrote:
 Nick,

 While one instance has only one thread, there could be many instances
 serving the same number of clients simultaneously.
 Thus, the metric from the multiple instances will be messed up,
 because the metric logs are recorded in the global area, such as
 memcache, or as the debug log.  (is there some area to store data per
 instance? or is there a way to get the instance id?)

 There shouldn't be any barrier for me to release the source code, but
 firstly, it has to work.

  App Engine apps run in a single-threaded environment. That is, a given
  interpreter instance will only ever be processing one request at any given
  time. Thus, you don't need to worry about concurrent invocations.

 On Jun 11, 6:15 pm, Nick Johnson (Google) nick.john...@google.com
 wrote:



  Hi Liang Han,

  (Replies inline)

  On Thu, Jun 11, 2009 at 2:15 AM, Liang Han liang@gmail.com wrote:

   A simple application, which is running at the google app engine,
   visits the datastore, and uses the urlfetch service as well.    I want
   to add the 6 hooks into the code to get the timestamp when code is
   running at that checkpoint, thus the transactions performance
   profiling can be done by calculating with the timestamps.

   Here's the flow in pseudo code:

   class MainPage(webapp.RequestHandler):
    def get(self):
      -- 1. hook at program starting
      do something ...
      -- 2. hook before fetching url
      result = urlfetch.fetch(url=http://...;)
      -- 3. hook after fetching url
      do something ...
      -- 4. hook before visiting datastore
      visit datastore
      -- 5. hook after visiting datastore
      do something
      -- 6. finish hook

   Although it's straightforward to just add the hook code in the
   original code, however, in order to minimize the modification to
   existing code, I use the following approaches:

   1. Use apiproxy_stub_map.apiproxy.GetPreCallHooks().Append to add
   hooks to get data at checkpoint 2, 3, 4, 5.   I referenced the article
  http://code.google.com/appengine/articles/hooks.html

   2. Monkeypatch google.appengine.ext.webapp.WSGIApplication (assuming
   the original code is written with webapp framework) by overwritting
   def __call__(self, environ, start_response).  I just add my code
   before and after calling the real method.   Therefore, I can get data
   at checkpoint 1 and 6.     The orignial code just need to modified to
   use the subclass of  WSGIApplication.

  Cool stuff you're working on! Are you planning on releasing it for others to
  use?

   Here's the problem I run into.
   Since multiple users might be visiting the same application at the
   sametime, in order not to mess up data from different users, we must
   be able to get a same id, such as thread id for the 6 checkpoints of
   each user.  However, I cannot achieve this.

  App Engine apps run in a single-threaded environment. That is, a given
  interpreter instance will only ever be processing one request at any given
  time. Thus, you don't need to worry about concurrent invocations.

  -Nick Johnson

   I have tried to use thread.get_ident(), but it always returns -1.  (I
   know google app engine doesn't allow create new thread, but it doesn't
   make any sense to return -1 for threads created by google engine
   itself ...)

   I tried to store some data at the thread local objects pool (just as I
   do with Java), but seems the thread.local is not the same with the one
   in Java.    I'm not familiar with python anyway, maybe I miss
   something or misunderstand something.

   Do you guys have any idea about this?    Thanks very much in advance!- 
   Hide quoted text -

 - Show quoted text -