Making the datastore readonly temporarily

18 views
Skip to first unread message

Alkis Evlogimenos ('Αλκης Ευλογημένος)

unread,
Apr 28, 2009, 8:26:10 AM4/28/09
to google-a...@googlegroups.com
Sometimes you want to make the datastore readonly for users to perform some global changes (say schema update).

How do people achieve this?

Out of what I can think of:
- Do you write another version of your application that errors on each request that writes to the datastore? This seems error prone and a maintenance headache.
- Do you monkeypatch db.put and db.delete to unconditionally throw an exception and make that exception visible to the frontend?
- Do you use hooks and pre hook datastore operations to throw an exception and make that exception visible to the frontend?

Any other ideas?

--

Alkis

djidjadji

unread,
Apr 28, 2009, 8:58:43 AM4/28/09
to google-a...@googlegroups.com
If you don't have to do it often you can use the following method.

Make a version of the application that displays a page that the site
is temporarily under maintenance. Give an estimate for how long it
will take.
app.yaml redirects all requests to maintenance.py

Find a time of day where the site is less busy.
Make the maintenance version current.
Update version X to the new schema.
Do the update using urls http://X.latest.myapp.appspot.com
Test the update
Make X the new version.

This is the least hassle, I think.

2009/4/28 Alkis Evlogimenos ('Αλκης Ευλογημένος) <evlog...@gmail.com>:

Alkis Evlogimenos ('Αλκης Ευλογημένος)

unread,
Apr 28, 2009, 9:07:06 AM4/28/09
to google-a...@googlegroups.com
Yes but this means no access to the site for the duration. I want to have read only access to the site for the duration.

2009/4/28 djidjadji <djid...@gmail.com>



--

Alkis

Jason (Google)

unread,
Apr 30, 2009, 6:43:41 PM4/30/09
to google-a...@googlegroups.com
I second djidjadji's suggestion. While it's true that your application will be unavailable, it's definitely the simplest solution and gives your users a clear expectation that some of your application's functionality is not available; otherwise, they might be confused why some aspects of your site work but others don't, especially if your messaging is subtle.

The only other suggestion is to wrap all of your write calls to the datastore so you can easily disable them altogether. That's tricker than the first solution, however.

- Jason

Alkis Evlogimenos ('Αλκης Ευλογημένος)

unread,
Apr 30, 2009, 6:52:29 PM4/30/09
to google-a...@googlegroups.com
I ended up with this:

class ReadOnlyError(db.Error):
  pass

def make_datastore_readonly():
  """Throw ReadOnlyError on put and delete operations."""
  def hook(service, call, request, response):
    assert(service == 'datastore_v3')
    if users.is_current_user_admin():
      return
    if call in ('Put', 'Delete'):
      raise ReadOnlyError('Datastore is in read-only mode')

  apiproxy_stub_map.apiproxy.
GetPreCallHooks().Push(
    'readonly_datastore', hook, 'datastore_v3')

And special cased the ReadOnlyError exception in the read handler to print out an error (503) that shows the site is on read only mode. Then I did the migration, everything went fine :-)


2009/5/1 Jason (Google) <apij...@google.com>



--

Alkis
Reply all
Reply to author
Forward
0 new messages