veyron.io/playground: Stream playground output to client in realtime.

Output is streamed as JSONified Events, one per line, similar to
builder output. Output size limit is enforced.
Moved Event writing support into a shared playground lib to make it
accessible to compilerd.
Also changed Docker build to include all builder and lib files in
local file mode.

Change-Id: Iefb0ccfa3d8593d2887d530bcb1750dc728bf568
diff --git a/lib/limited_writer.go b/lib/limited_writer.go
new file mode 100644
index 0000000..a93464b
--- /dev/null
+++ b/lib/limited_writer.go
@@ -0,0 +1,64 @@
+// LimitedWriter is an io.Writer wrapper that limits the total number of bytes
+// written to the underlying writer.
+//
+// All attempted writes count against the limit, regardless of whether they
+// succeed.
+// Not thread-safe.
+
+package lib
+
+import (
+	"errors"
+	"io"
+	"net/http"
+	"sync"
+)
+
+var ErrWriteLimitExceeded = errors.New("LimitedWriter: write limit exceeded")
+
+// Initialize using NewLimitedWriter.
+type LimitedWriter struct {
+	io.Writer
+	maxLen           int
+	maxLenExceededCb func()
+	lenWritten       int
+}
+
+func NewLimitedWriter(writer io.Writer, maxLen int, maxLenExceededCb func()) *LimitedWriter {
+	return &LimitedWriter{
+		Writer:           writer,
+		maxLen:           maxLen,
+		maxLenExceededCb: maxLenExceededCb,
+	}
+}
+
+func (t *LimitedWriter) Write(p []byte) (n int, err error) {
+	if t.lenWritten+len(p) > t.maxLen {
+		t.lenWritten = t.maxLen
+		if t.maxLenExceededCb != nil {
+			t.maxLenExceededCb()
+		}
+		return 0, ErrWriteLimitExceeded
+	}
+	if len(p) == 0 {
+		return 0, nil
+	}
+	t.lenWritten += len(p)
+	return t.Writer.Write(p)
+}
+
+var _ http.Flusher = (*LimitedWriter)(nil)
+
+func (t *LimitedWriter) Flush() {
+	if f, ok := t.Writer.(http.Flusher); ok {
+		f.Flush()
+	}
+}
+
+// Wraps a function to prevent it from executing more than once.
+func DoOnce(f func()) func() {
+	var once sync.Once
+	return func() {
+		once.Do(f)
+	}
+}