Beispiel #1
0
func TestOpenRTB(t *testing.T) {
	m := make(map[string]interface{})

	if err := json.Unmarshal(sample, &m); err != nil {
		t.Fatal(err)
	}

	br, err := json.Marshal(m)
	if err != nil {
		t.Fatal(err)
	}

	log.Println(string(br))

	b := &Bidders{
		Pattern: "../../../../configs/bidders/*.json",
	}

	c := trace.Start(trace.SetHandler(context.Background(), nil), "test", "")

	b.Start()
	e := &Exchange{Bidders: b}

	w := httptest.NewRecorder()
	e.ServeHTTP(c, w, &http.Request{Body: ioutil.NopCloser(bytes.NewReader(br))})

	trace.Leave(c, "done")

	log.Println(w.Code, w.Body.String())
}
Beispiel #2
0
func (b *Bidders) Start() (err error) {
	b.state.Store(make(map[string]*Agent))

	//log.Println("START")

	update := func() (err error) {
		b.mu.Lock()
		defer b.mu.Unlock()

		log.Println("checking configurations...")

		ctx := trace.Start(trace.SetHandler(context.Background(), b.Tracer), b.Name+".Tick", "")
		last := b.state.Load().(map[string]*Agent)

		agents, err := Import(b.Pattern)
		if err != nil {
			log.Println(err)
			err = nil
		}

		if len(agents) == 0 {
			log.Println("no files found: ", b.Pattern)
			trace.Leave(ctx, "Errors.NoFiles")
			return
		}

		next := make(map[string]*Agent)
		now := time.Now().UTC()

		for _, agent := range agents {
			id := fmt.Sprintf("%d", agent.ID)
			//log.Println(id, agent.Account[0])
			next[id] = agent
			if a := last[id]; a == nil {
				agent.Begin()
			} else {
				agent.state = a.state
				agent.Update(ctx, now)
			}
		}

		b.state.Store(next)
		trace.Leave(ctx, "Done")
		return
	}

	if err = update(); err != nil {
		log.Println(err)
	}

	b.tick = rtb.PeriodicFunc(rtb.Every(time.Minute), func() {
		err := update()
		if err != nil {
			log.Println(err)
		}
	})

	return
}
Beispiel #3
0
// ServeHTTP creates the root context and pass it to the HTTP request handler.
// The default /ready route is also handled.
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if atomic.LoadInt64(&s.ready) == 0 {
		http.Error(w, "server is closed", http.StatusServiceUnavailable)
		return
	}

	// start trace
	key := r.Header.Get(trace.HeaderKey)
	ctx := trace.Start(trace.SetHandler(context.Background(), s.Tracer), s.name, key)

	// ready?
	if r.URL.Path == "/ready" && r.Method == "GET" {
		trace.Leave(ctx, "Ready")
		w.WriteHeader(http.StatusOK)
		return
	}

	if s.Handler != nil {
		s.Handler.ServeHTTP(ctx, w, r)
	}

	trace.Leave(ctx, "Served")
}
Beispiel #4
0
// Start installs the server and starts serving requests until the server is closed.
func (s *Server) Start() (err error) {
	s.Server.Handler = s

	// open socket
	s.listen, err = net.Listen("tcp", defaults.String(s.Server.Addr, ":http"))
	if err != nil {
		return
	}

	s.name = defaults.String(s.Name, s.listen.Addr().String())

	// provide a default read timeout if missing
	if 0 == s.Server.ReadTimeout {
		s.Server.ReadTimeout = time.Minute
	}

	// track new/closed HTTP connections
	s.conns = make(map[net.Conn]http.ConnState)

	cs := s.Server.ConnState
	s.Server.ConnState = func(conn net.Conn, state http.ConnState) {
		s.mu.Lock()
		defer s.mu.Unlock()

		switch state {
		case http.StateNew:
			atomic.AddInt64(&s.count, +1)
			s.wg.Add(1)
			s.conns[conn] = state
		case http.StateClosed, http.StateHijacked:
			atomic.AddInt64(&s.count, -1)
			s.wg.Done()
			delete(s.conns, conn)
		case http.StateActive, http.StateIdle:
			s.conns[conn] = state
		}

		if nil != cs {
			cs(conn, state)
		}
	}

	// update metrics
	s.tick = Tick(time.Second, func() {
		ctx := trace.Start(trace.SetHandler(context.Background(), s.Tracer), s.name+".Tick", "")
		trace.Set(ctx, "Connections", atomic.LoadInt64(&s.count))
		trace.Set(ctx, "State", atomic.LoadInt64(&s.ready))
		trace.Leave(ctx, "Ticked")
	})

	// serve requests
	go func() {
		s.Server.Serve(s.listen)
	}()

	// set ready
	if !atomic.CompareAndSwapInt64(&s.ready, 0, 1) {
		panic("server is already ready to serve requests")
	}

	return
}