SlideShare uma empresa Scribd logo
1 de 51
Baixar para ler offline
DESIGN YOUR CLIENTMike Kabischev
JUNO
▸250k lines of code
▸~70 microservices
▸hundreds of running containers
▸thousands RPS
▸40+ backend engineers
CODE BELONGS TO THE
TEAM, NOT THE INDIVIDUAL
CLEAN CODE
▸Simple
▸Adaptable
▸Testable
ONE CLIENT STORY
3-RD PARTY
SERVICE A SERVICE B SERVICE C
3-RD PARTY
SERVICE A SERVICE B SERVICE C
HTTP CLIENT
// HTTPClient wraps httpClient
type HTTPClient struct {
    httpClient *http.Client
}
// Do sends HTTP request
func (c *HTTPClient) Do(r *http.Request) (*http.Response, error) {
    return http.DefaultClient.Do(r)
}
HTTP CLIENT
HTTP CLIENT
‣Authorization
‣Logging
‣Instrumentation
‣Backoff retries
‣Load balancing
// Do sends HTTP request with authorization, load balancing,
// retries, metrics & logging
func (c *HTTPClient) Do(r *http.Request) (res *http.Response, err error) {
    r.Header.Add("Authorization", c.AuthToken)
    for i := 0; i < c.RetryAttempts; i++ {
        r.URL.Host = c.Backends[rand.Intn(len(c.Backends))]
        c.Logger.Printf("make HTTP call. Method: %v. URL: %v", r.Method, r.URL)
        start := time.Now()
        res, err = http.DefaultClient.Do(r)
        c.DurationSummary.Observe(time.Since(start).Seconds())
        if err != nil {
            c.Logger.Printf("error while making HTTP call: %v", err)
            time.Sleep(time.Duration(i) * c.RetryDelay)
            continue
        }
        break
    }
    c.Logger.Printf("response code: %v", res.StatusCode)
    return res, err
}
HTTP CLIENT
// Do sends HTTP request with authorization, load balancing,
// retries, metrics & logging
func (c *HTTPClient) Do(r *http.Request) (res *http.Response, err error) {
    r.Header.Add("Authorization", c.AuthToken)
    for i := 0; i < c.RetryAttempts; i++ {
        r.URL.Host = c.Backends[rand.Intn(len(c.Backends))]
        c.Logger.Printf("make HTTP call. Method: %v. URL: %v", r.Method, r.URL)
        start := time.Now()
        res, err = http.DefaultClient.Do(r)
        c.DurationSummary.Observe(time.Since(start).Seconds())
        if err != nil {
            c.Logger.Printf("error while making HTTP call: %v", err)
            time.Sleep(time.Duration(i) * c.RetryDelay)
            continue
        }
        break
    }
    c.Logger.Printf("response code: %v", res.StatusCode)
    return res, err
}
HTTP CLIENT
EVERYTHING IS ALREADY INVENTED
// A Handler responds to an HTTP request.
type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w, r)
}
HTTP HANDLERS
MIDDLEWARE
// Middleware adds additional behaviour to handler
type Middleware func(http.Handler) http.Handler
MIDDLEWARE CHAIN
HANDLERREQUEST
Middleware A
Middleware B
Middleware C
MIDDLEWARE CHAIN
HANDLERREQUEST
Middleware A
Middleware B
Middleware C
MIDDLEWARE CHAIN
HANDLERREQUEST
Middleware A
Middleware B
Middleware C
MIDDLEWARE CHAIN
HANDLERREQUEST
Middleware A
Middleware B
Middleware C
MIDDLEWARE CHAIN
HANDLERREQUEST
Middleware A
Middleware B
Middleware C
MIDDLEWARE CHAIN
HANDLERRESPONSE
Middleware A
Middleware B
Middleware C
MIDDLEWARE CHAIN
CLIENTRESPONSE
Middleware A
Middleware B
Middleware C
MIDDLEWARE CHAIN
CLIENTRESPONSE
Middleware A
Middleware B
Middleware C
MIDDLEWARE CHAIN
HANDLER RESPONSE
Middleware A
Middleware B
Middleware C
MIDDLEWARE CHAIN
HANDLER RESPONSE
Middleware A
Middleware B
Middleware C
PROJECT IT TO THE CLIENT SIDE
CLIENT INTERFACE
// Client is an interface supported by http.Client
type Client interface {
    Do(req *http.Request) (*http.Response, error)
}
// ClientFn is a function that implements Client
type ClientFn func(*http.Request) (*http.Response, error)
// Do is an implementation of Client interface
func (c ClientFn) Do(r *http.Request) (*http.Response, error) {
    return c(r)
}
MIDDLEWARE
// Middleware adds additional behaviour to Client
type Middleware func(Client) Client
LOGGING
// Logging returns a Middleware that logs request
func Logging(l *log.Logger) Middleware {
    return func(c Client) Client {
        return ClientFn(func(r *http.Request) (*http.Response, error) {
            l.Printf("HTTP call. Method: %v. URL: %v", r.Method, r.URL)
            return c.Do(r)
        })
    }
}
HEADERS
// Header adds specified header to request
func Header(key, value string) Middleware {
    return func(c Client) Client {
        return ClientFn(func(r *http.Request) (*http.Response, error) {
            r.Header.Add(key, value)
            return c.Do(r)
        })
    }
}
// BasicAuthorization adds header for Basic HTTP Authorization
func BasicAuthorization(username, password string) Middleware {
    value := []byte(username + ":" + password)
    encoded := base64.StdEncoding.EncodeToString(value)
    return Header("Authorization", "Basic "+encoded)
}
METRICS
// Metrics returns a Middleware that measures the time taken by request
func Metrics(s prometheus.Summary) Middleware {
    return func(c Client) Client {
        return ClientFn(func(r *http.Request) (*http.Response, error) {
            defer func(t time.Time) {
                s.Observe(time.Since(t).Seconds())
            }(time.Now())
            return c.Do(r)
        })
    }
}
BACKOFF
// Backoff returns a Middleware that makes configured number of attemps
// to make HTTP call
func Backoff(attemps int, delay time.Duration) Middleware {
    return func(c Client) Client {
        return ClientFn(func(r *http.Request) (res *http.Response, err error) {
            for i := 0; i < attemps; i++ {
                if res, err := c.Do(r); err == nil {
                    break
                }
                time.Sleep(time.Duration(i) * delay)
            }
            return res, err
        })
    }
}
LOAD BALANCING
// LoadBalancing returns a Middleware that chooses random backend from
// the specified list
func LoadBalancing(backends ...string) Middleware {
    return func(c Client) Client {
        return ClientFn(func(r *http.Request) (*http.Response, error) {
            r.URL.Host = backends[rand.Intn(len(backends))]
            return c.Do®
        })
    }
}
RECOVER
// Recover returns a middleware that recovers all panics
func Recover() Middleware {
    return func(c Client) Client {
        return ClientFn(func(r *http.Request) (res *http.Response, err error) {
            defer func() {
                if r := recover(); r != nil {
                    err = fmt.Errorf("recovered panic: %v", r)
                }
            }()
            return c.Do(r)
        })
    }
}
MIDDLEWARE CHAIN
// Chain wraps a Client c with all the given middlewares
func Chain(c Client, mw ...Middleware) Client {
    result := c
    for _, middleware := range mw {
        result = middleware(result)
    }
    return result
}
MIDDLEWARE CHAIN
client := Chain(
    &http.Client{},
    Logging(log.New(os.Stdout, "http: ", log.LstdFlags)),
)
MIDDLEWARE CHAIN
client := Chain(
    &http.Client{},
    Logging(log.New(os.Stdout, "http: ", log.LstdFlags)),
    BasicAuthorization("username", "password"),
)
MIDDLEWARE CHAIN
client := Chain(
    &http.Client{},
    Logging(log.New(os.Stdout, "http: ", log.LstdFlags)),
    BasicAuthorization("username", "password"),
    Metrics(NewSummary("request_duration_seconds")),
)
MIDDLEWARE CHAIN
client := Chain(
    &http.Client{},
    Logging(log.New(os.Stdout, "http: ", log.LstdFlags)),
    BasicAuthorization("username", "password"),
    Metrics(NewSummary("request_duration_seconds")),
    Backoff(3, 20*time.Millisecond),
)
MIDDLEWARE CHAIN
client := Chain(
    &http.Client{},
    Logging(log.New(os.Stdout, "http: ", log.LstdFlags)),
    BasicAuthorization("username", "password"),
    Metrics(NewSummary("request_duration_seconds")),
    Backoff(3, 20*time.Millisecond),
    LoadBalancing("instance01", "instance02", "instance03"),
)
MIDDLEWARE CHAIN
client := Chain(
    &http.Client{},
    Logging(log.New(os.Stdout, "http: ", log.LstdFlags)),
    BasicAuthorization("username", "password"),
    Metrics(NewSummary("request_duration_seconds")),
    Backoff(3, 20*time.Millisecond),
LoadBalancing("instance01", "instance02", "instance03"),
    Recover(),
)
http://idiomaticgo.com/post/best-practice/accept-interfaces-return-structs/
ACCEPT INTERFACES
RETURN STRUCTS
https://github.com/gojuno/go-zooz
GO WAY
NOT GO WAY
googlemaps.github.io/maps
github.com/aws/aws-sdk-go
github.com/coreos/go-etcd
github.com/moby/moby
github.com/openzipkin/zipkin-go-opentracing
github.com/stripe/stripe-go
... and more ...
DON'T FORGET THE BASICS
https://go-proverbs.github.io
https://golang.org/doc/effective_go.html
https://github.com/golang/go/wiki/CodeReviewComments
SIMPLICITY IS COMPLICATED
Rob Pike
QUESTIONS?

Mais conteúdo relacionado

Mais procurados

lldb – Debugger auf Abwegen
lldb – Debugger auf Abwegenlldb – Debugger auf Abwegen
lldb – Debugger auf Abwegeninovex GmbH
 
Lab 1: Compiler Toolchain
Lab 1: Compiler ToolchainLab 1: Compiler Toolchain
Lab 1: Compiler Toolchainenidcruz
 
IBM Cloud University: Java, Node.js and Swift
IBM Cloud University: Java, Node.js and SwiftIBM Cloud University: Java, Node.js and Swift
IBM Cloud University: Java, Node.js and SwiftChris Bailey
 
Sharding and Load Balancing in Scala - Twitter's Finagle
Sharding and Load Balancing in Scala - Twitter's FinagleSharding and Load Balancing in Scala - Twitter's Finagle
Sharding and Load Balancing in Scala - Twitter's FinagleGeoff Ballinger
 
Background Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRbBackground Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRbJuan Maiz
 
Writing Docker monitoring agent with Go
Writing Docker monitoring agent with GoWriting Docker monitoring agent with Go
Writing Docker monitoring agent with GoNaoki AINOYA
 
c++ project on restaurant billing
c++ project on restaurant billing c++ project on restaurant billing
c++ project on restaurant billing Swakriti Rathore
 
System programmin practical file
System programmin practical fileSystem programmin practical file
System programmin practical fileAnkit Dixit
 
MongoDB World 2016: Implementing Async Networking in MongoDB 3.2
MongoDB World 2016: Implementing Async Networking in MongoDB 3.2MongoDB World 2016: Implementing Async Networking in MongoDB 3.2
MongoDB World 2016: Implementing Async Networking in MongoDB 3.2MongoDB
 
Critical errors in CryEngine V code
Critical errors in CryEngine V codeCritical errors in CryEngine V code
Critical errors in CryEngine V codePVS-Studio
 
Serverless, The Middy Way - Workshop
Serverless, The Middy Way - WorkshopServerless, The Middy Way - Workshop
Serverless, The Middy Way - WorkshopLuciano Mammino
 
32 shell-programming
32 shell-programming32 shell-programming
32 shell-programmingkayalkarnan
 

Mais procurados (13)

lldb – Debugger auf Abwegen
lldb – Debugger auf Abwegenlldb – Debugger auf Abwegen
lldb – Debugger auf Abwegen
 
Lab 1: Compiler Toolchain
Lab 1: Compiler ToolchainLab 1: Compiler Toolchain
Lab 1: Compiler Toolchain
 
IBM Cloud University: Java, Node.js and Swift
IBM Cloud University: Java, Node.js and SwiftIBM Cloud University: Java, Node.js and Swift
IBM Cloud University: Java, Node.js and Swift
 
Sharding and Load Balancing in Scala - Twitter's Finagle
Sharding and Load Balancing in Scala - Twitter's FinagleSharding and Load Balancing in Scala - Twitter's Finagle
Sharding and Load Balancing in Scala - Twitter's Finagle
 
Background Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRbBackground Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRb
 
Writing Docker monitoring agent with Go
Writing Docker monitoring agent with GoWriting Docker monitoring agent with Go
Writing Docker monitoring agent with Go
 
c++ project on restaurant billing
c++ project on restaurant billing c++ project on restaurant billing
c++ project on restaurant billing
 
System programs in C language.
System programs in C language.System programs in C language.
System programs in C language.
 
System programmin practical file
System programmin practical fileSystem programmin practical file
System programmin practical file
 
MongoDB World 2016: Implementing Async Networking in MongoDB 3.2
MongoDB World 2016: Implementing Async Networking in MongoDB 3.2MongoDB World 2016: Implementing Async Networking in MongoDB 3.2
MongoDB World 2016: Implementing Async Networking in MongoDB 3.2
 
Critical errors in CryEngine V code
Critical errors in CryEngine V codeCritical errors in CryEngine V code
Critical errors in CryEngine V code
 
Serverless, The Middy Way - Workshop
Serverless, The Middy Way - WorkshopServerless, The Middy Way - Workshop
Serverless, The Middy Way - Workshop
 
32 shell-programming
32 shell-programming32 shell-programming
32 shell-programming
 

Semelhante a Design your client: go way

Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interfaceJoakim Gustin
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interfaceEvolve
 
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeGDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeKAI CHU CHUNG
 
Meetup talk: Readying your Go Webservice
Meetup talk: Readying your Go WebserviceMeetup talk: Readying your Go Webservice
Meetup talk: Readying your Go WebserviceRalph Ligtenberg
 
Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparisonHiroshi Nakamura
 
Finagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at PinterestFinagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at PinterestPavan Chitumalla
 
HTTPBuilder NG: Back From The Dead
HTTPBuilder NG: Back From The DeadHTTPBuilder NG: Back From The Dead
HTTPBuilder NG: Back From The Deadnoamt
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web ToolkitsYiguang Hu
 
Finagle - an intro to rpc & a sync programming in jvm
Finagle - an intro to rpc & a sync programming in jvmFinagle - an intro to rpc & a sync programming in jvm
Finagle - an intro to rpc & a sync programming in jvmPrasannaKumar Sathyanarayanan
 
GWT training session 3
GWT training session 3GWT training session 3
GWT training session 3SNEHAL MASNE
 
Функции обратного вызова в C++. Виталий Ткаченко. CoreHard Spring 2019
Функции обратного вызова в C++. Виталий Ткаченко. CoreHard Spring 2019Функции обратного вызова в C++. Виталий Ткаченко. CoreHard Spring 2019
Функции обратного вызова в C++. Виталий Ткаченко. CoreHard Spring 2019corehard_by
 
Retrofit library for android
Retrofit library for androidRetrofit library for android
Retrofit library for androidInnovationM
 
Retrofit Library In Android
Retrofit Library In AndroidRetrofit Library In Android
Retrofit Library In AndroidInnovationM
 
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)Brian Sam-Bodden
 
