Discusses how you can use the capabilities API and/or the CapabilityDisabled exceptions to catch and handle errors during planned or unplanned downtimes and help maintain a good user experience.
4. Capabilities API - datastore
is_enabled method can be used to test whether a certain
capability is currently enabled.
datastore_writes = CapabilitySet(
'datastore_v3',
capabilities=['write'])
if not datastore_writes.is_enabled():
# ...render form with form elements disabled
# or, if a form is submitted, push a new task
# to the task queue
else:
# ...render form normally
5. Capabilities API - datastore
will_remain_enabled_for method can be used to learn whether
a component will be disabled within a certain number of
seconds
datastore_writes = CapabilitySet(
'datastore_v3',
capabilities=['write'])
if datastore_writes.will_remain_enabled_for(60):
# ...render form normally
else:
# ...render form with form elements disabled
6. Capabilities API - memcache
The capabilities API can be used with other services including
memcache...
memcache_set = CapabilitySet(
'memcache',
methods=['set'])
if memcache_set.is_enabled():
# ...fetch from cache
else:
# ...bypass cache
7. Capabilities API - images
... as well as the Images service.
images_capability = CapabilitySet('images')
if images_capability.is_enabled():
my_image = images.resize(my_image, 64, 64)
8. Capabilities API
Pros:
Automated -- no changes needed when read-only mode
begins or ends
Allows for datastore writes to be "deferred" by pushing a
new task to the task queue instead of writing immediately;
the task will be continually re-tried until the task succeeds,
so the write should occur eventually.
Cons:
Python-only (for now)
Undocumented (for now)
see google/appengine/api/capabilities SDK directory
10. Exception handling - Python
Python:
http://code.google.com/appengine/docs/python/howto/maintenance.html
from google.appengine.ext import db
import google.appengine.runtime.apiproxy_errors
myModel = db.Model()
try:
myModel.put()
except apiproxy_errors.CapabilityDisabledError:
# fail gracefully here or add a new task to the
# task queue that writes the new entity when
# the datastore is available
12. Memcache exception handling - Java
Java:
http://code.google.com/appengine/docs/java/howto/maintenance.html
As with Python, memcache is unavailable during read-only
mode and exceptions aren't thrown by default.
You can use a StrictErrorHandler if you want an exception
thrown when get and put aren't available.
14. Exception handling
Pros:
Automated -- no changes needed when read-only mode
begins or ends
Allows for datastore writes to be "deferred" by pushing a
new task to the task queue instead of writing immediately;
the task will be continually re-tried until the task succeeds,
so the write should occur eventually.
Cons:
Reactive -- exception is caught only after the read or write
call is processed, unlike the first solution.
Complicates code slightly -- the exception needs to be
caught for every write attempt.
15. Note on using tasks to defer writes
The task queue allows you defer writes when the datastore is
unavailable -- you can add a new task instead, which the
system will automatically retry in the background until it
succeeds.
If you choose this approach, keep the following in mind:
The number of tasks that you can add per day is currently
limited to 1,000,000. If your app receives a lot of write traffic
(e.g. > 350 QPS), you could exceed this quota unless the
period of unavailability is short.
Consider adding a timestamp field to your entities plus extra
logic so you don't accidentally overwrite a later update when
the tasks are applied.
20. Read-only versions
Pros:
Proactive -- e.g. users see a grayed-out form instead of an
error on save
Cons:
Manual -- it's your responsibility to be aware of and switch
versions before read-only mode starts and after it ends
Only useful for planned downtimes -- unless other mitigation
strategies are in place, your app will still go down during
unplanned downtimes.
Maintenance
21. Thanks!
Jason Cooper
Google Developer Programs
jasonacooper@google.com
April 6, 2010