Skip to content
Snippets Groups Projects
Commit fe066b4d authored by Peter J. Keleher's avatar Peter J. Keleher
Browse files

auto

parent 975d7244
No related branches found
No related tags found
No related merge requests found
# Immutability Changes Everything
![im](immut1.png)
Trends:
- increasing storage
- increasing distribution
- increasing ambiguity
- LSF, COW, LSM
## Append-only computing
- logs are **the truth**
- single-master changes are applied sequentially via single-master or concensus
## Data on the:
- inside
- mutable relational data
- outside: think artifacts, reports, summaries
- immutable
- identity
- (possibly) versioned
## Immutable Is Not Always Immutable
- optimizing for read access: indexes, de-normalization
- farming out portions of work, with re-try.
- bit meanings change
- normalization is there to eliminate update anomalies
- table decomposition takes a single large table and makes multiple small tables
- updating mult tables causes *update anomolies*
- anomolies addressed by *normalization*, which makes the tables a bit less efficient
- if immutable, no anomolies, so....
- versioned data changes, but versions do not
## Bottom line
1. Immutability enables unambiguous identity
1. Immutability enables massive replication/caching/parallelism
1. Immutability eliminates locking
1. Immutability enables re-computation
- from immutable
- of immutable
notes/immut1.png

386 KiB

# Class Requirements
- attend class
- contribute to the discussion
- present a paper
- write [blog](http://818.kelehers.me/blog.rb) entries
- build massive and awesome projects in Go
# Grading
- Projects:
- There will six projects, each with a two-to-three week time window.
- 10% for the first, 11% each for the rest
- All projects must get at least half credit to pass the course.
- Paper presentation: 5%
- Blog entries: 10%
- You are required to upload a blog entry before each class except the first. More details in class.
- Midterm/Final: 20%
# Projects
- P1: Go, and UbiStore
- P2: Security, Verification
- P3: Log Synchronization, gRPC
- merkel trees
- background anti-entropy
- P4: RAFT
- consensus!
- P5: RAFT 2
- more consensus
- joint consensus
- integration into anti-entropy
- P6: Abstractions on a Shared Log
- transactions
- high-level abstractions
# Things of Note
- [Piazza](https://piazza.com/umd/fall2023/cmsc818e)
- Do not post code, other than small snippets to illustrate a problem, *no
code answering question*.
- I do encourage posting questions about Go usage, FUSE weirdness, etc.
- [Web page](https://sedna.cs.umd.edu/818/)
- one-stop shop for all info goodness
# What are we doing?
- learning systems by building them
- building things we can actually use.
# Go
dudes at Bell labs:
- Ken Thompson unix, turing award winner
- Rob Pike
now at google.
New *systems* programming language.
Pain points:
- slow builds
- dependency explosion -
/sys/stat.h included 37 times (1984 test, probably much worse now)
google build of a binary that totaled 4.2 MB of source turned into 8GB seen by compiler
- concurrency, multi-core support built-in
- memory allocation
## Brief tour
(from perspective of C)
- package/include system
- interfaces
- duck typing
- slices vs arrays
- maps
- typesafe
- goroutines
- channels
- garbage collection
## Preliminaries:
- everything in GOPATH
- **go** build/install/get/run/...
- emacs go-mode comes w/ distribution
### Gotchas:
- all passed by value: pointers, but also stucts, arrays (use slices)
- no pointer arith
- ++ exists, but not expression
- no implicit conversions, but int(4.3)
- no type aliases
- `type dint int` now distinct types
- can add methods to user-defined types
- no ternary
**And**:
- no constructors/destructors
- no default args
- no exceptions (but panic/recover)
- no arrays of mixed type
## Packages:
- everything is part of a package
- variables, methods exported by starting with capitalized name
package "dss"
func invisible(int one) {
...
}
func Visible(int one) {
...
}
called:
import "blah/pete/dss"
dss.Visible(...)
## Modules
- packages are in modules
- modules encode dependencies, and can be used to fetch them, e.g.:
```
go mod init
g mod tidy
```
## Memory allocation
- allocation:
- new() zeros,
- make() initializes, for channels, maps, slices...
## Arrays
- fixed size
- passed by value to funcs
- arrays are defined using a fixed size, e.g. `sa :
[3]Int`, or
```
var sa [3]int = [3]int{1, 2, 3}
sb := [3]int{1, 2, 3}
sb2 := [3]int{0:1, 2:3}
sc := [...]int{1, 2, 3}
fmt.Println(sa)
fmt.Println(sb)
fmt.Println(sb2)
fmt.Println(sc)
```
## Slices!
sl := arr[0:2]
fmt.Println(sl)
sl2 := []int{4, 5, 6}
fmt.Println(sl2)
sl3 := append(sl2, 7, 8)
fmt.Println(sl3)
sl2 = append(sl2, 9, 10)
fmt.Println(sl2)
fmt.Println(sl3)
[play](https://play.golang.org/p/eMseomDmtBl)
## Maps
type Vertex struct {
Lat, Lon, float64
}
m := map[string] Vertex {
"one" : {40.8, -74.5},
"two" : {41.8, -75.5},
}
keys can be anything that can be sorted (strings, int..)
= m["four"]
m["four"] = ...
Returns default value if no exist.
m["four"], ok = ...
"ok" *true* if in map
## Functions:
func blah(i int...) int {
func blah(i int...) (int, int) {
### Methods:
func (d *Myobj) blah(i int...) (int, int) {
### Interfaces:
- not objects
- just method signatures
- implicit
type Shape interface {
func Area() int
}
ANY type that implements the 'Area' method is implicitly a Shape
How?
Let's say I have another object:
type Circle struct {
radius int
....
}
Now I define:
func (n *Circle) Area() int { // receiver/name/args/return
....
}
A Circle is now a Shape!
- implicit (Duck typing)
- variables
c := new(Circle)
var s Shape
s = c
Can also define:
func (n *Rect) Area() int ...
var r Rect
s = &r
And a Rect is now a shape.
*Why maybe no good?*
### Cool things: stack is in the heap, so:
Allocation!
func() *int {
id := 2
return &id
}
### Anonymous functions == Closures!
func intSeq() func() int {
i := 0
return func() int {
i += 1
return i
}
}
func main() {
nextInt := intSeq()
fmt.Println(nextInt())
fmt.Println(nextInt())
fmt.Println(nextInt())
}
[play](https://play.golang.org/p/KIefyeKFEP)
### More fun: fib!
func fib() func() int {
i1, i2 := 0, 1
return func() (r int) {
r = i1
i1, i2 = i2, i1+i2
return
}
}
func main() {
f := fib()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
[play](https://play.golang.org/p/jLDSk4Wend)
## Goroutines
Lightweight threads:
f(x,y)
go f(x,y)
Sync w/ *channels*, not explicit locks...
package main
import (
"fmt"
"time"
)
func slowFunc(done chan int) {
time.Sleep(2*time.Second)
fmt.Println("goroutine finish...")
done <- 1
}
func main() {
ch := make(chan int)
go slowFunc(ch)
fmt.Println("waiting...")
<-ch
fmt.Println("done!")
}
[play](https://go.dev/play/p/96dOj_Vp4m4)
blocking sends, receives until other side ready
ch := make(chan int, 5) // buffered
sync library
# Panic / Defer / Recover
```
package main
import (
"fmt"
"github.com/pkg/errors"
)
func A() {
defer fmt.Println("A")
defer func() {
if r := recover(); r != nil {
fmt.Printf("Panic: %+v\n", r)
}
}()
B()
}
func B() {
defer fmt.Println("B")
C()
}
func C() {
defer fmt.Println("C")
Break()
}
func Break() {
defer fmt.Println("D")
// panic(errors.New("the show must go on"))
fmt.Println("after panic")
}
func main() {
A()
fmt.Printf("After 'A'\n")
}
```
[play](https://go.dev/play/p/xNP3zxVI3SB)
"Note that unlike some languages which use exceptions for handling of many errors, in Go it is idiomatic to use error-indicating return values wherever possible."
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment