Added sections on go context and flags

This commit is contained in:
2025-01-13 16:21:11 -05:00
parent 2644b07951
commit f69fcfc50b
4 changed files with 117 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
# Context
Context is a way of passing information or enforcing timeouts when calling functions throughout your application as a single requests goes from layer to layer. This is usually passed as the first parameter in your functions if being used.
```go
// create an empty context
ctx := context.Background()
// append value to context
ctx = context.WithValue(ctx, "key", "value")
value := ctx.Value("key")
```
## Timeouts
```go
ctx, cancel := context.WithTimeout(context.Background(), 2 * time.Second)
defer cancel() // can call before timeout
go longRunningFunc(ctx)
select {
case <-ctx.Done():
fms.Println("done blocking main thread also!")
}
time.Sleep(2*time.Second)
func longRunningFunc(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("timed out")
return
default:
fmt.Println("still processing")
}
time.Sleep(1*time.Second)
}
}
```

62
docs/go/advanced/flags.md Normal file
View File

@@ -0,0 +1,62 @@
# Flags
Flags allow you to define command line arguments to your applications. This gives you some more useful features over `os.Args` such as help strings and validation.
```go
var age = flag.Int("age", 20, "age of user") // arg name, default, help
fmt.Println(*age) // gives us a pointer to the value
// or
var age int
flag.IntVar(&age, "age", 20, "age of user")
fmt.Println(age)
// with structs
type ServerConfig struct {
port int
env string
}
var config ServerConfig
flag.IntVar(&config.port, "port", 8000, "server port")
flag.StringVar(&config.env, "env", "dev", "environment")
flag.Parse()
```
## Custom Flags
Normally flags can only be strings, ints, or booleans, but you can create your own custom flag types by implementing the `Value` interface which has two functions, `String` and `Set`.
```go
type AddrVal struct {
addr *string
}
func (a AddrVal) String() string {
if a.addr == nil {
return ""
}
return *a.addr
}
func (a AddrVal) Set(s string) error {
if err := validateAddr(s); err != nil {
return err
}
*a.addr = s
return nil
}
func validateAddr(addr string) error {
// validate address
return nil
}
func main() {
addr := ":8080" // default value
flag.Var(AddrVal{&addr}, "addr", "address to listen on")
flag.Parse()
fmt.Println("address: ", addr)
}
```

View File

@@ -10,6 +10,8 @@ go get github.com/go-chi/chi/v5/middleware
go get github.com/go-chi/cors
```
## Basic Implementation
```go
// main.go
package main
@@ -241,6 +243,16 @@ func (app *Config) errorJSON(w http.ResponseWriter, err error, status ...int) er
}
```
## Adding Custom Types to Session
```go
// main.go, before creating session
gob.Register(data.User{})
// to add type to session
app.Session.Put(r.Context(), "user", user) // user *data.User
```
## Testing
```go

View File

@@ -16,6 +16,8 @@
{
"text": "Go Advanced",
"items": [
{"text": "Context", "link": "/go/advanced/context"},
{"text": "Flags", "link": "/go/advanced/flags"},
{ "text": "Testing", "link": "/go/advanced/testing" },
{"text": "HTTP", "link": "/go/advanced/http"},
{"text": "RPC", "link": "/go/advanced/rpc"},