-
-
Save Double1996/65ed65041c2b9d5bf3d9924f4160d065 to your computer and use it in GitHub Desktop.
Simple HTTP Server in Go using mongoDB and channels
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"gopkg.in/mgo.v2" | |
"gopkg.in/mgo.v2/bson" | |
"io" | |
"math/rand" | |
"net/http" | |
"sync" | |
"time" | |
) | |
// handler functions | |
// simple handler that just responds with a fixed string | |
func requestHandler1(w http.ResponseWriter, r *http.Request) { | |
io.WriteString(w, "Hello world!") | |
} | |
// Handler which makes three mongo queries at the same time and responds with the | |
// one that returns the quickest | |
func requestHandler2(w http.ResponseWriter, r *http.Request, mongoSession *mgo.Session) { | |
c1 := make(chan string) | |
c2 := make(chan string) | |
c3 := make(chan string) | |
go query("AAPL", mongoSession, c1) | |
go query("GOOG", mongoSession, c2) | |
go query("MSFT", mongoSession, c3) | |
select { | |
case data := <-c1: | |
io.WriteString(w, data) | |
case data := <-c2: | |
io.WriteString(w, data) | |
case data := <-c3: | |
io.WriteString(w, data) | |
} | |
} | |
// runs a query against mongodb | |
func query(ticker string, mongoSession *mgo.Session, c chan string) { | |
sessionCopy := mongoSession.Copy() | |
defer sessionCopy.Close() | |
collection := sessionCopy.DB("akka").C("stocks") | |
var result bson.M | |
collection.Find(bson.M{"Ticker": ticker}).One(&result) | |
asString, _ := json.MarshalIndent(result, "", " ") | |
amt := time.Duration(rand.Intn(120)) | |
time.Sleep(time.Millisecond * amt) | |
c <- string(asString) | |
} | |
// starts the application | |
func main() { | |
server := http.Server{ | |
Addr: ":8000", | |
Handler: NewHandler(), | |
} | |
// start listening | |
fmt.Println("Started server 2") | |
server.ListenAndServe() | |
} | |
// Constructor for the server handlers | |
func NewHandler() *myHandler { | |
h := new(myHandler) | |
h.defineMappings() | |
return h | |
} | |
// Definition of this struct | |
type myHandler struct { | |
// holds the mapping | |
mux map[string]func(http.ResponseWriter, *http.Request) | |
} | |
// functions defined on struct | |
func (my *myHandler) defineMappings() { | |
session, err := mgo.Dial("localhost") | |
if err != nil { | |
panic(err) | |
} | |
// make the mux | |
my.mux = make(map[string]func(http.ResponseWriter, *http.Request)) | |
// matching of request path | |
my.mux["/hello"] = requestHandler1 | |
my.mux["/get"] = my.wrap(requestHandler2, session) | |
} | |
// returns a function so that we can use the normal mux functionality and pass in a shared mongo session | |
func (my *myHandler) wrap(target func(http.ResponseWriter, *http.Request, *mgo.Session), mongoSession *mgo.Session) func(http.ResponseWriter, *http.Request) { | |
return func(resp http.ResponseWriter, req *http.Request) { | |
target(resp, req, mongoSession) | |
} | |
} | |
// implements serveHTTP so this struct can act as a http server | |
func (my *myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |
if h, ok := my.mux[r.URL.String()]; ok { | |
// handle paths that are found | |
h(w, r) | |
return | |
} else { | |
// handle unhandled paths | |
io.WriteString(w, "My server: "+r.URL.String()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment