func (s *WardenServer) handleStream(conn net.Conn, request *protocol.StreamRequest) (proto.Message, error) { handle := request.GetHandle() jobID := request.GetJobId() container, err := s.backend.Lookup(handle) if err != nil { return nil, err } s.bomberman.Pause(container.Handle()) defer s.bomberman.Unpause(container.Handle()) stream, err := container.Stream(jobID) if err != nil { return nil, err } var response proto.Message for chunk := range stream { if chunk.ExitStatus != nil { response = &protocol.StreamResponse{ ExitStatus: proto.Uint32(*chunk.ExitStatus), } break } protocol.Messages(&protocol.StreamResponse{ Name: proto.String(chunk.Name), Data: proto.String(string(chunk.Data)), }).WriteTo(conn) } return response, nil }
"code.google.com/p/gogoprotobuf/proto" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/pivotal-cf-experimental/garden/message_reader" protocol "github.com/pivotal-cf-experimental/garden/protocol" ) var _ = Describe("Reading request messages over the wire", func() { Context("when a request is received", func() { It("returns the request and no error", func() { payload := bufio.NewReader( protocol.Messages(&protocol.EchoRequest{ Message: proto.String("some-message"), }), ) request, err := message_reader.ReadRequest(payload) Expect(err).ToNot(HaveOccurred()) Expect(request).To(Equal( &protocol.EchoRequest{ Message: proto.String("some-message"), }, )) }) }) Context("when the connection is broken", func() { It("returns an error", func() {
. "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/pivotal-cf-experimental/garden/message_reader" protocol "github.com/pivotal-cf-experimental/garden/protocol" ) var _ = Describe("Reading response messages over the wire", func() { Context("when a message of the expected type is received", func() { It("populates the response object and returns no error", func() { var echoResponse protocol.EchoResponse err := message_reader.ReadMessage( bufio.NewReader(protocol.Messages(&protocol.EchoRequest{ Message: proto.String("some message"), })), &echoResponse, ) Expect(err).ToNot(HaveOccurred()) Expect(echoResponse.GetMessage()).To(Equal("some message")) }) }) Context("when the connection is broken", func() { It("returns an error", func() { var dummyResponse protocol.PingResponse payload := protocol.Messages(&protocol.PingRequest{})
func (s *WardenServer) serveConnection(conn net.Conn) { read := bufio.NewReader(conn) for { var response proto.Message var err error if <-s.stopping { conn.Close() break } request, err := message_reader.ReadRequest(read) if err == io.EOF { break } if err != nil { log.Println("error reading request:", err) continue } if <-s.stopping { conn.Close() break } s.openRequests.Incr() switch request.(type) { case *protocol.PingRequest: response, err = s.handlePing(request.(*protocol.PingRequest)) case *protocol.EchoRequest: response, err = s.handleEcho(request.(*protocol.EchoRequest)) case *protocol.CreateRequest: response, err = s.handleCreate(request.(*protocol.CreateRequest)) case *protocol.DestroyRequest: response, err = s.handleDestroy(request.(*protocol.DestroyRequest)) case *protocol.ListRequest: response, err = s.handleList(request.(*protocol.ListRequest)) case *protocol.StopRequest: response, err = s.handleStop(request.(*protocol.StopRequest)) case *protocol.CopyInRequest: response, err = s.handleCopyIn(request.(*protocol.CopyInRequest)) case *protocol.CopyOutRequest: response, err = s.handleCopyOut(request.(*protocol.CopyOutRequest)) case *protocol.SpawnRequest: response, err = s.handleSpawn(request.(*protocol.SpawnRequest)) case *protocol.LinkRequest: s.openRequests.Decr() response, err = s.handleLink(request.(*protocol.LinkRequest)) s.openRequests.Incr() case *protocol.StreamRequest: s.openRequests.Decr() response, err = s.handleStream(conn, request.(*protocol.StreamRequest)) s.openRequests.Incr() case *protocol.RunRequest: s.openRequests.Decr() response, err = s.handleRun(request.(*protocol.RunRequest)) s.openRequests.Incr() case *protocol.LimitBandwidthRequest: response, err = s.handleLimitBandwidth(request.(*protocol.LimitBandwidthRequest)) case *protocol.LimitMemoryRequest: response, err = s.handleLimitMemory(request.(*protocol.LimitMemoryRequest)) case *protocol.LimitDiskRequest: response, err = s.handleLimitDisk(request.(*protocol.LimitDiskRequest)) case *protocol.LimitCpuRequest: response, err = s.handleLimitCpu(request.(*protocol.LimitCpuRequest)) case *protocol.NetInRequest: response, err = s.handleNetIn(request.(*protocol.NetInRequest)) case *protocol.NetOutRequest: response, err = s.handleNetOut(request.(*protocol.NetOutRequest)) case *protocol.InfoRequest: response, err = s.handleInfo(request.(*protocol.InfoRequest)) default: err = UnhandledRequestError{request} } if err != nil { response = &protocol.ErrorResponse{ Message: proto.String(err.Error()), } } protocol.Messages(response).WriteTo(conn) s.openRequests.Decr() } }
JustBeforeEach(func() { wardenServer = server.New("unix", socketPath, 0, serverBackend) err := wardenServer.Start() Expect(err).ToNot(HaveOccurred()) Eventually(ErrorDialing("unix", socketPath)).ShouldNot(HaveOccurred()) serverConnection, err = net.Dial("unix", socketPath) Expect(err).ToNot(HaveOccurred()) responses = bufio.NewReader(serverConnection) }) writeMessages := func(message proto.Message) { num, err := protocol.Messages(message).WriteTo(serverConnection) Expect(err).ToNot(HaveOccurred()) Expect(num).ToNot(Equal(0)) } readResponse := func(response proto.Message) { err := message_reader.ReadMessage(responses, response) Expect(err).ToNot(HaveOccurred()) } It("stops accepting new connections", func() { go wardenServer.Stop() Eventually(ErrorDialing("unix", socketPath)).Should(HaveOccurred()) }) It("stops handling requests on existing connections", func() {