Skip to content

Sync Gateway DB online offline implementation design notes

Andrew Reslan edited this page Jul 27, 2015 · 1 revision

#Implementation Notes

##Online/Offline operations must be Idempotent

In database.go

Add an RunState enum to track the state of a database here

type RunState int

const (
	Stopped RunState = iota
	Starting
	Running
	Stopping
)

Add a RunState member to DatabaseContext struct here

runstate		   RunState

A request to take a db offline/online will check the offline status, if the DB is already in the target status, take no action and return success status.

While state change is taking place write lock will be taken on DBContext

##Bringing a DB online

When a DB is going online the following actions must be taken

  1. Call Close() on the current DatabaseContext

  2. Reload the config for the DB instance being brought back online

  3. Call NewDatabaseContext() for loaded configuration

  4. Replace old DatabaseContext with new DatabaseContext

##Taking a DB offline.

When a DB is taken offline the following actions must be taken

  1. Take a write lock on the DatabaseContext, set offline to true

Update handler.go

Add the following member to the handler struct

runoffline          bool

Add a makeOfflineHandler function as a duplicate of makeHandler

Update the newHandler function to take a boolean to indicate that the handler should still run when the associated database of offline.

func newHandler(server *ServerContext, privs handlerPrivs, r http.ResponseWriter, rq *http.Request, bool runOffline)) *handler {

Use the boolean to set the runOffline member of the handler struct

Update makeHandler so that it passes a 'false' value to newHandler runOffline argument

Update makeOfflineHandler so that it passes a 'true' to newHandler runOffline argument

In the invoke function if there is a dbContext for the current call check the DB runtime state here)

If the state is 'Running', continue processing the request as normal.

Otherwise if the state is 'Offline' check if handler runoffline is true. If it is continue processing as normal, otherwise return an error with HTTP status

503 Service Unavailable “Service is currently under maintenance”

otherwise process request as normal

  1. Pass an "Exit" message into any active changes feeds for the DB

Add a termination channel to the DatabaseContext struct

When creating a changes feed pass the termination channel

In the changes feed select statement, add an additional case for the termination channel. Close the changes feed when a message is received.

when a database is taken offline, close the termination channel, this will cause each changes feed to be terminated.

  1. (OPTIONAL) when a DB is being taken offline all open requests against the DB should be drained and the appropriate error code returned to the client. The current architecture may not easily support this, the decision to implement will depend on the estimated level of effort vs the added value to clients.

There is no plan to implement this, as an alternative the number of open connection against a DB will be tracked, so that offline actions can wait for all synchronous calls to close before executing.

Each synchronous call will take a read lock on the DB context, with a deferred close();

Offline operations that should not run until all synchronous calls have completed (e.g. _resync) will take a write lock on the DBContext, and block until the lock is available

#Operations supported while a DB is offline. While a DB is offline the following administrative operations will still be functional.

  1. /db/ REST API, the response will contain an offline property

The property value will be read from the DatabaseContext offline

“offline”:true

  1. Add a new handler for PUT method on /db/_config/

Add

handlePutDbConfig

  1. Run a _resync for an updated sync function

A DB Should be offline when calling _resync via the REST API, if the DB is online an error status code should be returned to the caller. The main steps of the _resync function are:

  1. Follow same process to bring DB online
  2. Set DatabaseContext offline to true
  3. Resync all document in the DB

##Auto detect TAP feed offline

This will implemented in a separate ticket and will be built over the online/offline functionality.

Creating a DB

When creating a DB via REST API a caller can pass “offline”:true, Sync Gateway will create the DB but leave it in the offline state.

This should require no additional changes

Clone this wiki locally