本文整理匯總了Golang中github.com/couchbase/sync_gateway/db.ChangesOptions.Wait方法的典型用法代碼示例。如果您正苦於以下問題:Golang ChangesOptions.Wait方法的具體用法?Golang ChangesOptions.Wait怎麽用?Golang ChangesOptions.Wait使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類github.com/couchbase/sync_gateway/db.ChangesOptions
的用法示例。
在下文中一共展示了ChangesOptions.Wait方法的4個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: handleChanges
//.........這裏部分代碼省略.........
if err != nil {
err = base.HTTPErrorf(http.StatusBadRequest, "Bad doc id's")
}
if len(docidKeys) > 0 {
docIdsArray = docidKeys
}
}
options.HeartbeatMs = getRestrictedIntQuery(
h.rq.URL.Query(),
"heartbeat",
kDefaultHeartbeatMS,
kMinHeartbeatMS,
h.server.config.MaxHeartbeat*1000,
true,
)
options.TimeoutMs = getRestrictedIntQuery(
h.rq.URL.Query(),
"timeout",
kDefaultTimeoutMS,
0,
kMaxTimeoutMS,
true,
)
} else {
// POST request has parameters in JSON body:
body, err := h.readBody()
if err != nil {
return err
}
feed, options, filter, channelsArray, docIdsArray, _, err = h.readChangesOptionsFromJSON(body)
if err != nil {
return err
}
}
// Get the channels as parameters to an imaginary "bychannel" filter.
// The default is all channels the user can access.
userChannels := channels.SetOf(channels.AllChannelWildcard)
if filter != "" {
if filter == "sync_gateway/bychannel" {
if channelsArray == nil {
return base.HTTPErrorf(http.StatusBadRequest, "Missing 'channels' filter parameter")
}
var err error
userChannels, err = channels.SetFromArray(channelsArray, channels.ExpandStar)
if err != nil {
return err
}
if len(userChannels) == 0 {
return base.HTTPErrorf(http.StatusBadRequest, "Empty channel list")
}
} else if filter == "_doc_ids" {
if docIdsArray == nil {
return base.HTTPErrorf(http.StatusBadRequest, "Missing 'doc_ids' filter parameter")
}
if len(docIdsArray) == 0 {
return base.HTTPErrorf(http.StatusBadRequest, "Empty doc_ids list")
}
} else {
return base.HTTPErrorf(http.StatusBadRequest, "Unknown filter; try sync_gateway/bychannel or _doc_ids")
}
}
h.db.ChangesClientStats.Increment()
defer h.db.ChangesClientStats.Decrement()
options.Terminator = make(chan bool)
var err error
forceClose := false
switch feed {
case "normal", "":
if filter == "_doc_ids" {
err, forceClose = h.sendChangesForDocIds(userChannels, docIdsArray, options)
} else {
err, forceClose = h.sendSimpleChanges(userChannels, options)
}
case "longpoll":
options.Wait = true
err, forceClose = h.sendSimpleChanges(userChannels, options)
case "continuous":
err, forceClose = h.sendContinuousChangesByHTTP(userChannels, options)
case "websocket":
err, forceClose = h.sendContinuousChangesByWebSocket(userChannels, options)
default:
err = base.HTTPErrorf(http.StatusBadRequest, "Unknown feed type")
forceClose = false
}
close(options.Terminator)
if forceClose && h.user != nil {
h.db.DatabaseContext.NotifyUser(h.user.Name())
}
return err
}
示例2: handleChanges
// Top-level handler for _changes feed requests. Accepts GET or POST requests.
func (h *handler) handleChanges() error {
// http://wiki.apache.org/couchdb/HTTP_database_API#Changes
// http://docs.couchdb.org/en/latest/api/database/changes.html
restExpvars.Add("changesFeeds_total", 1)
restExpvars.Add("changesFeeds_active", 1)
defer restExpvars.Add("changesFeeds_active", -1)
var feed string
var options db.ChangesOptions
var filter string
var channelsArray []string
if h.rq.Method == "GET" {
// GET request has parameters in URL:
feed = h.getQuery("feed")
var err error
if options.Since, err = db.ParseSequenceID(h.getQuery("since")); err != nil {
return err
}
options.Limit = int(h.getIntQuery("limit", 0))
options.Conflicts = (h.getQuery("style") == "all_docs")
options.IncludeDocs = (h.getBoolQuery("include_docs"))
filter = h.getQuery("filter")
channelsParam := h.getQuery("channels")
if channelsParam != "" {
channelsArray = strings.Split(channelsParam, ",")
}
options.HeartbeatMs = getRestrictedIntQuery(h.rq.URL.Query(), "heartbeat", 0, kMinHeartbeatMS, 0)
options.TimeoutMs = getRestrictedIntQuery(h.rq.URL.Query(), "timeout", kDefaultTimeoutMS, 0, kMaxTimeoutMS)
} else {
// POST request has parameters in JSON body:
body, err := h.readBody()
if err != nil {
return err
}
feed, options, filter, channelsArray, err = readChangesOptionsFromJSON(body)
if err != nil {
return err
}
}
// Get the channels as parameters to an imaginary "bychannel" filter.
// The default is all channels the user can access.
userChannels := channels.SetOf(channels.AllChannelWildcard)
if filter != "" {
if filter != "sync_gateway/bychannel" {
return base.HTTPErrorf(http.StatusBadRequest, "Unknown filter; try sync_gateway/bychannel")
}
if channelsArray == nil {
return base.HTTPErrorf(http.StatusBadRequest, "Missing 'channels' filter parameter")
}
var err error
userChannels, err = channels.SetFromArray(channelsArray, channels.ExpandStar)
if err != nil {
return err
}
if len(userChannels) == 0 {
return base.HTTPErrorf(http.StatusBadRequest, "Empty channel list")
}
}
h.db.ChangesClientStats.Increment()
defer h.db.ChangesClientStats.Decrement()
options.Terminator = make(chan bool)
defer close(options.Terminator)
switch feed {
case "normal", "":
return h.sendSimpleChanges(userChannels, options)
case "longpoll":
options.Wait = true
return h.sendSimpleChanges(userChannels, options)
case "continuous":
return h.sendContinuousChangesByHTTP(userChannels, options)
case "websocket":
return h.sendContinuousChangesByWebSocket(userChannels, options)
default:
return base.HTTPErrorf(http.StatusBadRequest, "Unknown feed type")
}
}
示例3: generateContinuousChanges
// This is the core functionality of both the HTTP and WebSocket-based continuous change feed.
// It defers to a callback function 'send()' to actually send the changes to the client.
// It will call send(nil) to notify that it's caught up and waiting for new changes, or as
// a periodic heartbeat while waiting.
func (h *handler) generateContinuousChanges(inChannels base.Set, options db.ChangesOptions, send func([]*db.ChangeEntry) error) (error, bool) {
// Set up heartbeat/timeout
var timeoutInterval time.Duration
var timer *time.Timer
var heartbeat <-chan time.Time
if options.HeartbeatMs > 0 {
ticker := time.NewTicker(time.Duration(options.HeartbeatMs) * time.Millisecond)
defer ticker.Stop()
heartbeat = ticker.C
} else if options.TimeoutMs > 0 {
timeoutInterval = time.Duration(options.TimeoutMs) * time.Millisecond
defer func() {
if timer != nil {
timer.Stop()
}
}()
}
options.Wait = true // we want the feed channel to wait for changes
options.Continuous = true // and to keep sending changes indefinitely
var lastSeq db.SequenceID
var feed <-chan *db.ChangeEntry
var timeout <-chan time.Time
var err error
var closeNotify <-chan bool
cn, ok := h.response.(http.CloseNotifier)
if ok {
closeNotify = cn.CloseNotify()
} else {
base.LogTo("Changes", "continuous changes cannot get Close Notifier from ResponseWriter")
}
forceClose := false
loop:
for {
if feed == nil {
// Refresh the feed of all current changes:
if lastSeq.IsNonZero() { // start after end of last feed
options.Since = lastSeq
}
if h.db.IsClosed() {
forceClose = true
break loop
}
feed, err = h.db.MultiChangesFeed(inChannels, options)
if err != nil || feed == nil {
return err, forceClose
}
}
if timeoutInterval > 0 && timer == nil {
// Timeout resets after every change is sent
timer = time.NewTimer(timeoutInterval)
timeout = timer.C
}
// Wait for either a new change, a heartbeat, or a timeout:
select {
case entry, ok := <-feed:
if !ok {
feed = nil
} else if entry == nil {
err = send(nil)
} else if entry.Err != nil {
break loop // error returned by feed - end changes
} else {
entries := []*db.ChangeEntry{entry}
waiting := false
// Batch up as many entries as we can without waiting:
collect:
for len(entries) < 20 {
select {
case entry, ok = <-feed:
if !ok {
feed = nil
break collect
} else if entry == nil {
waiting = true
break collect
} else if entry.Err != nil {
break loop // error returned by feed - end changes
}
entries = append(entries, entry)
default:
break collect
}
}
base.LogTo("Changes", "sending %d change(s)", len(entries))
err = send(entries)
if err == nil && waiting {
err = send(nil)
}
//.........這裏部分代碼省略.........
示例4: generateContinuousChanges
// This is the core functionality of both the HTTP and WebSocket-based continuous change feed.
// It defers to a callback function 'send()' to actually send the changes to the client.
// It will call send(nil) to notify that it's caught up and waiting for new changes, or as
// a periodic heartbeat while waiting.
func (h *handler) generateContinuousChanges(inChannels base.Set, options db.ChangesOptions, send func([]*db.ChangeEntry) error) error {
// Set up heartbeat/timeout
var timeoutInterval time.Duration
var timer *time.Timer
var heartbeat <-chan time.Time
if options.HeartbeatMs > 0 {
ticker := time.NewTicker(time.Duration(options.HeartbeatMs) * time.Millisecond)
defer ticker.Stop()
heartbeat = ticker.C
} else if options.TimeoutMs > 0 {
timeoutInterval = time.Duration(options.TimeoutMs) * time.Millisecond
defer func() {
if timer != nil {
timer.Stop()
}
}()
}
options.Wait = true // we want the feed channel to wait for changes
options.Continuous = true // and to keep sending changes indefinitely
var lastSeq db.SequenceID
var feed <-chan *db.ChangeEntry
var timeout <-chan time.Time
var err error
loop:
for {
if feed == nil {
// Refresh the feed of all current changes:
if lastSeq.Seq > 0 { // start after end of last feed
options.Since = lastSeq
}
if h.db.IsClosed() {
break loop
}
feed, err = h.db.MultiChangesFeed(inChannels, options)
if err != nil || feed == nil {
return err
}
}
if timeoutInterval > 0 && timer == nil {
// Timeout resets after every change is sent
timer = time.NewTimer(timeoutInterval)
timeout = timer.C
}
// Wait for either a new change, a heartbeat, or a timeout:
select {
case entry, ok := <-feed:
if !ok {
feed = nil
} else if entry == nil {
err = send(nil)
} else {
entries := []*db.ChangeEntry{entry}
waiting := false
// Batch up as many entries as we can without waiting:
collect:
for len(entries) < 20 {
select {
case entry, ok = <-feed:
if !ok {
feed = nil
break collect
} else if entry == nil {
waiting = true
break collect
}
entries = append(entries, entry)
default:
break collect
}
}
base.LogTo("Changes", "sending %d change(s)", len(entries))
err = send(entries)
if err == nil && waiting {
err = send(nil)
}
lastSeq = entries[len(entries)-1].Seq
if options.Limit > 0 {
if len(entries) >= options.Limit {
break loop
}
options.Limit -= len(entries)
}
}
// Reset the timeout after sending an entry:
if timer != nil {
timer.Stop()
timer = nil
}
case <-heartbeat:
err = send(nil)
//.........這裏部分代碼省略.........