Java web programming
Java web programmingJava web programming
Java web programmingChing Yi Chan
 
Async programming on NET
Async programming on NETAsync programming on NET
Async programming on NETyuyijq
 
Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...
Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...
Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...Twilio Inc
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScriptQiangning Hong
 
What's new in jQuery 1.5
What's new in jQuery 1.5What's new in jQuery 1.5
What's new in jQuery 1.5Martin Kleppe
 

Semelhante a Design your client: go way (20)

Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interface
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interface
 
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeGDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
 
Meetup talk: Readying your Go Webservice
Meetup talk: Readying your Go WebserviceMeetup talk: Readying your Go Webservice
Meetup talk: Readying your Go Webservice
 
Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparison
 
gRPC in Go
gRPC in GogRPC in Go
gRPC in Go
 
Finagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at PinterestFinagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at Pinterest
 
HTTPBuilder NG: Back From The Dead
HTTPBuilder NG: Back From The DeadHTTPBuilder NG: Back From The Dead
HTTPBuilder NG: Back From The Dead
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web Toolkits
 
Finagle - an intro to rpc & a sync programming in jvm
Finagle - an intro to rpc & a sync programming in jvmFinagle - an intro to rpc & a sync programming in jvm
Finagle - an intro to rpc & a sync programming in jvm
 
GWT training session 3
GWT training session 3GWT training session 3
GWT training session 3
 
Функции обратного вызова в C++. Виталий Ткаченко. CoreHard Spring 2019
Функции обратного вызова в C++. Виталий Ткаченко. CoreHard Spring 2019Функции обратного вызова в C++. Виталий Ткаченко. CoreHard Spring 2019
Функции обратного вызова в C++. Виталий Ткаченко. CoreHard Spring 2019
 
Retrofit library for android
Retrofit library for androidRetrofit library for android
Retrofit library for android
 
Retrofit Library In Android
Retrofit Library In AndroidRetrofit Library In Android
Retrofit Library In Android
 
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)
 
Java web programming
Java web programmingJava web programming
Java web programming
 
Async programming on NET
Async programming on NETAsync programming on NET
Async programming on NET
 
Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...
Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...
Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
What's new in jQuery 1.5
What's new in jQuery 1.5What's new in jQuery 1.5
What's new in jQuery 1.5
 

Último

Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxAsutosh Ranjan
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxupamatechverse
 
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130Suhani Kapoor
 
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Call Girls in Nagpur High Profile
 
Microscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxMicroscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxpurnimasatapathy1234
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...roncy bisnoi
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...ranjana rawat
 
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...Soham Mondal
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escortsranjana rawat
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordAsst.prof M.Gokilavani
 
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)Suman Mia
 
result management system report for college project
result management system report for college projectresult management system report for college project
result management system report for college projectTonystark477637
 
UNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular ConduitsUNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular Conduitsrknatarajan
 
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130Suhani Kapoor
 

Último (20)

Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptx
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
 
Water Industry Process Automation & Control Monthly - April 2024
Water Industry Process Automation & Control Monthly - April 2024Water Industry Process Automation & Control Monthly - April 2024
Water Industry Process Automation & Control Monthly - April 2024
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptx
 
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
 
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
 
Microscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxMicroscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptx
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
 
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
 
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
 
result management system report for college project
result management system report for college projectresult management system report for college project
result management system report for college project
 
UNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular ConduitsUNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular Conduits
 
Roadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and RoutesRoadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and Routes
 
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
 

