示例#1
0
// deliver routes an incoming update to the appropriate server.
func (h *EndpointHandler) deliver(cn http.CloseNotifier, uaid, chid string,
	version int64, requestID string, data string) (delivered bool) {

	worker, workerConnected := h.app.GetWorker(uaid)
	var routingTime time.Duration

	// Always route to other servers first, in case we're holding open a stale
	// connection and the client has already reconnected to a different server.
	shouldRoute := h.alwaysRoute || !workerConnected

	if shouldRoute {
		h.metrics.Increment("updates.routed.outgoing")
		// Abort routing if the connection goes away.
		var cancelSignal <-chan bool
		if cn != nil {
			cancelSignal = cn.CloseNotify()
		}
		// Route the update.
		startTime := timeNow().UTC()
		delivered, _ = h.router.Route(cancelSignal, uaid, chid, version,
			startTime, requestID, data)
		routingTime = timeNow().UTC().Sub(startTime)

		// Increment appropriate metrics
		if delivered {
			h.metrics.Increment("router.broadcast.hit")
			h.metrics.Timer("updates.routed.hits", routingTime)
		} else {
			h.metrics.Increment("router.broadcast.miss")
			h.metrics.Timer("updates.routed.misses", routingTime)
		}
	}

	// Should we attempt local delivery? Only if the worker is connected
	// and we either always route, or failed to remote deliver
	shouldLocalDeliver := workerConnected && (h.alwaysRoute || !delivered)

	if shouldLocalDeliver {
		if err := worker.Send(chid, version, data); err == nil {
			delivered = true
		}
	}

	// Increment the appropriate final metric whether deliver did or
	// did not work
	if delivered {
		h.metrics.Increment("updates.appserver.received")
	} else {
		h.metrics.Increment("updates.appserver.rejected")
	}

	return delivered
}
示例#2
0
func closeHandler(userId int64, cn http.CloseNotifier) {
	<-cn.CloseNotify()
}