// 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 }
func closeHandler(userId int64, cn http.CloseNotifier) { <-cn.CloseNotify() }