Commit 47e13382 authored by Serene H's avatar Serene H
Browse files

initial client roundtrip estimate on broker

parent 6cecd31f
...@@ -26,6 +26,7 @@ type BrokerContext struct { ...@@ -26,6 +26,7 @@ type BrokerContext struct {
// the second http POST. // the second http POST.
idToSnowflake map[string]*Snowflake idToSnowflake map[string]*Snowflake
proxyPolls chan *ProxyPoll proxyPolls chan *ProxyPoll
metrics *Metrics
} }
func NewBrokerContext() *BrokerContext { func NewBrokerContext() *BrokerContext {
...@@ -35,6 +36,7 @@ func NewBrokerContext() *BrokerContext { ...@@ -35,6 +36,7 @@ func NewBrokerContext() *BrokerContext {
snowflakes: snowflakes, snowflakes: snowflakes,
idToSnowflake: make(map[string]*Snowflake), idToSnowflake: make(map[string]*Snowflake),
proxyPolls: make(chan *ProxyPoll), proxyPolls: make(chan *ProxyPoll),
metrics: new(Metrics),
} }
} }
...@@ -67,7 +69,7 @@ func (ctx *BrokerContext) RequestOffer(id string) []byte { ...@@ -67,7 +69,7 @@ func (ctx *BrokerContext) RequestOffer(id string) []byte {
request.id = id request.id = id
request.offerChannel = make(chan []byte) request.offerChannel = make(chan []byte)
ctx.proxyPolls <- request ctx.proxyPolls <- request
// Block until an offer is available... // Block until an offer is available, or timeout which sends a nil offer.
offer := <-request.offerChannel offer := <-request.offerChannel
return offer return offer
} }
...@@ -96,6 +98,8 @@ func (ctx *BrokerContext) Broker() { ...@@ -96,6 +98,8 @@ func (ctx *BrokerContext) Broker() {
} }
// Create and add a Snowflake to the heap. // Create and add a Snowflake to the heap.
// Required to keep track of proxies between providing them
// with an offer and awaiting their second POST with an answer.
func (ctx *BrokerContext) AddSnowflake(id string) *Snowflake { func (ctx *BrokerContext) AddSnowflake(id string) *Snowflake {
snowflake := new(Snowflake) snowflake := new(Snowflake)
snowflake.id = id snowflake.id = id
...@@ -141,29 +145,32 @@ snowflake proxy, which responds with the SDP answer to be sent in ...@@ -141,29 +145,32 @@ snowflake proxy, which responds with the SDP answer to be sent in
the HTTP response back to the client. the HTTP response back to the client.
*/ */
func clientOffers(ctx *BrokerContext, w http.ResponseWriter, r *http.Request) { func clientOffers(ctx *BrokerContext, w http.ResponseWriter, r *http.Request) {
startTime := time.Now()
offer, err := ioutil.ReadAll(r.Body) offer, err := ioutil.ReadAll(r.Body)
if nil != err { if nil != err {
log.Println("Invalid data.") log.Println("Invalid data.")
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
// Immediately fail if there are no snowflakes available.
// Find the most available snowflake proxy, and pass the offer to it.
// TODO: Needs improvement - maybe shouldn't immediately fail?
if ctx.snowflakes.Len() <= 0 { if ctx.snowflakes.Len() <= 0 {
log.Println("Client: No snowflake proxies available.") log.Println("Client: No snowflake proxies available.")
w.WriteHeader(http.StatusServiceUnavailable) w.WriteHeader(http.StatusServiceUnavailable)
return return
} }
// Otherwise, find the most available snowflake proxy, and pass the offer to it.
snowflake := heap.Pop(ctx.snowflakes).(*Snowflake) snowflake := heap.Pop(ctx.snowflakes).(*Snowflake)
defer delete(ctx.idToSnowflake, snowflake.id) delete(ctx.idToSnowflake, snowflake.id)
snowflake.offerChannel <- offer snowflake.offerChannel <- offer
// Wait for the answer to be returned on the channel. // Wait for the answer to be returned on the channel or timeout.
select { select {
case answer := <-snowflake.answerChannel: case answer := <-snowflake.answerChannel:
log.Println("Client: Retrieving answer") log.Println("Client: Retrieving answer")
w.Write(answer) w.Write(answer)
// Initial tracking of elapsed time.
ctx.metrics.clientRoundtripEstimate = time.Since(startTime) /
time.Millisecond
case <-time.After(time.Second * ClientTimeout): case <-time.After(time.Second * ClientTimeout):
log.Println("Client: Timed out.") log.Println("Client: Timed out.")
w.WriteHeader(http.StatusGatewayTimeout) w.WriteHeader(http.StatusGatewayTimeout)
...@@ -196,7 +203,11 @@ func proxyAnswers(ctx *BrokerContext, w http.ResponseWriter, r *http.Request) { ...@@ -196,7 +203,11 @@ func proxyAnswers(ctx *BrokerContext, w http.ResponseWriter, r *http.Request) {
} }
func debugHandler(ctx *BrokerContext, w http.ResponseWriter, r *http.Request) { func debugHandler(ctx *BrokerContext, w http.ResponseWriter, r *http.Request) {
s := fmt.Sprintf("current: %d", ctx.snowflakes.Len()) s := fmt.Sprintf("current snowflakes available: %d\n", ctx.snowflakes.Len())
for _, snowflake := range ctx.idToSnowflake {
s += fmt.Sprintf("\nsnowflake %d: %s", snowflake.index, snowflake.id)
}
s += fmt.Sprintf("\n\nroundtrip avg: %d", ctx.metrics.clientRoundtripEstimate)
w.Write([]byte(s)) w.Write([]byte(s))
} }
......
package snowflake_broker
import (
// "golang.org/x/net/internal/timeseries"
"time"
)
// Implements Observable
type Metrics struct {
// snowflakes timeseries.Float
clientRoundtripEstimate time.Duration
}
func NewMetrics() *Metrics {
m := new(Metrics)
return m
}
...@@ -5,6 +5,6 @@ ClientTransportPlugin snowflake exec ./client \ ...@@ -5,6 +5,6 @@ ClientTransportPlugin snowflake exec ./client \
-url https://snowflake-reg.appspot.com/ \ -url https://snowflake-reg.appspot.com/ \
-front www.google.com \ -front www.google.com \
-ice stun:stun.l.google.com:19302 \ -ice stun:stun.l.google.com:19302 \
-max 1 -max 3
Bridge snowflake 0.0.3.0:1 Bridge snowflake 0.0.3.0:1
...@@ -125,6 +125,7 @@ class Snowflake ...@@ -125,6 +125,7 @@ class Snowflake
try try
offer = JSON.parse desc offer = JSON.parse desc
dbg 'Received:\n\n' + offer.sdp + '\n' dbg 'Received:\n\n' + offer.sdp + '\n'
console.log offer
sdp = new SessionDescription offer sdp = new SessionDescription offer
@sendAnswer pair if pair.receiveWebRTCOffer sdp @sendAnswer pair if pair.receiveWebRTCOffer sdp
catch e catch e
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment