Пример #1
0
//process recreates the request that should be sent to the target host
//it stores the response in the store of replies.
func (c *Consumer) process(petition *Petition) {
	var (
		req   *http.Request
		resp  *http.Response
		reply *Reply
		start = bson.Now()
	)

	db := c.SessionSeed.DB(c.Cfg.Database)
	petColl := db.C(c.Cfg.Instance + c.Cfg.PetitionsColl)
	replyColl := db.C(c.Cfg.ResponsesColl)
	errColl := db.C(c.Cfg.ErrorsColl)

	mylog.Debugf("processing petition %+v", petition)
	req, err := petition.Request()
	if err != nil {
		mylog.Alert(petition.ID, err)
		return
	}
	mylog.Debugf("restored request %+v", req)
	mylog.Debug("before making request", petition.ID)
	resp, err = c.doRequest(req, petition.ID)
	if err == nil {
		mylog.Debug("after making request", petition.ID)
		defer func() {
			mylog.Debug("closing response body", petition.ID)
			resp.Body.Close()
		}()
	}

	reply = newReply(resp, petition, err)
	reply.Created = start
	mylog.Debugf("created reply %+v", reply)
	if err != nil || resp.StatusCode < 200 || resp.StatusCode >= 300 {
		e := errColl.Insert(reply)
		if e != nil {
			mylog.Alert("ERROR inserting erroneous reply", petition.ID, err)
			c.SessionSeed.Refresh()
		}
	}
	mylog.Debugf("before insert reply %+v", reply)
	err = replyColl.Insert(reply)
	mylog.Debugf("after insert reply %+v", reply)
	if err != nil {
		mylog.Alert("ERROR inserting reply", petition.ID, err)
		c.SessionSeed.Refresh()
	}
	mylog.Debugf("before remove petition %+v", petition)
	err = petColl.Remove(bson.M{"id": petition.ID})
	mylog.Debugf("after remove petition %+v", petition)
	if err != nil {
		mylog.Alert("ERROR removing petition", petition.ID, err)
		c.SessionSeed.Refresh()
	}

}
Пример #2
0
//ServeHTTP implements HTTP handler interface
func (l *Listener) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	mylog.Debugf("received request %+v", r)
	w.Header().Set("Content-Type", "application/json")
	if l.Stopped() {
		mylog.Debug("warning client server is stopping")
		http.Error(w, `{"error":"Server is shutting down"}`, 503)
		return
	}
	relayedRequest, e := newPetition(r)
	if e != nil {
		mylog.Debug("petition with error", e)
		http.Error(w, fmt.Sprintf(`{"error": %q }`, e), 400)
		return
	}
	db := l.SessionSeed.DB(l.Cfg.Database)
	petColl := db.C(l.Cfg.Instance + l.Cfg.PetitionsColl)
	mylog.Debugf("petition created %+v", relayedRequest)
	e = petColl.Insert(relayedRequest)
	if e != nil {
		http.Error(w, fmt.Sprintf(`{"error": %q, "ref":%q }`, e, relayedRequest.ID), 500)
		mylog.Alert("ERROR inserting", relayedRequest.ID, e)
		l.SessionSeed.Refresh()
		return
	}
	select {
	case l.SendTo <- relayedRequest:
		mylog.Debug("enqueued petition", relayedRequest)
		fmt.Fprintf(w, "{\"id\":%q}\n", relayedRequest.ID)
	default:
		mylog.Alert("server is busy")
		http.Error(w, `{"error":"Server is busy"}`, 500)
		mylog.Debugf("before remove petition", relayedRequest.ID)
		err := petColl.Remove(bson.M{"id": relayedRequest.ID})
		mylog.Debugf("after remove petition", relayedRequest.ID)
		if err != nil {
			mylog.Alert("ERROR removing petition", relayedRequest.ID, e)
			l.SessionSeed.Refresh()
			return
		}
		return
	}
}
Пример #3
0
func main() {
	var cfgFile = flag.String("config", "./gridas.yaml", "configuration file")
	flag.Parse()
	cfg, err := config.ReadConfig(*cfgFile)
	if err != nil {
		mylog.Alert(err)
		os.Exit(-1)
	}
	fmt.Printf("configuration %q %+v\n", *cfgFile, cfg)

	mylog.SetLevel(cfg.LogLevel)
	mylog.Alert("hello World!")
	reqChan := make(chan *gridas.Petition, cfg.QueueSize)
	session, err := mgo.Dial(cfg.Mongo)
	if err != nil {
		mylog.Alert(err)
		panic(err)
	}
	defer func() {
		session.Close()
		mylog.Debugf("mongo session closed %+v", session)
	}()

	mylog.Debugf("mongo session %+v", session)

	db := session.DB(cfg.Database)
	mylog.Debug("mongo database", db)
	listener := &gridas.Listener{SendTo: reqChan, Cfg: cfg, SessionSeed: session}
	mylog.Debugf("listener %+v", listener)
	consumer := &gridas.Consumer{GetFrom: reqChan, Cfg: cfg, SessionSeed: session}
	mylog.Debugf("consumer %+v", consumer)
	rplyr := &gridas.Replyer{Cfg: cfg, SessionSeed: session}
	mylog.Debugf("replyer %+v", rplyr)
	rcvr := &gridas.Recoverer{SendTo: reqChan, Cfg: cfg, SessionSeed: session}
	mylog.Debugf("recoverer %+v", rcvr)
	endConsumers := consumer.Start(cfg.Consumers)
	if err := rcvr.Recover(); err != nil {
		mylog.Alert(err)
		os.Exit(-1)
	}
	http.Handle("/", listener)
	http.Handle("/responses/", http.StripPrefix("/responses/", rplyr))
	go func() {
		mylog.Debug("starting HTTP server (listener)")
		err := http.ListenAndServe(":"+cfg.Port, nil)
		if err != nil {
			mylog.Alert(err)
			os.Exit(-1)
		}
	}()

	onEnd(func() {
		mylog.Info("shutting down gridas ...")
		listener.Stop()
		mylog.Debug("listener stopped")
		consumer.Stop()
		mylog.Debug("consumer stopped")
	})
	<-endConsumers
	mylog.Alert("bye World!")
}