Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send RPC from skinny server #92

Merged
merged 15 commits into from
Oct 20, 2018
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions build_container/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ echo "Running build"
# The current working directory is the root of the repo.
# Write your output to the `build_out` directory

echo "Building skinny server"
go build -o build_out/skinny skinny/*.go

echo "Building example go microservice"
SRC_DIR=services/example_go_python_microservice
protoc -I=$SRC_DIR \
Expand All @@ -41,6 +38,9 @@ cp services/example_go_python_microservice/python/*.py $PYTHON_OUT_DIR
echo "Building example binary"
g++ services/example_microservice/main.cc -o build_out/example_ms

echo "Building skinny server"
go build -o build_out/skinny skinny/*.go

echo "Installing node.js dependencies"
cd chump && npm install && cd ..

Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ services:
dockerfile: Dockerfile
volumes:
- .:/repo
environment:
- GO_SERVER_HOST=example_go_microservice
example_microservice:
build:
context: ./services/example_microservice
Expand Down
77 changes: 69 additions & 8 deletions skinny/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import (
"time"

"github.com/gorilla/mux"

"google.golang.org/grpc"
pb "greetingCard"
)

const (
Expand All @@ -30,6 +33,12 @@ type serverWrapper struct {
// shutdownWait specifies how long the server should wait when shutting
// down for existing connections to finish before forcing a shutdown.
shutdownWait time.Duration
// greetingCards channel is the underlying connection to the GreetingCards
// service. This reference must be retained so it can by closed later.
greetingCardsChannel *grpc.ClientConn
iandioch marked this conversation as resolved.
Show resolved Hide resolved
// greetingCards is the RPC client for talking to the GreetingCards
// service.
greetingCards pb.GreetingCardsClient
}

// handleNotImplemented returns a http.HandlerFunc with a 501 Not Implemented
Expand Down Expand Up @@ -66,6 +75,32 @@ func (s *serverWrapper) handleFollow() http.HandlerFunc {
}
}

// handleGreet sends an RPC to example_go_microservice with a card for the
// given name.
// TODO(#91): Remove example code when there are several real services being
// contacted from this server.
func (s *serverWrapper) handleGreet() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
name := mux.Vars(r)["username"]
msg := fmt.Sprintf("hello %#v", name)
from := fmt.Sprintf("skinny-server-%v", name)
gc := &pb.GreetingCard{
Sender: from,
Letter: msg,
MoneyEnclosed: 123,
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()

ack, err := s.greetingCards.GetGreetingCard(ctx, gc)
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Received ack card: %#v\n", ack.Letter)
fmt.Fprintf(w, "Received: %#v", ack.Letter)
}
}

// setupRoutes specifies the routing of all endpoints on the server.
// Centralised routing config allows easier debugging of a specific endpoint,
// as the code handling it can be looked up here.
Expand All @@ -86,6 +121,7 @@ func (s *serverWrapper) setupRoutes() {
// User-facing routes
r.HandleFunc("/", s.handleIndex())
r.HandleFunc("/@{username}/follow", s.handleFollow())
r.HandleFunc("/@{username}/greet", s.handleGreet())

// c2s routes
r.HandleFunc("/api/", s.handleNotImplemented())
Expand All @@ -94,6 +130,30 @@ func (s *serverWrapper) setupRoutes() {
r.HandleFunc("/ap/", s.handleNotImplemented())
}

func (s *serverWrapper) shutdown() {
log.Printf("Stopping skinny server.\n")
ctx, cancel := context.WithTimeout(context.Background(), s.shutdownWait)
defer cancel()
// Waits for active connections to terminate, or until it hits the timeout.
s.server.Shutdown(ctx)

s.greetingCardsChannel.Close()
}

func createGreetingCardsClient() (*grpc.ClientConn, pb.GreetingCardsClient) {
host := os.Getenv("GO_SERVER_HOST")
if host == "" {
log.Fatal("GO_SERVER_HOST env var not set for skinny server.")
}
addr := host + ":8000"

conn, err := grpc.Dial(addr, grpc.WithInsecure())
if err != nil {
log.Fatalf("Skinny server did not connect: %v", err)
}
return conn, pb.NewGreetingCardsClient(conn)
}

// buildServerWrapper sets up all necessary individual parts of the server
// wrapper, and returns one that is ready to run.
func buildServerWrapper() *serverWrapper {
Expand All @@ -106,7 +166,14 @@ func buildServerWrapper() *serverWrapper {
IdleTimeout: time.Second * 60,
Handler: r,
}
s := &serverWrapper{r, srv, 20 * time.Second}
greetingCardsChannel, greetingCardsClient := createGreetingCardsClient()
s := &serverWrapper{
router: r,
server: srv,
shutdownWait: 20 * time.Second,
greetingCardsChannel: greetingCardsChannel,
greetingCards: greetingCardsClient,
}
s.setupRoutes()
return s
}
Expand Down Expand Up @@ -135,12 +202,6 @@ func main() {

// Block until we receive signal.
<-c
ctx, cancel := context.WithTimeout(context.Background(), s.shutdownWait)
defer cancel()

// Waits for active connections to terminate, or until it hits the timeout.
s.server.Shutdown(ctx)

log.Printf("Stopping skinny server.\n")
s.shutdown()
os.Exit(0)
}
13 changes: 12 additions & 1 deletion skinny/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@ import (
"net/http"
"net/http/httptest"
"testing"
"time"

"github.com/gorilla/mux"
)

func newTestServerWrapper() *serverWrapper {
// TODO(iandioch): Fake/mock instead of using real dependencies
return buildServerWrapper()
r := mux.NewRouter()
srv := &http.Server{}
s := &serverWrapper {
router: r,
server: srv,
shutdownWait: 20*time.Second,
greetingCardsChannel: nil,
greetingCards: nil,
}
s.setupRoutes()
return s
}

func TestHandleNotImplemented(t *testing.T) {
Expand Down