hashmap losing references over time

30 views
Skip to first unread message

Peter Warren

unread,
Nov 5, 2009, 6:48:16 PM11/5/09
to Google App Engine
I have a hashmap on app engine that loses its contents after 5-10
minutes. Does app engine release unused objects after a timeout? I
couldn't find any relevant documentation.

My caching class (code below) holds references to uploaded objects and
also stores a serialized version of the uploaded object in the
datastore. When a client requests an object, the cache is checked
first. If the object isn't in the cache, the object is retrieved from
the datastore.

When the cache is empty, remote retrieval of an object (1k in size)
takes about 6-7 seconds, I assume for the fetch from datastore and
deserialization. When the object is in cache it takes around 160ms.
(#s are from Firebug.)

I confirmed with debug code that my hashmap is indeed being emptied
after a while and that it's not client caching or other code issues.

I cannot reproduce this locally with the app engine plugin for
eclipse.

Is there a way to make the app engine leave my hashmap alone?

Thanks for any help,
Peter

-----
private static ConfiguratorStorage storage = new
ConfiguratorStorage();

private HashMap<ConfiguratorID, Configurator> idToConfiguratorMap;

private ConfiguratorStorage() {
idToConfiguratorMap = new HashMap<ConfiguratorID, Configurator>
();
}

public static ConfiguratorStorage getInstance() {
return storage;
}

public Configurator getConfigurator(ConfiguratorID id) {
Configurator configurator = idToConfiguratorMap.get(id);
if (configurator == null) {
PersistenceManager persistenceManager =
Persistence.getPersistenceManagerFactory().getPersistenceManager();
try {
ConfiguratorDAO wrapper =
persistenceManager.getObjectById(ConfiguratorDAO.class, id.toString
());
configurator = wrapper.getConfigurator();
idToConfiguratorMap.put(configurator.getConfiguratorID
(), configurator);
} catch (JDOObjectNotFoundException nfe) {
// do nothing
} finally {
persistenceManager.close();
}
}
return configurator;
}

public void saveConfigurator(Configurator configurator, String
xml) throws IOException {
idToConfiguratorMap.put(configurator.getConfiguratorID(),
configurator);
PersistenceManager persistenceManager =
Persistence.getPersistenceManagerFactory().getPersistenceManager();
ConfiguratorDAO wrapper = new ConfiguratorDAO(configurator);
try {
persistenceManager.makePersistent(wrapper);
} finally {
persistenceManager.close();
}
}
-----

Tim Hoffman

unread,
Nov 5, 2009, 9:49:58 PM11/5/09
to Google App Engine
If you cache is in memory (ie not stored memcache or the datastore)
then if the instance holding the hashmap is shutdown from inactivity
(oftern in less than two minutes) you will lose everything.

Stuff in memcache will dissappear too, though for other reasons
(memory pressure, time ...) but
will tend to stay around longer than instance memory, and is shared
between all instances. However it will dissapear too
at some point so you need to deal with that as well.

The only thing guarunteed to hand around is data you persist in the
data store

When you say "remote retrieval takes 6-7 secs" I assume you don't mean
from the datastore?

T

Peter Warren

unread,
Nov 6, 2009, 12:52:30 PM11/6/09
to Google App Engine
> If you cache is in memory (ie not stored memcache or the datastore)
> then if the instance holding the hashmap is shutdown from inactivity
> (oftern in less than two minutes) you will lose everything.

I didn't realize inactive apps got shut down. That seems to be the
root of the problem.

> When you say "remote retrieval takes 6-7 secs" I assume you don't mean from the datastore?

6-7 seconds is the amount of time for my web brower to receive a
response to its request for an object from the server. It seems that
all that time is spent re-starting the app. Once the app is re-
started, retrieving and de-serializing (I'm storing my objects as
serialized blobs due to datanucleus choking on some generic classes)
an object from the datastore takes around 200ms. For example, getting
2 objects from datastore after inactive interval: first takes 6-7
seconds, second takes 200ms.

So... is there any way to keep my app from being inactivated? I could
schedule a cron job to ping my app every couple minutes. Is that the
recommended solution?

Oddly enough, looking at the cron documentation, their first example
entry is:

<cron>
<url>/recache</url>
<description>Repopulate the cache every 2 minutes</description>
<schedule>every 2 minutes</schedule>
</cron>

Peter

Nick Johnson (Google)

unread,
Nov 6, 2009, 12:59:46 PM11/6/09
to google-a...@googlegroups.com
Hi Peter,

On Fri, Nov 6, 2009 at 5:52 PM, Peter Warren <pe...@nomad.org> wrote:

> If you cache is in memory (ie not stored memcache or the datastore)
> then if the instance holding the hashmap is shutdown from inactivity
> (oftern in less than two minutes) you will lose everything.

I didn't realize inactive apps got shut down.  That seems to be the
root of the problem.

App Engine is a clustered service, so you cannot rely on subsequent requests hitting the same instance of the app in any case. You need to use memcache if it's important that cached data be accessible to all requests, or the datastore otherwise.

-Nick Johnson



--
Nick Johnson, Developer Programs Engineer, App Engine
Google Ireland Ltd. :: Registered in Dublin, Ireland, Registration Number: 368047

Peter Warren

unread,
Nov 6, 2009, 1:34:44 PM11/6/09
to Google App Engine
Thanks for your response, Nick.

I am now using memcache and notice the same lag when making a request
after an inactive interval of more than around 5 minutes. I am
assuming now that this lag is due to app engine re-starting an
instance of my application and not data access. I assume this because
after an inactive interval only the first request for an object takes
a long time.

I thought initially the lag was due to having to re-populate my
cache. I now believe the lag is due to app engine re-starting an
instance of my app.

Seems that a periodic url request (e.g. via a cron job) would keep my
app instance alive and avoid the startup lag. Are there other ways to
keep the app instance alive?

Thanks,
Peter

On Nov 6, 9:59 am, "Nick Johnson (Google)" <nick.john...@google.com>
wrote:

Roy Smith

unread,
Nov 6, 2009, 9:18:15 PM11/6/09
to google-a...@googlegroups.com
This is an oft discussed feature of appengine. If you search for "cron" in this group, you'll see several discussuions which all seem to come to the same conclusion as you've done. I think there may even be an issue request for paid-for hot instances.
Reply all
Reply to author
Forward
0 new messages