Design your client: go way

  • 2. JUNO ▸250k lines of code ▸~70 microservices ▸hundreds of running containers ▸thousands RPS ▸40+ backend engineers
  • 3. CODE BELONGS TO THE TEAM, NOT THE INDIVIDUAL
  • 4.
  • 7. 3-RD PARTY SERVICE A SERVICE B SERVICE C
  • 8. 3-RD PARTY SERVICE A SERVICE B SERVICE C
  • 10. // HTTPClient wraps httpClient type HTTPClient struct {     httpClient *http.Client } // Do sends HTTP request func (c *HTTPClient) Do(r *http.Request) (*http.Response, error) {     return http.DefaultClient.Do(r) } HTTP CLIENT
  • 12. // Do sends HTTP request with authorization, load balancing, // retries, metrics & logging func (c *HTTPClient) Do(r *http.Request) (res *http.Response, err error) {     r.Header.Add("Authorization", c.AuthToken)     for i := 0; i < c.RetryAttempts; i++ {         r.URL.Host = c.Backends[rand.Intn(len(c.Backends))]         c.Logger.Printf("make HTTP call. Method: %v. URL: %v", r.Method, r.URL)         start := time.Now()         res, err = http.DefaultClient.Do(r)         c.DurationSummary.Observe(time.Since(start).Seconds())         if err != nil {             c.Logger.Printf("error while making HTTP call: %v", err)             time.Sleep(time.Duration(i) * c.RetryDelay)             continue         }         break     }     c.Logger.Printf("response code: %v", res.StatusCode)     return res, err } HTTP CLIENT
  • 13.
  • 14. // Do sends HTTP request with authorization, load balancing, // retries, metrics & logging func (c *HTTPClient) Do(r *http.Request) (res *http.Response, err error) {     r.Header.Add("Authorization", c.AuthToken)     for i := 0; i < c.RetryAttempts; i++ {         r.URL.Host = c.Backends[rand.Intn(len(c.Backends))]         c.Logger.Printf("make HTTP call. Method: %v. URL: %v", r.Method, r.URL)         start := time.Now()         res, err = http.DefaultClient.Do(r)         c.DurationSummary.Observe(time.Since(start).Seconds())         if err != nil {             c.Logger.Printf("error while making HTTP call: %v", err)             time.Sleep(time.Duration(i) * c.RetryDelay)             continue         }         break     }     c.Logger.Printf("response code: %v", res.StatusCode)     return res, err } HTTP CLIENT
  • 16. // A Handler responds to an HTTP request. type Handler interface {     ServeHTTP(ResponseWriter, *Request) } // The HandlerFunc type is an adapter to allow the use of // ordinary functions as HTTP handlers. If f is a function // with the appropriate signature, HandlerFunc(f) is a // Handler that calls f. type HandlerFunc func(ResponseWriter, *Request) // ServeHTTP calls f(w, r). func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {     f(w, r) } HTTP HANDLERS
  • 17. MIDDLEWARE // Middleware adds additional behaviour to handler type Middleware func(http.Handler) http.Handler
  • 26. MIDDLEWARE CHAIN HANDLER RESPONSE Middleware A Middleware B Middleware C
  • 27. MIDDLEWARE CHAIN HANDLER RESPONSE Middleware A Middleware B Middleware C
  • 28. PROJECT IT TO THE CLIENT SIDE
  • 29. CLIENT INTERFACE // Client is an interface supported by http.Client type Client interface {     Do(req *http.Request) (*http.Response, error) } // ClientFn is a function that implements Client type ClientFn func(*http.Request) (*http.Response, error) // Do is an implementation of Client interface func (c ClientFn) Do(r *http.Request) (*http.Response, error) {     return c(r) }
  • 30. MIDDLEWARE // Middleware adds additional behaviour to Client type Middleware func(Client) Client
  • 31. LOGGING // Logging returns a Middleware that logs request func Logging(l *log.Logger) Middleware {     return func(c Client) Client {         return ClientFn(func(r *http.Request) (*http.Response, error) {             l.Printf("HTTP call. Method: %v. URL: %v", r.Method, r.URL)             return c.Do(r)         })     } }
  • 32. HEADERS // Header adds specified header to request func Header(key, value string) Middleware {     return func(c Client) Client {         return ClientFn(func(r *http.Request) (*http.Response, error) {             r.Header.Add(key, value)             return c.Do(r)         })     } } // BasicAuthorization adds header for Basic HTTP Authorization func BasicAuthorization(username, password string) Middleware {     value := []byte(username + ":" + password)     encoded := base64.StdEncoding.EncodeToString(value)     return Header("Authorization", "Basic "+encoded) }
  • 33. METRICS // Metrics returns a Middleware that measures the time taken by request func Metrics(s prometheus.Summary) Middleware {     return func(c Client) Client {         return ClientFn(func(r *http.Request) (*http.Response, error) {             defer func(t time.Time) {                 s.Observe(time.Since(t).Seconds())             }(time.Now())             return c.Do(r)         })     } }
  • 34. BACKOFF // Backoff returns a Middleware that makes configured number of attemps // to make HTTP call func Backoff(attemps int, delay time.Duration) Middleware {     return func(c Client) Client {         return ClientFn(func(r *http.Request) (res *http.Response, err error) {             for i := 0; i < attemps; i++ {                 if res, err := c.Do(r); err == nil {                     break                 }                 time.Sleep(time.Duration(i) * delay)             }             return res, err         })     } }
  • 35. LOAD BALANCING // LoadBalancing returns a Middleware that chooses random backend from // the specified list func LoadBalancing(backends ...string) Middleware {     return func(c Client) Client {         return ClientFn(func(r *http.Request) (*http.Response, error) {             r.URL.Host = backends[rand.Intn(len(backends))]             return c.Do®         })     } }
  • 36. RECOVER // Recover returns a middleware that recovers all panics func Recover() Middleware {     return func(c Client) Client {         return ClientFn(func(r *http.Request) (res *http.Response, err error) {             defer func() {                 if r := recover(); r != nil {                     err = fmt.Errorf("recovered panic: %v", r)                 }             }()             return c.Do(r)         })     } }
  • 37.
  • 38. MIDDLEWARE CHAIN // Chain wraps a Client c with all the given middlewares func Chain(c Client, mw ...Middleware) Client {     result := c     for _, middleware := range mw {         result = middleware(result)     }     return result }
  • 39. MIDDLEWARE CHAIN client := Chain(     &http.Client{},     Logging(log.New(os.Stdout, "http: ", log.LstdFlags)), )
  • 40. MIDDLEWARE CHAIN client := Chain(     &http.Client{},     Logging(log.New(os.Stdout, "http: ", log.LstdFlags)),     BasicAuthorization("username", "password"), )
  • 41. MIDDLEWARE CHAIN client := Chain(     &http.Client{},     Logging(log.New(os.Stdout, "http: ", log.LstdFlags)),     BasicAuthorization("username", "password"),     Metrics(NewSummary("request_duration_seconds")), )
  • 42. MIDDLEWARE CHAIN client := Chain(     &http.Client{},     Logging(log.New(os.Stdout, "http: ", log.LstdFlags)),     BasicAuthorization("username", "password"),     Metrics(NewSummary("request_duration_seconds")),     Backoff(3, 20*time.Millisecond), )
  • 43. MIDDLEWARE CHAIN client := Chain(     &http.Client{},     Logging(log.New(os.Stdout, "http: ", log.LstdFlags)),     BasicAuthorization("username", "password"),     Metrics(NewSummary("request_duration_seconds")),     Backoff(3, 20*time.Millisecond),     LoadBalancing("instance01", "instance02", "instance03"), )
  • 44. MIDDLEWARE CHAIN client := Chain(     &http.Client{},     Logging(log.New(os.Stdout, "http: ", log.LstdFlags)),     BasicAuthorization("username", "password"),     Metrics(NewSummary("request_duration_seconds")),     Backoff(3, 20*time.Millisecond), LoadBalancing("instance01", "instance02", "instance03"),     Recover(), )
  • 48.
  • 49. DON'T FORGET THE BASICS https://go-proverbs.github.io https://golang.org/doc/effective_go.html https://github.com/golang/go/wiki/CodeReviewComments