├── examples ├── gobug.sh ├── govet.sh ├── vet_repeated_json_tags.go ├── plugins │ ├── plugin.go │ └── main.go ├── alias.go ├── os_executable.go ├── maps.go ├── struct_conversion.go ├── mutex_test.go ├── shutdown.go ├── sort.go └── json_old.go ├── img ├── rocket.jpg └── party-gopher.png ├── extra └── popquiz.go ├── README.md └── presentation.slide /examples/gobug.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | go bug -------------------------------------------------------------------------------- /examples/govet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | go tool vet examples/vet_repeated_json_tags.go 4 | -------------------------------------------------------------------------------- /img/rocket.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecheney/go-1.8-release-party/HEAD/img/rocket.jpg -------------------------------------------------------------------------------- /img/party-gopher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecheney/go-1.8-release-party/HEAD/img/party-gopher.png -------------------------------------------------------------------------------- /examples/vet_repeated_json_tags.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type T struct { 4 | A string `json:"A"` 5 | B string `json:"A"` 6 | C string `json:"C"xml:"C"` 7 | } 8 | -------------------------------------------------------------------------------- /examples/plugins/plugin.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // // No C code needed. 4 | import "C" 5 | 6 | import "fmt" 7 | 8 | var V int 9 | 10 | func init() { 11 | fmt.Println("Plugin loading") 12 | } 13 | 14 | func F() { 15 | fmt.Printf("Hello, number %d\n", V) 16 | } 17 | -------------------------------------------------------------------------------- /examples/alias.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type A struct { a int } 4 | 5 | type B struct { a int } 6 | 7 | type C B 8 | 9 | type D = B 10 | 11 | func main() { 12 | var ( a A; b B; c C; d D ) 13 | a = b // nope 14 | b = c // also nope 15 | d = b // new in Go 1.9! 16 | } 17 | -------------------------------------------------------------------------------- /examples/os_executable.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | // START OMIT 10 | fmt.Printf("os.Args[0]: %q\n", os.Args[0]) 11 | exec, _ := os.Executable() 12 | fmt.Printf("os.Executable(): %q\n", exec) 13 | // END OMIT 14 | } 15 | -------------------------------------------------------------------------------- /examples/maps.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | m := map[int]int{4: 4, 8: 8, 15: 15, 16: 16, 23: 23, 42: 42} 5 | go func() { 6 | for { 7 | for _, v := range m { 8 | _ = v 9 | } 10 | } 11 | }() 12 | for { 13 | for k, _ := range m { 14 | m[k]++ 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/struct_conversion.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | example() 5 | } 6 | 7 | // START OMIT 8 | func example() { 9 | type T1 struct { 10 | X int `json:"foo"` 11 | } 12 | type T2 struct { 13 | X int `json:"bar"` 14 | } 15 | var v1 T1 16 | var v2 T2 17 | v1 = T1(v2) // now legal 18 | _ = v1 19 | } 20 | 21 | // END OMIT 22 | -------------------------------------------------------------------------------- /examples/plugins/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "plugin" 6 | ) 7 | 8 | func main() { 9 | // START OMIT 10 | fmt.Printf("main started...\n") 11 | p, err := plugin.Open("plugin.so") 12 | if err != nil { 13 | panic(err) 14 | } 15 | 16 | v, err := p.Lookup("V") 17 | if err != nil { 18 | panic(err) 19 | } 20 | 21 | f, err := p.Lookup("F") 22 | if err != nil { 23 | panic(err) 24 | } 25 | 26 | *v.(*int) = 7 27 | f.(func())() // prints "Hello, number 7" 28 | // END OMIT 29 | } 30 | -------------------------------------------------------------------------------- /extra/popquiz.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "sync" 4 | 5 | func Close(c chan int) { 6 | select { 7 | case <-c: 8 | default: 9 | close(c) 10 | } 11 | } 12 | 13 | func loop() { 14 | const N = 2000 15 | start := make(chan int) 16 | c := make(chan int) 17 | var done sync.WaitGroup 18 | done.Add(N) 19 | for i := 0; i < N; i++ { 20 | go func() { 21 | defer done.Done() 22 | <-start 23 | Close(c) 24 | }() 25 | } 26 | close(start) 27 | done.Wait() 28 | } 29 | 30 | func main() { 31 | for { 32 | loop() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/mutex_test.go: -------------------------------------------------------------------------------- 1 | package mutex 2 | 3 | import "testing" 4 | import "sync" 5 | 6 | type Map struct { 7 | sync.Mutex 8 | m map[string]int 9 | } 10 | 11 | func (m *Map) Put(key string, val int) { 12 | m.Lock() 13 | m.m[key] = val 14 | m.Unlock() 15 | } 16 | 17 | func BenchmarkMutex(b *testing.B) { 18 | const N = 16 19 | for n := 0; n < b.N; n++ { 20 | var done sync.WaitGroup 21 | done.Add(N) 22 | m := Map{m: make(map[string]int)} 23 | for i := 0; i < N; i++ { 24 | go func(i int) { 25 | defer done.Done() 26 | m.Put("foo", i) 27 | }(i) 28 | } 29 | done.Wait() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/shutdown.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | func main() { 11 | srv := &http.Server{Addr: ":8080", Handler: http.DefaultServeMux} 12 | 13 | go func() { 14 | fmt.Println("Press enter to shutdown server") 15 | fmt.Scanln() 16 | log.Println("Shutting down server...") 17 | if err := srv.Shutdown(context.Background()); err != nil { // HL 18 | log.Fatalf("could not shutdown: %v", err) 19 | } 20 | }() 21 | 22 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 23 | fmt.Fprintln(w, "Happy Go 1.8'th") 24 | }) 25 | if err := srv.ListenAndServe(); err != http.ErrServerClosed { // HL 26 | log.Fatalf("listen: %s\n", err) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Go 1.8 Release Party 2 | 3 | [View this presentation online](https://talks.godoc.org/github.com/davecheney/go-1.8-release-party/presentation.slide) 4 | 5 | This repository is a companion to the [Go 1.8 release party](https://github.com/golang/go/wiki/Go-1.8-Release-Party) on Feb 16, 2017. 6 | 7 | ## Contributing 8 | 9 | If you'd like to contribute to this presentation, please do so. 10 | Specifically detailed explanations, _with code!_, are keenly sought. 11 | If you have a code example or sample code, consider placing them in another repository and linking to it from this presentation. 12 | 13 | If you don't know where to start, [please consult the list of open issues](https://github.com/davecheney/go-1.8-release-party/issues) or grep the presentation for `TODO`. 14 | 15 | -------------------------------------------------------------------------------- /examples/sort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "sort" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | switch strings.ToLower(field) { 10 | case "updated": 11 | sort.Slice(subs, func(i, j int) bool { return subs[i].Updated.After(subs[j].Updated) }) 12 | case "trust": 13 | sort.Slice(subs, func(i, j int) bool { return subs[i].Trust > subs[j].Trust }) 14 | case "stddev": 15 | sort.Slice(subs, func(i, j int) bool { 16 | var s1, s2 stats.Sample 17 | for _, r := range subs[i].Ratings { 18 | s1.Xs = append(s1.Xs, float64(r.Value)) 19 | } 20 | for _, r := range subs[j].Ratings { 21 | s2.Xs = append(s2.Xs, float64(r.Value)) 22 | } 23 | return s1.StdDev() < s2.StdDev() 24 | }) 25 | case "rating": 26 | fallthrough 27 | default: 28 | sort.Slice(subs, func(i, j int) bool { return subs[i].Rating > subs[j].Rating }) 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/json_old.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "log" 7 | ) 8 | 9 | func main() { 10 | in := []byte(` 11 | { 12 | "full_name": "Gopher", 13 | "age": 7, 14 | "social_security": 1234 15 | }`) 16 | 17 | var p Person 18 | if err := json.Unmarshal(in, &p); err != nil { 19 | log.Fatal(err) 20 | } 21 | fmt.Printf("%+v\n", p) 22 | } 23 | 24 | type Person struct { 25 | Name string 26 | AgeYears int 27 | SSN int 28 | } 29 | 30 | func (p *Person) UnmarshalJSON(data []byte) error { 31 | var aux struct { 32 | Name string `json:"full_name"` 33 | AgeYears int `json:"age"` 34 | SSN int `json:"social_security"` 35 | } 36 | if err := json.Unmarshal(data, &aux); err != nil { 37 | return err 38 | } 39 | *p = Person{ 40 | Name: aux.Name, 41 | AgeYears: aux.AgeYears, 42 | SSN: aux.SSN, 43 | } 44 | *p = Person(aux) 45 | return nil 46 | } 47 | -------------------------------------------------------------------------------- /presentation.slide: -------------------------------------------------------------------------------- 1 | Go 1.8 Release Party 2 | Sydney Go Users' Group 3 | 16 Feb 2017 4 | 5 | Dave Cheney 6 | @davecheney 7 | 8 | * License and Materials 9 | 10 | This presentation is licensed under the [[https://creativecommons.org/licenses/by-sa/4.0/][Creative Commons Attribution-ShareAlike 4.0 International]] licence. 11 | 12 | The materials for this presentation are available on GitHub: 13 | 14 | .link https://github.com/davecheney/go-1.8-release-party 15 | 16 | You are encouraged to remix, transform, or build upon the material, providing you distribute your contributions under the same license. 17 | 18 | If you have suggestions or corrections to this presentation, please raise [[https://github.com/davecheney/go-1.8-release-party/issues][an issue on the GitHub project]]. 19 | 20 | * Go 1.8 21 | 22 | Go 1.8 is released! 23 | 24 | .image img/rocket.jpg _ 350 25 | 26 | .link https://t.co/cIEsMPeY0k Go 1.8 Announcement 27 | 28 | Go 1.8 is the 9th release in the Go 1 series. It follows from the previous version, Go 1.7, [[https://blog.golang.org/go1.7][released on the 16th of August, 2016]] 29 | 30 | .link http://golang.org/doc/go1.8 Go 1.8 Release Notes 31 | 32 | * What's changed? 33 | 34 | So, what's happened in the last six months? 35 | 36 | - Performance 37 | - Compiler changes 38 | - Tool changes 39 | - Runtime changes 40 | - Changes to the standard library 41 | 42 | * Performance 43 | 44 | * Performance 45 | 46 | As always, the changes are so general and varied that precise statements about performance are difficult to make. 47 | 48 | Most programs should run a bit faster, due to speedups in the garbage collector and optimizations in the standard library. 49 | 50 | The new back end, based on static single assignment form (SSA), generates more compact, more efficient code and provides a better platform for optimizations such as bounds check elimination. 51 | 52 | - The new back end reduces the CPU time required by our benchmark programs by 20-30% on 32-bit ARM systems. 53 | - For 64-bit x86 systems, which already used the SSA back end in Go 1.7, the gains are a more modest 0-10%. 54 | - Other architectures will likely see improvements closer to the 32-bit ARM numbers. 55 | 56 | .link https://dave.cheney.net/2016/11/19/go-1-8-toolchain-improvements Go 1.8 Toolchain Improvements 57 | 58 | * Garbage Collector 59 | 60 | Garbage collection pauses should be significantly shorter than they were in Go 1.7, usually under 100 microseconds and often as low as 10 microseconds. 61 | 62 | .link https://talks.golang.org/2017/state-of-go.slide#34 Garbage Collector Improvements Over Time (ht. @francesc) 63 | 64 | # More work remains for Go 1.9. 65 | 66 | # .link https://github.com/golang/proposal/blob/master/design/17503-eliminate-rescan.md Eliminating Stop-The-World Stack Re-scanning (Design doc) 67 | 68 | * Defer 69 | 70 | The overhead of deferred function calls has been reduced by nearly half. 71 | 72 | name old time/op new time/op delta 73 | Defer-4 75.1ns ± 1% 43.3ns ± 1% -42.31% (p=0.000 n=8+10) 74 | 75 | In reality, this speeds up defer by about 2.2X. The two benchmarks 76 | below compare a Lock/defer Unlock pair (DeferLock) with a Lock/Unlock 77 | pair (NoDeferLock). NoDeferLock establishes a baseline cost, so these 78 | two benchmarks together show that this change reduces the overhead of 79 | defer from 61.4ns to 27.9ns. 80 | 81 | name old time/op new time/op delta 82 | DeferLock-4 77.4ns ± 1% 43.9ns ± 1% -43.31% (p=0.000 n=10+10) 83 | NoDeferLock-4 16.0ns ± 0% 15.9ns ± 0% -0.39% (p=0.000 n=9+8) 84 | 85 | .link https://golang.org/cl/29656 Source: CL 29656 86 | .link https://dave.cheney.net/2016/11/19/go-1-8-toolchain-improvements#defer Defer and cgo improvements 87 | 88 | * Cgo 89 | 90 | The overhead of cgo calls is reduced by more than half: 91 | 92 | name old time/op new time/op delta 93 | CgoNoop-8 146ns ± 1% 56ns ± 6% -61.57% (p=0.000 n=25+30) 94 | 95 | This is the result of merging two defers on the standard cgo calling path. 96 | 97 | .link https://crawshaw.io/blog/go1.8-cgo Less cgo overhead in Go 1.8 98 | 99 | * Miscellaneous performance improvements 100 | 101 | Lots of small updates to the standard library. 102 | 103 | There have been optimizations to implementations in the `bytes`, `crypto/aes`, `crypto/cipher`, `crypto/elliptic`, `crypto/sha256`, `crypto/sha512`, `encoding/asn1`, `encoding/csv`, `encoding/hex`, `encoding/json`, `hash/crc32`, `image/color`, `image/draw`, `math`, `math/big`, `reflect`, `regexp`, `runtime`, `strconv`, `strings`, `syscall`, `text/template`, and `unicode/utf8` packages. 104 | 105 | .link http://golang.org/doc/go1.8#library Go 1.8 Standard Library Changes 106 | 107 | * Compiler changes 108 | 109 | * SSA backend 110 | 111 | - All backends updated to use the new SSA form. Old "plan9" style compiler backend deleted. 112 | - Big performance improvements for 32-bit ARM. 113 | - Easy to add new SSA backends (for values of easy compiler engineers work in). eg, adding MIPS backend was straight forward, SPARC and RISC-V are rumored to be next. 114 | 115 | * New parser 116 | 117 | Robert Griesemer and Matthew Dempsky replaced the parser. 118 | 119 | The new parser removes many of the package level variables which came along for the ride from the previous YACC based parser. 120 | 121 | Removing package level globals is a stepping stone to making the compiler more parallel. In fact this work has started in the development branch. 122 | 123 | This new parser is considerably faster, but in 1.8 is hamstrung by having to convert between the new style AST and the old version the rest of the compiler expects. 124 | 125 | Expect this AST conversion to be removed in Go 1.9. 126 | 127 | * Compiler speed 128 | 129 | About a 12-15% improvement compared to Go 1.7 130 | 131 | .image https://dave.cheney.net/wp-content/uploads/2016/11/Screenshot-2016-11-19-at-08.57.10.png 132 | 133 | * Struct conversion 134 | 135 | When explicitly converting a value from one struct type to another, as of Go 1.8 the tags are ignored. 136 | 137 | .play examples/struct_conversion.go /START OMIT/,/END OMIT/ 138 | 139 | * Ports 140 | 141 | The number of platforms Go supports, on balance, continues to grow. 142 | 143 | - Go now supports 32-bit MIPS on Linux for both big-endian (linux/mips) and little-endian machines (linux/mipsle) that implement the MIPS32r1 instruction set with FPU or kernel FPU emulation. Note that many common MIPS-based routers lack an FPU and have firmware that doesn't enable kernel FPU emulation; Go won't run on such machines. 144 | - On DragonFly BSD, Go now requires DragonFly 4.4.4 or later. 145 | - On OpenBSD, Go now requires OpenBSD 5.9 or later. 146 | - The Plan 9 port's networking support is now much more complete and matches the behavior of Unix and Windows with respect to deadlines and cancelation. 147 | - Go 1.8 now only supports OS X 10.8 or later. _This_is_likely_the_last_Go_release_to_support_10.8_. Compiling Go or running binaries on older OS X versions is untested. 148 | 149 | * Go 1.8 may be the last to support ARMv5 150 | 151 | Supporting ARMv5 has been a problem for several releases. 152 | 153 | Currently we have no ARMv5 builders so have no idea if Go 1.8 actually works on real ARMv5 hardware (we test on ARMv7). 154 | 155 | Several companies have complained about loosing ARMv5 support, and several have offered to run a builder -- but there are _still_ no real ARMv5 builders on the dashboard. 156 | 157 | If you or your company care about ARMv5, you have to shoulder some of the burden. Contact @bradfitz and set up a builder. 158 | 159 | .link https://github.com/golang/go/issues/17082 Proposal: runtime: drop support for linux/armv5E and linux/armv6 160 | .link https://github.com/golang/go/wiki/DashboardBuilders Dashboard Builders (wiki) 161 | 162 | _No_ARMv5_builders_means_ARMv5_support_will_be_dropped_in_Go_1.9_. 163 | 164 | * Tool changes 165 | 166 | * go tool yacc 167 | 168 | The yacc tool (previously available by running “go tool yacc”) has been removed. As of Go 1.7 it was no longer used by the Go compiler. 169 | 170 | It has moved to the “tools” repository and is now available at golang.org/x/tools/cmd/goyacc. 171 | 172 | * go tool asm 173 | 174 | `go`tool`asm` now supports a flotilla of Intel and PPC vector instructions. 175 | 176 | For 64-bit x86 systems, the following instructions have been added: `VBROADCASTSD`, `BROADCASTSS`, `MOVDDUP`, `MOVSHDUP`, `MOVSLDUP`, `VMOVDDUP`, `VMOVSHDUP`, and `VMOVSLDUP`. 177 | 178 | For 64-bit PPC systems, the common vector scalar instructions have been added: `LXS`, `LXSDX`, `LXSI`, `LXSIWAX`, `LXSIWZX`, `LXV`, `LXVD2X`, `LXVDSX`, `LXVW4X`, `MFVSR`, `MFVSRD`, `MFVSRWZ`, `MTVSR`, `MTVSRD`, `MTVSRWA`, `MTVSRWZ`, `STXS`, `STXSDX`, `STXSI`, `STXSIWX`, `STXV`, `STXVD2X`, `STXVW4X`, `XSCV`, `XSCVDPSP`, `XSCVDPSPN`, `XSCVDPSXDS`, `XSCVDPSXWS`, `XSCVDPUXDS`, `XSCVDPUXWS`, `XSCVSPDP`, `XSCVSPDPN`, `XSCVSXDDP`, `XSCVSXDSP`, `XSCVUXDDP`, `XSCVUXDSP`, `XSCVX`, `XSCVXP`, `XVCV`, `XVCVDPSP`, `XVCVDPSXDS`, `XVCVDPSXWS`, `XVCVDPUXDS`, `XVCVDPUXWS`, `XVCVSPDP`, `XVCVSPSXDS`, `XVCVSPSXWS`, `XVCVSPUXDS`, `XVCVSPUXWS`, `XVCVSXDDP`, `XVCVSXDSP`, `XVCVSXWDP`, `XVCVSXWSP`, `XVCVUXDDP`, `XVCVUXDSP`, `XVCVUXWDP`, `XVCVUXWSP`, `XVCVX`, `XVCVXP`, `XXLAND`, `XXLANDC`, `XXLANDQ`, `XXLEQV`, `XXLNAND`, `XXLNOR`, `XXLOR`, `XXLORC`, `XXLORQ`, `XXLXOR`, `XXMRG`, `XXMRGHW`, `XXMRGLW`, `XXPERM`, `XXPERMDI`, `XXSEL`, `XXSI`, `XXSLDWI`, `XXSPLT`, and `XXSPLTW`. 179 | 180 | * go tool trace 181 | 182 | The `trace` tool has a new `-pprof` flag for producing pprof-compatible blocking and latency profiles from an execution trace. 183 | 184 | Garbage collection events are now shown more clearly in the execution trace viewer. 185 | 186 | Garbage collection activity is shown on its own row and GC helper goroutines are annotated with their roles. 187 | 188 | .link https://www.youtube.com/watch?v=mmqDlbWk_XA Rhys Hiltner's execution tracer presentation (dotGo 2016) 189 | 190 | * go tool vet 191 | 192 | Vet is stricter in some ways and looser where it previously caused false positives. Vet now checks for: 193 | 194 | - copying an array of locks 195 | - duplicate JSON and XML struct field tags 196 | - non-space-separated struct tags 197 | - deferred calls to HTTP `Response.Body.Close` before checking errors 198 | - indexed arguments in `Printf`. 199 | 200 | .code examples/vet_repeated_json_tags.go 201 | 202 | .play examples/govet.sh /go tool/ 203 | 204 | * go fix 205 | 206 | `go`fix` now rewrites references to `golang.org/x/net/context` to the standard library provided `context` package. 207 | 208 | * go bug 209 | 210 | The new `go`bug` command starts a bug report on GitHub, prefilled with information about the current system. 211 | 212 | Example: 213 | 214 | .play examples/gobug.sh /go bug/ 215 | 216 | * Default $GOPATH 217 | 218 | Lastly, it is no longer necessary to set `$GOPATH` before using the `go` command. 219 | 220 | When `GOPATH` is not defined, the tool will use: 221 | 222 | - `$HOME/go` on Unix 223 | - `%USERPROFILE%\go` on Windows 224 | 225 | If you don't like these defaults, just set `$GOPATH` to your preferred location. 226 | 227 | * Runtime changes 228 | 229 | * Mutex contention profile 230 | 231 | Peter Wienberger has added a new pprof profile, mutex contention. 232 | 233 | .code examples/mutex_test.go /testing.B/,/^}/ 234 | 235 | 236 | _note_: Due to an oversight this only works with `sync.Mutex`, not `sync.RWMutex`, this oversight will be addressed early in Go 1.9. 237 | 238 | .link https://github.com/golang/go/issues/18496 runtime: contended mutex profiling doesn't work for sync.RWMutex 239 | 240 | * Mutex contention profile 241 | 242 | % go test examples/mutex_test.go -bench=. -mutexprofile=mutex.out 243 | % go tool pprof mutex.test mutex.out 244 | (pprof) list 245 | Total: 290.81ms 246 | ROUTINE ======================== command-line-arguments.(*Map).Put in /Users/dfc/devel/go-1.8-release-party/examples/mutex_test.go 247 | 0 290.81ms (flat, cum) 100% of Total 248 | . . 9:} 249 | . . 10: 250 | . . 11:func (m *Map) Put(key string, val int) { 251 | . . 12: m.Lock() 252 | . . 13: m.m[key] = val 253 | . 290.81ms 14: m.Unlock() 254 | . . 15:} 255 | . . 16: 256 | . . 17:func BenchmarkMutex(b *testing.B) { 257 | . . 18: const N = 16 258 | . . 19: for n := 0; n < b.N; n++ { 259 | 260 | * Homework 261 | 262 | Mutex profile is not supported in, [[pkg/profile][https://github.com/pkg/profile]]. yet ... 263 | 264 | Who wants to be the first to send me a PR? 265 | 266 | * Plugins 267 | 268 | Go now supports a “plugin” build mode for generating plugins written in Go, and a new plugin package for loading such plugins at run time. 269 | 270 | Plugin support is currently only available on Linux. 271 | 272 | * Plugin Example 273 | 274 | .code examples/plugins/plugin.go 275 | 276 | Then to build plugin.so 277 | 278 | $ go build -buildmode=plugin plugin.go 279 | 280 | * Plugin Example - Using Plugin 281 | .code examples/plugins/main.go /START OMIT/,/END OMIT/ 282 | 283 | $ go run main.go 284 | main started... 285 | Plugin loading 286 | Hello, number 7 287 | 288 | * Plugins demo 289 | 290 | Demo video: [[https://twitter.com/francesc/status/827851085943566336][twitter.com/francesc]] 291 | 292 | Source code: [[https://github.com/campoy/golang-plugins][github.com/campoy/golang-plugins]] 293 | 294 | * os.Executable 295 | 296 | `os.Executable` returns an absolute path to the currently running program. 297 | 298 | .play examples/os_executable.go /START OMIT/,/END OMIT/ 299 | 300 | Executable returns the path name for the executable that started the current process. There is no guarantee that the path is still pointing to the correct executable. 301 | 302 | If a symlink was used to start the process, depending on the operating system, the result might be the symlink or the path it pointed to. If a stable result is needed, path/filepath.EvalSymlinks might help. 303 | 304 | .link http://golang.org/pkg/os/#Executable os.Executable (godoc.org) 305 | 306 | * Detection of concurrent map accesses 307 | 308 | In Go 1.6, the runtime added lightweight, [[http://talks.godoc.org/github.com/davecheney/gosyd/go1.6.slide#18][best-effort detection of concurrent misuse of maps]]. Go 1.8 improves that detector with support for detecting programs that concurrently write to and iterate over a map. 309 | 310 | .play examples/maps.go /func main/,/^}/ 311 | 312 | If the runtime detects this condition, it prints a diagnosis and crashes the program. 313 | 314 | * Changes to the standard library 315 | 316 | * sort.Slice 317 | 318 | The `sort` package has a new convenice method `sort.Slice` 319 | 320 | .code examples/sort.go /switch.+{/,/^\t}/ 321 | 322 | * HTTP shutdown 323 | 324 | A long requested feature, graceful shutdown of a `http.Server` was added in Go 1.8. 325 | 326 | Call `Shutdown` when a signal is received: 327 | 328 | .code examples/shutdown.go /main\(\) {/,/^} 329 | 330 | * HTTP/2 331 | 332 | `http.Response` now satisfies the `http.Pusher` interface. 333 | 334 | type Pusher interface { 335 | Push(target string, opts *PushOptions) error 336 | } 337 | 338 | * More context support 339 | 340 | Continuing Go 1.7's adoption of `context.Context` into the standard library, Go 1.8 adds more context support to existing packages: 341 | 342 | - The new `Server.Shutdown` takes a context argument. 343 | - There have been significant additions to the `database/sql` package with context support. 344 | - All nine of the new `Lookup` methods on the new `net.Resolver` now take a context. 345 | 346 | * Minor changes 347 | 348 | .link http://golang.org/doc/go1.8#minor_library_changes Minor library changes 349 | 350 | * What's coming up in Go 1.9 351 | 352 | * What's coming up in Go 1.9 353 | 354 | Before we close, let's quickly touch on some of the things coming up in Go 1.9 355 | 356 | _note_: All of these are speculation, nothing is set in stone until code hits the repo. 357 | 358 | * Aliases 359 | 360 | After being rolled back before the Go 1.8 freeze, aliases are being re-proposed for Go 1.9 in a more limited fashion. 361 | 362 | .link https://golang.org/design/18130-type-alias 363 | 364 | .play -edit examples/alias.go 365 | 366 | * Faster / cheaper runtime.MemStats 367 | 368 | The cost of calling `runtime.MemStats` is propotional to the size of the heap; Austin recently timed it at ~1.7ms per Gb. 369 | 370 | There is a CL ready to land that reduces it to 20 us per proc (thread servicing a goroutine) which is a much smaller upper bound. 371 | 372 | .link https://golang.org/issue/13613 373 | 374 | * Improvements to the inliner 375 | 376 | Inlining has historically been limited to leaf functions because of the concern of agressive inlining on the call graph. 377 | 378 | In support of this Robert Griesemer and Matthew Dempsky have been improving the line number tracking in Go 1.9 to make it flexible enough to lift the restriction on non-leaf functions. 379 | 380 | An unnamed intern has been hired to work on the inliner for 1.9. 381 | 382 | Josh Bleecher-Snyder has also suggest that the cost model for inlining should be revised to make sure inlining is paying for itself. 383 | 384 | .link https://github.com/golang/go/issues/17566 Issue 17566 385 | 386 | * A user level poller 387 | 388 | Go has used epoll/kqueue/poll/select for _network_sockets_ for years. 389 | 390 | Reads/Writes to other file descriptors have traditionally consumed an OS thread during operation 391 | 392 | Recently Ian Lance Taylor landed a refactor that broken our the `runtime` polling subsystem and extended to work for the rest of the `os` package. 393 | 394 | .link https://go-review.googlesource.com/#/c/36799/ net: refactor poller into new internal/poll package 395 | .link https://go-review.googlesource.com/#/c/36800/ os: use poller for file I/O 396 | 397 | There is no sign of a programmer accessible poller, yet. 398 | 399 | * Official dependency management tool 400 | 401 | Finally! 402 | 403 | Peter Bourgon, Edward Muller, Sam Boyer, Jess Frazelle, and Steve Francia have been working on an _official_ dependency management tool, `dep`. 404 | 405 | If you're used to Glide or govendor, you won't be too surprised. 406 | 407 | .link https://groups.google.com/forum/#!topic/go-package-management/et1qFUjrkP4 Mailing List Announcement 408 | 409 | It's described as _pre_alpha_ at the moment, but you should check it out, and let them know what you think. 410 | 411 | .link https://github.com/golang/dep 412 | 413 | * Conclusion 414 | 415 | .image img/party-gopher.png 416 | 417 | Upgrade to Go 1.8, now! 418 | 419 | It's literally the best version of Go, _ever_. 420 | 421 | --------------------------------------------------------------------------------