Fit slides to screen
This commit is contained in:
parent
69342a7b45
commit
19d79613cd
11 changed files with 59 additions and 62 deletions
|
@ -8,7 +8,6 @@ import (
|
||||||
func SimpleCancelation() {
|
func SimpleCancelation() {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
cancel()
|
cancel()
|
||||||
|
@ -19,6 +18,8 @@ func SimpleCancelation() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OMIT
|
||||||
|
|
||||||
func SimpleTimeout() {
|
func SimpleTimeout() {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -28,6 +29,8 @@ func SimpleTimeout() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OMIT
|
||||||
|
|
||||||
func doSlowJob(ctx context.Context) error {
|
func doSlowJob(ctx context.Context) error {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
|
|
@ -22,7 +22,6 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
defer fd.Close()
|
defer fd.Close()
|
||||||
|
|
||||||
scanner := bufio.NewScanner(fd)
|
scanner := bufio.NewScanner(fd)
|
||||||
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
|
|
|
@ -3,7 +3,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"errors"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/cookiejar"
|
"net/http/cookiejar"
|
||||||
"time"
|
"time"
|
||||||
|
@ -13,16 +12,9 @@ func main() {
|
||||||
// все куки записанные в этот Jar будут передаваться
|
// все куки записанные в этот Jar будут передаваться
|
||||||
// и изменяться во всех запросах
|
// и изменяться во всех запросах
|
||||||
cj, _ := cookiejar.New(nil)
|
cj, _ := cookiejar.New(nil)
|
||||||
|
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
Timeout: 1 * time.Second,
|
Timeout: 1 * time.Second,
|
||||||
Jar: cj,
|
Jar: cj,
|
||||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
|
||||||
if len(via) > 20 {
|
|
||||||
return errors.New("too many redirects")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
Transport: &http.Transport{
|
Transport: &http.Transport{
|
||||||
// резмер буферов чтения и записи (4KB по-умолчанию)
|
// резмер буферов чтения и записи (4KB по-умолчанию)
|
||||||
WriteBufferSize: 32 << 10,
|
WriteBufferSize: 32 << 10,
|
||||||
|
@ -38,6 +30,5 @@ func main() {
|
||||||
// ...
|
// ...
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = client
|
_ = client
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,12 @@ import (
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
body := bytes.NewBufferString("All your base are belong to us")
|
body := bytes.NewBufferString("All your base are belong to us")
|
||||||
req, err := http.NewRequest("POST", "https://myapi.com/create", body)
|
req, err := http.NewRequest(http.MethodPost, "https://myapi.com/create", body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("X-Source", "Zero Wing")
|
req.Header.Set("X-Source", "Zero Wing")
|
||||||
|
|
||||||
repr, err := httputil.DumpRequestOut(req, true)
|
repr, err := httputil.DumpRequestOut(req, true)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Println(string(repr))
|
fmt.Println(string(repr))
|
||||||
|
@ -26,6 +25,6 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
fmt.Println(resp.StatusCode)
|
fmt.Println(resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,16 +17,15 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func run() error {
|
func handler(w http.ResponseWriter, r *http.Request) {
|
||||||
handler := func(w http.ResponseWriter, r *http.Request) {
|
_, _ = w.Write([]byte("pong"))
|
||||||
_, _ = w.Write([]byte("pong"))
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
func run() error {
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
Addr: ":8080",
|
Addr: ":8080",
|
||||||
Handler: http.HandlerFunc(handler),
|
Handler: http.HandlerFunc(handler),
|
||||||
}
|
}
|
||||||
|
|
||||||
serveChan := make(chan error, 1)
|
serveChan := make(chan error, 1)
|
||||||
go func() {
|
go func() {
|
||||||
serveChan <- srv.ListenAndServe()
|
serveChan <- srv.ListenAndServe()
|
||||||
|
@ -34,15 +33,13 @@ func run() error {
|
||||||
|
|
||||||
stop := make(chan os.Signal, 1)
|
stop := make(chan os.Signal, 1)
|
||||||
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-stop:
|
case <-stop:
|
||||||
fmt.Println("shutting down gracefully")
|
fmt.Println("shutting down gracefully")
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
return srv.Shutdown(ctx)
|
return srv.Shutdown(ctx)
|
||||||
|
|
||||||
case err := <-serveChan:
|
case err := <-serveChan:
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,13 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func NewAPICLient(baseURL string) *APIClient {
|
||||||
|
if baseURL == "" {
|
||||||
|
baseURL = BaseURLProd
|
||||||
|
}
|
||||||
|
return &APIClient{baseURL: baseURL, httpc: new(http.Client)}
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
BaseURLProd = "https://github.com/api"
|
BaseURLProd = "https://github.com/api"
|
||||||
)
|
)
|
||||||
|
@ -16,26 +23,14 @@ type APIClient struct {
|
||||||
httpc *http.Client
|
httpc *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAPICLient(baseURL string) *APIClient {
|
|
||||||
if baseURL == "" {
|
|
||||||
baseURL = BaseURLProd
|
|
||||||
}
|
|
||||||
return &APIClient{
|
|
||||||
baseURL: baseURL,
|
|
||||||
httpc: new(http.Client),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *APIClient) GetReposCount(ctx context.Context, userID string) (int, error) {
|
func (c *APIClient) GetReposCount(ctx context.Context, userID string) (int, error) {
|
||||||
url := c.baseURL + "/users/" + userID + "/repos/count"
|
url := c.baseURL + "/users/" + userID + "/repos/count"
|
||||||
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
|
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
|
||||||
|
|
||||||
resp, err := c.httpc.Do(req)
|
resp, err := c.httpc.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
|
@ -9,20 +9,13 @@ import (
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
urls := []string{"https://golang.org/doc", "https://golang.org/pkg", "https://golang.org/help"}
|
urls := []string{"https://golang.org/doc", "https://golang.org/pkg", "https://golang.org/help"}
|
||||||
|
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
Transport: &http.Transport{
|
Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}},
|
||||||
TLSClientConfig: &tls.Config{
|
|
||||||
InsecureSkipVerify: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
for _, url := range urls {
|
for _, url := range urls {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
|
||||||
go func(url string) {
|
go func(url string) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
resp, err := client.Get(url)
|
resp, err := client.Get(url)
|
||||||
|
|
|
@ -11,14 +11,9 @@ import (
|
||||||
func main() {
|
func main() {
|
||||||
urls := []string{"https://golang.org/doc", "https://golang.org/pkg", "https://golang.org/help"}
|
urls := []string{"https://golang.org/doc", "https://golang.org/pkg", "https://golang.org/help"}
|
||||||
|
|
||||||
client := &http.Client{
|
client := &http.Client{Transport: &http.Transport{MaxConnsPerHost: 100}}
|
||||||
Transport: &http.Transport{
|
|
||||||
MaxConnsPerHost: 100,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
for _, url := range urls {
|
for _, url := range urls {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
http и context
|
http и context
|
||||||
Лекция 6
|
Лекция 6
|
||||||
|
|
||||||
Георгий Зуйков
|
Фёдор Короткий
|
||||||
|
|
||||||
* Имеем из коробки
|
* Имеем из коробки
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ http и context
|
||||||
|
|
||||||
* Делаем более лучший запрос
|
* Делаем более лучший запрос
|
||||||
|
|
||||||
.play custompost/custompost.go
|
.play custompost/custompost.go /func/,/^}/
|
||||||
|
|
||||||
`http.DefaultClient` - базовый глобальный клиент с настройками по-умолчанию.
|
`http.DefaultClient` - базовый глобальный клиент с настройками по-умолчанию.
|
||||||
|
|
||||||
|
@ -87,12 +87,20 @@ http и context
|
||||||
|
|
||||||
.code simpleserver/simpleserver.go /func RunTLSServer/,/^}/
|
.code simpleserver/simpleserver.go /func RunTLSServer/,/^}/
|
||||||
|
|
||||||
http.Handler - интерфейс, описывающий функцию для обработки HTTP запроса.
|
* Простой HTTP сервер
|
||||||
|
|
||||||
|
`http.Handler` - интерфейс, описывающий функцию для обработки HTTP запроса.
|
||||||
|
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
ServeHTTP(ResponseWriter, *Request)
|
ServeHTTP(ResponseWriter, *Request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResponseWriter interface {
|
||||||
|
Header() Header
|
||||||
|
WriteStatus(int)
|
||||||
|
Write([]byte) (int, error)
|
||||||
|
}
|
||||||
|
|
||||||
* Роутинг
|
* Роутинг
|
||||||
|
|
||||||
.code simpleserver/router.go /func RunServerWithRouting/,/OMIT/
|
.code simpleserver/router.go /func RunServerWithRouting/,/OMIT/
|
||||||
|
@ -119,10 +127,6 @@ http.Handler - интерфейс, описывающий функцию для
|
||||||
|
|
||||||
* context
|
* context
|
||||||
|
|
||||||
Контекст - инкапсулированное состояние определенной части приложения.
|
|
||||||
Позволяет оповещать операции о необходимости завершения и/или передавать контекстозависимые значения между различными частями приложения.
|
|
||||||
Контексты наследуемы, при отмене закрывается родительский и все дочерние контексты.
|
|
||||||
|
|
||||||
type Context interface {
|
type Context interface {
|
||||||
// Возвращает время, когда операция будет оповещена о необходимости завершения
|
// Возвращает время, когда операция будет оповещена о необходимости завершения
|
||||||
Deadline() (deadline time.Time, ok bool)
|
Deadline() (deadline time.Time, ok bool)
|
||||||
|
@ -142,15 +146,37 @@ http.Handler - интерфейс, описывающий функцию для
|
||||||
Value(key interface{}) interface{}
|
Value(key interface{}) interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
Типы контекстов:
|
- Отмена таймауты
|
||||||
- TODO
|
- Передача request scoped значений
|
||||||
- Background
|
|
||||||
- Cancel
|
|
||||||
- Deadline
|
|
||||||
|
|
||||||
|
* context
|
||||||
|
|
||||||
|
Типы контекстов:
|
||||||
|
|
||||||
|
// root context
|
||||||
|
todo := context.TODO()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// manual cancel
|
||||||
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// cancel by timeout
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(time.Second))
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
* Отменяем операции
|
* Отменяем операции
|
||||||
|
|
||||||
.code context/cancelation/cancelation.go /func SimpleCancelation()/,/OMIT/
|
.code context/cancelation/cancelation.go /func SimpleCancelation()/,/OMIT/
|
||||||
|
.code context/cancelation/cancelation.go /func doSlowJob/,/OMIT/
|
||||||
|
|
||||||
|
* Отменяем операции
|
||||||
|
|
||||||
|
.code context/cancelation/cancelation.go /func SimpleTimeout()/,/OMIT/
|
||||||
|
.code context/cancelation/cancelation.go /func doSlowJob/,/OMIT/
|
||||||
|
|
||||||
* context в библиотеках Go
|
* context в библиотеках Go
|
||||||
|
|
||||||
|
|
|
@ -10,5 +10,6 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
fmt.Println(resp.StatusCode)
|
fmt.Println(resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ func RunServerWithRouting() {
|
||||||
w.WriteHeader(404)
|
w.WriteHeader(404)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := http.ListenAndServe(":8080", http.HandlerFunc(router))
|
err := http.ListenAndServe(":8080", http.HandlerFunc(router))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -25,7 +24,6 @@ func RunServerWithRouting() {
|
||||||
func pongHandler(w http.ResponseWriter, r *http.Request) {
|
func pongHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
_, _ = w.Write([]byte("pong"))
|
_, _ = w.Write([]byte("pong"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func shmongHandler(w http.ResponseWriter, r *http.Request) {
|
func shmongHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
_, _ = w.Write([]byte("shmong"))
|
_, _ = w.Write([]byte("shmong"))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue