Text file talks/2012/insidepresent.slide

     1  Inside the "present" tool
     2  
     3  Andrew Gerrand
     4  Google
     5  @enneff
     6  adg@golang.org
     7  https://go.dev
     8  
     9  
    10  * The Playground API
    11  
    12  The API used by the Playground (and the Tour) is a simple HTTP POST request
    13  that returns a JSON-encoded response.
    14  
    15  Request:
    16  
    17  	POST /compile HTTP/1.1
    18  	Host:play.golang.org
    19  	Content-Length:113
    20  	Content-Type:application/x-www-form-urlencoded; charset=UTF-8
    21  
    22  	body=package+main%0A%0Aimport+%22fmt%22%0A%0Afunc+main()+%7B%0A%09fmt.Println(%22Hello%2C+playground%22)%0A%7D%0A
    23  
    24  Response body:
    25  
    26  	{"compile_errors":"","output":"Hello, playground\n"}
    27  
    28  
    29  * Playground drawbacks
    30  
    31  The compile service has no concept of time. (Necessary to limit resource use.)
    32  
    33  The API reflects this; output is sent in one blob, not streamed.
    34  
    35  Even when running locally, the API is bad for demonstrating code that uses time.
    36  
    37  Rob needed to use time in his _Go_Concurrency_Patterns_ talk.
    38  
    39  
    40  * Enter WebSockets
    41  
    42  WebSockets are a bi-directional communication channel between a JavaScript program running in a web browser and a web server. They are part of HTML 5.
    43  
    44  The `websocket` package in Go's `go.net` sub-repository provides a WebSocket client and server.
    45  
    46  I thought I could use WebSockets to stream program output to a running
    47  presentation.
    48  
    49  And thus the `present` tool was born.
    50  
    51  
    52  * Hello, WebSocket
    53  
    54  .code insidepresent/websocket.js
    55  .play insidepresent/websocket.go
    56  
    57  
    58  * Messages
    59  
    60  The client (browser) and server (present) communicate with JSON-encoded messages.
    61  
    62  .code insidepresent/socket.go /Message is/,/^}/
    63  
    64  Go's `encoding/json` format can convert these `Message` values to and from JSON.
    65  
    66  Go:
    67  
    68  	Message{Id: "0", Kind: "run", Body: `package main; func main() { print("hello"); }`}
    69  
    70  JSON:
    71  
    72  	{"Id":"0","Kind":"run","Body":"package main; func main() { print(\"hello\"); }"}
    73  
    74  
    75  * On the wire
    76  
    77  .play insidepresent/hello.go
    78  
    79  .html insidepresent/wire.html
    80  
    81  
    82  * Implementation
    83  
    84  * socketHandler (1/3)
    85  
    86  First, register the handler with the `net/http` package:
    87  
    88  	http.Handle("/socket", websocket.Handler(socketHandler))
    89  
    90  Implementation:
    91  
    92  .code insidepresent/socket.go /func socketHandler/,/errc/
    93  
    94  * socketHandler (2/3)
    95  
    96  .code insidepresent/socket.go /Decode messages/,/END/
    97  
    98  * socketHandler (3/3)
    99  
   100  .code insidepresent/socket-simple.go /Start and kill/,/^}/
   101  
   102  
   103  * Process
   104  
   105  .code insidepresent/socket.go /Process represents/,/^}/
   106  
   107  * StartProcess
   108  
   109  .code insidepresent/socket.go /StartProcess builds/,/^}/
   110  
   111  * Process.start (1/2)
   112  
   113  .code insidepresent/socket.go /start builds/,/END/
   114  
   115  * Process.start (2/2)
   116  
   117  .code insidepresent/socket.go /build x\.go/,/^}/
   118  
   119  * Process.cmd
   120  
   121  .code insidepresent/socket.go /cmd builds/,/^}/
   122  .code insidepresent/socket.go /messageWriter is/,/END/
   123  
   124  * Process.wait and Process.end
   125  
   126  .code insidepresent/socket.go /wait waits/,/^}/
   127  .code insidepresent/socket.go /end sends/,/^}/
   128  
   129  * Process.Kill
   130  
   131  .code insidepresent/socket.go /Kill stops/,/^}/
   132  
   133  
   134  * One more thing
   135  
   136  * Limiting output (1/2)
   137  
   138  .code insidepresent/socket.go /switch m\.Kind/,/^			}/
   139  
   140  * Limiting output (2/2)
   141  
   142  .code insidepresent/socket.go /limiter returns/,/^}/
   143  
   144  
   145  

View as plain text