示例#1
0
func New(
	listenNetwork, listenAddr string,
	containerGraceTime time.Duration,
	backend garden.Backend,
	logger lager.Logger,
) *GardenServer {
	s := &GardenServer{
		logger: logger.Session("garden-server"),

		listenNetwork: listenNetwork,
		listenAddr:    listenAddr,

		containerGraceTime: containerGraceTime,
		backend:            backend,

		stopping: make(chan bool),

		handling: new(sync.WaitGroup),
		conns:    make(map[net.Conn]net.Conn),

		streamer: streamer.New(time.Minute),

		destroys:  make(map[string]struct{}),
		destroysL: new(sync.Mutex),
	}

	handlers := map[string]http.Handler{
		routes.Ping:                   http.HandlerFunc(s.handlePing),
		routes.Capacity:               http.HandlerFunc(s.handleCapacity),
		routes.Create:                 http.HandlerFunc(s.handleCreate),
		routes.Destroy:                http.HandlerFunc(s.handleDestroy),
		routes.List:                   http.HandlerFunc(s.handleList),
		routes.Stop:                   http.HandlerFunc(s.handleStop),
		routes.StreamIn:               http.HandlerFunc(s.handleStreamIn),
		routes.StreamOut:              http.HandlerFunc(s.handleStreamOut),
		routes.CurrentBandwidthLimits: http.HandlerFunc(s.handleCurrentBandwidthLimits),
		routes.CurrentCPULimits:       http.HandlerFunc(s.handleCurrentCPULimits),
		routes.CurrentDiskLimits:      http.HandlerFunc(s.handleCurrentDiskLimits),
		routes.CurrentMemoryLimits:    http.HandlerFunc(s.handleCurrentMemoryLimits),
		routes.NetIn:                  http.HandlerFunc(s.handleNetIn),
		routes.NetOut:                 http.HandlerFunc(s.handleNetOut),
		routes.Info:                   http.HandlerFunc(s.handleInfo),
		routes.BulkInfo:               http.HandlerFunc(s.handleBulkInfo),
		routes.BulkMetrics:            http.HandlerFunc(s.handleBulkMetrics),
		routes.Run:                    http.HandlerFunc(s.handleRun),
		routes.Stdout:                 streamer.HandlerFunc(s.streamer.ServeStdout),
		routes.Stderr:                 streamer.HandlerFunc(s.streamer.ServeStderr),
		routes.Attach:                 http.HandlerFunc(s.handleAttach),
		routes.Metrics:                http.HandlerFunc(s.handleMetrics),
		routes.Properties:             http.HandlerFunc(s.handleProperties),
		routes.Property:               http.HandlerFunc(s.handleProperty),
		routes.SetProperty:            http.HandlerFunc(s.handleSetProperty),
		routes.RemoveProperty:         http.HandlerFunc(s.handleRemoveProperty),
		routes.SetGraceTime:           http.HandlerFunc(s.handleSetGraceTime),
	}

	mux, err := rata.NewRouter(routes.Routes, handlers)
	if err != nil {
		logger.Fatal("failed-to-initialize-rata", err)
	}

	conLogger := logger.Session("connection")

	s.server = &http.Server{
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			mux.ServeHTTP(w, r)
		}),

		ConnState: func(conn net.Conn, state http.ConnState) {
			switch state {
			case http.StateNew:
				conLogger.Debug("open", lager.Data{"local_addr": conn.LocalAddr(), "remote_addr": conn.RemoteAddr()})
				s.handling.Add(1)
			case http.StateActive:
				s.mu.Lock()
				delete(s.conns, conn)
				s.mu.Unlock()
			case http.StateIdle:
				select {
				case <-s.stopping:
					conn.Close()
				default:
					s.mu.Lock()
					s.conns[conn] = conn
					s.mu.Unlock()
				}
			case http.StateHijacked, http.StateClosed:
				s.mu.Lock()
				delete(s.conns, conn)
				s.mu.Unlock()
				conLogger.Debug("closed", lager.Data{"local_addr": conn.LocalAddr(), "remote_addr": conn.RemoteAddr()})
				s.handling.Done()
			}
		},
	}

	return s
}
示例#2
0
var _ = Describe("Streamer", func() {

	const testString = "x"

	var (
		graceTime time.Duration
		str       *streamer.Streamer

		stdoutChan        chan []byte
		stderrChan        chan []byte
		testByteSlice     []byte
		channelBufferSize int
	)

	JustBeforeEach(func() {
		str = streamer.New(graceTime)
		stdoutChan = make(chan []byte, channelBufferSize)
		stderrChan = make(chan []byte, channelBufferSize)
	})

	BeforeEach(func() {
		graceTime = 50 * time.Millisecond
		channelBufferSize = 1

		testByteSlice = []byte(testString)
	})

	It("should stream standard output until it is stopped", func() {
		sid := str.Stream(stdoutChan, stderrChan)
		w := &syncBuffer{
			Buffer: new(bytes.Buffer),