This came up in IRC, but there's some interest in read-only Phabricator. Some use cases:
- Lower-effort alternative to real HA which doesn't require intervention to switch or manage database masters. This was the driving use case here. Basically, trade writes away to get lower administrative costs.
- Allow Phabricator to stay up in read-only mode while updating, performing maintenance, etc, without risking data loss. This has come up as a nice-to-have in the past.
I think we can do this relatively easily. Roughly:
- Implement a read-only config flag. In this mode, we throw when establishing a write connection.
- No-op all the nonessential writes we perform when read-only is set (user access logging and cache fills come to mind).
- ApplicationSearch might be a little tricky, but should be able to switch to a pure GET mode.
- Eventually, remove write options from the UI, too, to make it clearer to users that they can't do writes.
The only tricky part that's critical is that we need an alternate, writable session store. Some ideas on this:
- The most obvious thing is to write things to SQLite or disk, but this seems fairly complicated, won't generalize, and won't scale across multiple readers.
- We could write to a second MySQL, or a specific table in MySQL which is only present for readers. This would work, but require more work and configuration from everyone.
- We could issue sessions without requiring storage:
- Define a new readonly session type which is only valid for readonly installs.
- The session cookie is <time, hash(time + user secret + application secret)> and good for a short period of time. Where we currently extend the session, we rotate the cookie instead.
- This isn't as nice as a writable session store from a security perspective, but is much simpler than alternatives.
After thinking about this, I lean heavily toward just defining a read-only session type for dealing with auth, since it's like 10x less dedicated code than anything else, and can be made approximately as secure.