-
Notifications
You must be signed in to change notification settings - Fork 138
Sync Gateway DB online offline implementation design notes
#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
-
Call Close() on the current DatabaseContext
-
Reload the config for the DB instance being brought back online
-
Call NewDatabaseContext() for loaded configuration
-
Replace old DatabaseContext with new DatabaseContext
##Taking a DB offline.
When a DB is taken offline the following actions must be taken
- 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
- 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.
- (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.
- /db/ REST API, the response will contain an offline property
The property value will be read from the DatabaseContext offline
“offline”:true
- Add a new handler for PUT method on /db/_config/
Add
handlePutDbConfig
- 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:
- Follow same process to bring DB online
- Set DatabaseContext offline to true
- 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.
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