go.talks: move websocket backend code to its own package

This makes it easier to include it in other programs, like the Tour.

R=golang-dev, campoy
CC=golang-dev
https://golang.org/cl/7297043
diff --git a/present/socket.go b/pkg/socket/socket.go
similarity index 80%
rename from present/socket.go
rename to pkg/socket/socket.go
index 40dba7e..96ede2a 100644
--- a/present/socket.go
+++ b/pkg/socket/socket.go
@@ -2,15 +2,19 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !appengine
-
-package main
+// Package socket implements an WebSocket-based playground backend.
+// Clients connect to a websocket handler and send run/kill commands, and
+// the server sends the output and exit status of the running processes.
+// Multiple clients running multiple processes may be served concurrently.
+// The wire format is JSON and is described by the Message type.
+//
+// This will not run on App Engine as WebSockets are not supported there.
+package socket
 
 import (
 	"encoding/json"
 	"io/ioutil"
 	"log"
-	"net/http"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -20,14 +24,10 @@
 	"code.google.com/p/go.net/websocket"
 )
 
-const msgLimit = 1000 // max number of messages to send per session
+// Handler implements a WebSocket handler for a client connection.
+var Handler = websocket.Handler(socketHandler)
 
-// HandleSocket registers the websocket handler with http.DefaultServeMux under
-// the given path.
-func HandleSocket(path string) {
-	playScript("/static/socket.js")
-	http.Handle(path, websocket.Handler(socketHandler))
-}
+const msgLimit = 1000 // max number of messages to send per session
 
 // Message is the wire format for the websocket connection to the browser.
 // It is used for both sending output messages and receiving commands, as
@@ -40,7 +40,7 @@
 
 // socketHandler handles the websocket connection for a given present session.
 // It handles transcoding Messages to and from JSON format, and starting
-// and killing Processes.
+// and killing processes.
 func socketHandler(c *websocket.Conn) {
 	in, out := make(chan *Message), make(chan *Message)
 	errc := make(chan error, 1)
@@ -69,8 +69,8 @@
 		}
 	}()
 
-	// Start and kill Processes and handle errors.
-	proc := make(map[string]*Process)
+	// Start and kill processes and handle errors.
+	proc := make(map[string]*process)
 	for {
 		select {
 		case m := <-in:
@@ -78,7 +78,7 @@
 			case "run":
 				proc[m.Id].Kill()
 				lOut := limiter(in, out)
-				proc[m.Id] = StartProcess(m.Id, m.Body, lOut)
+				proc[m.Id] = startProcess(m.Id, m.Body, lOut)
 			case "kill":
 				proc[m.Id].Kill()
 			}
@@ -94,18 +94,18 @@
 	}
 }
 
-// Process represents a running process.
-type Process struct {
+// process represents a running process.
+type process struct {
 	id   string
 	out  chan<- *Message
 	done chan struct{} // closed when wait completes
 	run  *exec.Cmd
 }
 
-// StartProcess builds and runs the given program, sending its output
+// startProcess builds and runs the given program, sending its output
 // and end event as Messages on the provided channel.
-func StartProcess(id, body string, out chan<- *Message) *Process {
-	p := &Process{
+func startProcess(id, body string, out chan<- *Message) *process {
+	p := &process{
 		id:   id,
 		out:  out,
 		done: make(chan struct{}),
@@ -119,7 +119,7 @@
 }
 
 // Kill stops the process if it is running and waits for it to exit.
-func (p *Process) Kill() {
+func (p *process) Kill() {
 	if p == nil {
 		return
 	}
@@ -129,7 +129,7 @@
 
 // start builds and starts the given program, sending its output to p.out,
 // and stores the running *exec.Cmd in the run field.
-func (p *Process) start(body string) error {
+func (p *process) start(body string) error {
 	// We "go build" and then exec the binary so that the
 	// resultant *exec.Cmd is a handle to the user's program
 	// (rather than the go tool process).
@@ -167,14 +167,14 @@
 
 // wait waits for the running process to complete
 // and sends its error state to the client.
-func (p *Process) wait() {
+func (p *process) wait() {
 	p.end(p.run.Wait())
 	close(p.done) // unblock waiting Kill calls
 }
 
 // end sends an "end" message to the client, containing the process id and the
 // given error value.
-func (p *Process) end(err error) {
+func (p *process) end(err error) {
 	m := &Message{Id: p.id, Kind: "end"}
 	if err != nil {
 		m.Body = err.Error()
@@ -183,8 +183,8 @@
 }
 
 // cmd builds an *exec.Cmd that writes its standard output and error to the
-// Process' output channel.
-func (p *Process) cmd(dir string, args ...string) *exec.Cmd {
+// process' output channel.
+func (p *process) cmd(dir string, args ...string) *exec.Cmd {
 	cmd := exec.Command(args[0], args[1:]...)
 	cmd.Dir = dir
 	cmd.Stdout = &messageWriter{p.id, "stdout", p.out}
@@ -219,7 +219,7 @@
 					return
 				}
 			case n == msgLimit:
-				// Process produced too much output. Kill it.
+				// process produced too much output. Kill it.
 				kill <- &Message{Id: m.Id, Kind: "kill"}
 			}
 			n++
diff --git a/present/local.go b/present/local.go
new file mode 100644
index 0000000..e655352
--- /dev/null
+++ b/present/local.go
@@ -0,0 +1,20 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !appengine
+
+package main
+
+import (
+	"net/http"
+
+	"code.google.com/p/go.talks/pkg/socket"
+)
+
+// HandleSocket registers the websocket handler with http.DefaultServeMux under
+// the given path.
+func HandleSocket(path string) {
+	playScript("/static/socket.js")
+	http.Handle(path, socket.Handler)
+}