SlideShare ist ein Scribd-Unternehmen logo
1 von 29
Downloaden Sie, um offline zu lesen
Gokit
Gophercon Korea 2015
anarcher
Gokit 소개
Gokit에 관심을 가지게 된 이유
Gokit의 구조
RPC Server 작성하기
typeAddRequeststruct{
A,Bint64
}
typeAddResponsestruct{
Vint64
}
typeHandlerstruct{}
func(hHandler)Add(reqAddRequest,res*AddResponse)error{
res.V=req.A+req.B
returnnil
}
funcmain(){
varadd=new(Handler)
s:=rpc.NewServer()
s.RegisterName("addsvc",add)
s.HandleHTTP(rpc.DefaultRPCPath,rpc.DefaultDebugPath)
gohttp.ListenAndServe(addr,s)
time.Sleep(1*time.Second)
ret:=ClientCall(1,2)
log.Println("ret:",ret)
} Run
입력받은 a,b를 더하는 비지니스 로직에 대한 RPC(net/rpc) 서버를 만들었다.
여기서, 실제로 서비스를 하기 위해서 무엇을 더해야 할까?
https://blog.twitter.com/2011/finagle-a-protocol-agnostic-rpc-system
(공통적인?!) 필요한 기능
여러 서버가 각기 다른 Transport(HTTP/JSON,gRPC,Thirft,Protobuf)을 사용하더라도, 비슷
한 기능이 필요하다
운영중인 서버의 상태를 모니터링하고 싶다.
-packagelog
-packagemetric
-packagetracing
다른 서버/서비스에 접속하기 위해,접속 가능한 접속 정보를 알거나 알려주어야 한다.
-servicediscovery
-packageloadbalancer
네트웍 요청에 대한 제한을 주는 등으로 가능한 안정성을 부여하고 싶다.
-packageratelimit
-packagecircuitbreaker
기타 등등
Go kit : a distributed programming toolkit
http://www.gophercon.com/talks/go-kit/
package endpoint
//Endpointisthefundamentalbuildingblockofserversandclients.
//ItrepresentsasingleRPCmethod.
typeEndpointfunc(ctxcontext.Context,requestinterface{})(responseinterface{},errerror)
//Middlewareisachainablebehaviormodifierforendpoints.
typeMiddlewarefunc(Endpoint)Endpoint
Endpoint은 하나의 RPC 메소드를 나타낸다
Gokit의 가장 기본적인 인터페이스
Middleware : Endpoint을 받아서 Endpoint을 반환하는 함수로 Endpoint의 기능을 확장
한다.
-ratelimit
-tracing
-circuitbreaker
-loadbalancer
-...
StringService
typeStringServiceinterface{
Uppercase(string)(string,error)
Count(string)int
}
typestringServicestruct{}
func(stringService)Uppercase(sstring)(string,error){
ifs==""{
return"",ErrEmpty
}
returnstrings.ToUpper(s),nil
}
func(stringService)Count(sstring)int{
returnlen(s)
}
StringService인터페이스로 비지니스 모델을 정의한다.
Request와 Response
typeUppercaseRequeststruct{
Sstring`json:"s"`
}
typeUppercaseResponsestruct{
V string`json:"v"`
Errerror `json:"err"`
}
typeCountRequeststruct{
Sstring`json:"s"`
}
typeCountResponsestruct{
Vint`json:"v"`
}
StringService의 RPC메소드의 요청( Request)와 응답( Response)을 struct으로
구성
Endpoint
typeEndpointfunc(ctxcontext.Context,requestinterface{})(responseinterface{},errerror)
funcmakeUppercaseEndpoint(svcStringService)endpoint.Endpoint{
returnfunc(ctxcontext.Context,requestinterface{})(interface{},error){
req:=request.(UppercaseRequest)
v,err:=svc.Uppercase(req.S)
returnUppercaseResponse{v,err},nil
}
}
funcmakeCountEndpoint(svcStringService)endpoint.Endpoint{
returnfunc(ctxcontext.Context,requestinterface{})(interface{},error){
req:=request.(CountRequest)
v:=svc.Count(req.S)
returnCountResponse{v},nil
}
}
Transport
//NetRpc'shandler
typeNetRpcBindingstruct{
Context context.Context
uppercaseEndpointendpoint.Endpoint
countEndpoint endpoint.Endpoint
}
Endpoint을 RPC라이브러리(net/rpc,grpc,thrift,...)에 필요한 형태로 사용할수 있도록
HTTP의 경우, github.com/go-kit/kit/transport/http에 helper struct가 있다
uppercaseHandler:=httptransport.Server{
Context: ctx,
Endpoint: makeUppercaseEndpoint(svc),
DecodeFunc:decodeUppercaseRequest,
EncodeFunc:encodeResponse,
}
countHandler:=httptransport.Server{
Context: ctx,
Endpoint: makeCountEndpoint(svc),
DecodeFunc:decodeCountRequest,
EncodeFunc:encodeResponse,
}
context.Context
http://blog.golang.org/context
typeContextinterface{
Done()<-chanstruct{} //closedwhenthisContextiscanceled
Err()error //whythisContextwascanceled
Deadline()(deadlinetime.Time,okbool)//whenthisContextwillbecanceled
Value(keyinterface{})interface{} //dataassociatedwiththisContext
}
Context들은 계층구조를 가진다 (상위 Context의 value가 파생된 Context에게 전달된다)
typeCancelFunc
typeContext
funcBackground()Context
funcTODO()Context
funcWithCancel(parentContext)(ctxContext,cancelCancelFunc)
funcWithDeadline(parentContext,deadlinetime.Time)(Context,CancelFunc)
funcWithTimeout(parentContext,timeouttime.Duration)(Context,CancelFunc)
funcWithValue(parentContext,keyinterface{},valinterface{})Context
func(nNetRpcBinding)Uppercase(reqUppercaseRequest,res*UppercaseResponse)error{
ctx,cancel:=context.WithCancel(n.Context)
defercancel()
responses:=make(chanUppercaseResponse,1)
errs:=make(chanerror,1)
gofunc(){
resp,err:=n.uppercaseEndpoint(ctx,req)
iferr!=nil{
errs<-err
return
}
responses<-resp.(UppercaseResponse)
}()
select{
case<-ctx.Done():
returncontext.DeadlineExceeded
caseerr:=<-errs:
returnerr
caseresp:=<-responses:
(*res)=resp
returnnil
}
}
func(nNetRpcBinding)Count(reqCountRequest,res*CountResponse)error{
ctx,cancel:=context.WithCancel(n.Context)
defercancel()
responses:=make(chanCountResponse,1)
errs:=make(chanerror,1)
gofunc(){
resp,err:=n.countEndpoint(ctx,req)
iferr!=nil{
errs<-err
return
}
responses<-resp.(CountResponse)
}()
select{
case<-ctx.Done():
returncontext.DeadlineExceeded
caseerr:=<-errs:
returnerr
caseresp:=<-responses:
(*res)=resp
returnnil
}
}
Main
funcmain(){
ctx:=context.Background()
svc:=stringService{}
netRpcBinding:=NetRpcBinding{ctx,makeUppercaseEndpoint(svc),makeCountEndpoint(svc)}
s:=rpc.NewServer()
s.RegisterName("stringsvc",netRpcBinding)
s.HandleHTTP(rpc.DefaultRPCPath,rpc.DefaultDebugPath)
gofunc(){
err:=http.ListenAndServe(":8080",s)
iferr!=nil{
log.Fatal(err)
}
}()
time.Sleep(1*time.Second)
client,_:=rpc.DialHTTP("tcp","localhost:8080")//sorryforignoretheerror
clientEndpoint:=NewNetRpcClient(client)
req:=UppercaseRequest{S:"gokit!"}
res,err:=clientEndpoint(ctx,req)
log.Println("res:",res.(UppercaseResponse).V,"err:",err)
} Run
Client
funcNewNetRpcClient(c*rpc.Client)endpoint.Endpoint{
returnfunc(ctxcontext.Context,requestinterface{})(interface{},error){
errs:=make(chanerror,1)
responses:=make(chaninterface{},1)
gofunc(){
varresponseUppercaseResponse
iferr:=c.Call("stringsvc.Uppercase",request,&response);err!=nil{
errs<-err
return
}
responses<-response
}()
select{
case<-ctx.Done():
returnnil,context.DeadlineExceeded
caseerr:=<-errs:
returnnil,err
caseresp:=<-responses:
returnresp,nil
}
}
}
Client도 역시...
Example: LRU Cache Endpoint
typeCacheKeyFuncfunc(requestinterface{})(interface{},bool)
funcNewLRUCache(cache*lru.Cache,cacheKeyCacheKeyFunc)endpoint.Middleware{
returnfunc(nextendpoint.Endpoint)endpoint.Endpoint{
returnfunc(ctxcontext.Context,requestinterface{})(interface{},error){
key,ok:=cacheKey(request)
if!ok{
returnnext(ctx,request)
}
val,ok:=cache.Get(key)
ifok{
fmt.Println("Returnfromcache",request,val)
returnval,nil
}
val,err:=next(ctx,request)
iferr==nil{
cache.Add(key,val)
}
fmt.Println("Returnfromendpoint",request,val)
returnval,err
}
}
} Run
cacheKeyFunc:=func(requestinterface{})(interface{},bool){
ifreq,ok:=request.(UppercaseRequest);ok{
returnreq.S,true
}
returnnil,false
}
cache,_:=lru.New(10)
e:=makeUppercaseEndpoint(svc)
e=NewLRUCache(cache,cacheKeyFunc)(e)
req:=UppercaseRequest{"gophercon!"}
resp,err:=e(context.Background(),req)
fmt.Println("resp",resp.(UppercaseResponse).V,"err",err)
resp,err=e(context.Background(),req)
fmt.Println("resp",resp.(UppercaseResponse).V,"err",err)
package logging
funclogging(loggerlog.Logger)endpoint.Middleware{
returnfunc(nextendpoint.Endpoint)endpoint.Endpoint{
returnfunc(ctxcontext.Context,requestinterface{})(interface{},error){
logger.Log("msg","callingendpoint")
deferlogger.Log("msg","calledendpoint")
returnnext(ctx,request)
}
}
}
varloggerlog.Logger
logger=log.NewLogfmtLogger(os.Stderr)
logger=log.NewContext(logger).With("ts",log.DefaultTimestampUTC)
uppercase:=makeUppercaseEndpoint(svc)
count:=makeCountEndpoint(svc)
uppercase=logging(log.NewContext(logger).With("method","uppercase"))(uppercase)
count=logging(log.NewContext(logger).With("method","count"))(count)
//net/rpc
netRpcBinding:=NetRpcBinding{ctx,uppercase,count} Run
package metric
counters, gauges, histograms에 대한 공통적인 인터페이스를 제공
expvar, statsd, prometheus에 대한 어댑터 제공
requests:=metrics.NewMultiCounter(
expvar.NewCounter("requests"),
statsd.NewCounter(ioutil.Discard,"requests_total",time.Second),
prometheus.NewCounter(stdprometheus.CounterOpts{
Namespace:"addsvc",
Subsystem:"add",
Name: "requests_total",
Help: "Totalnumberofreceivedrequests.",
},[]string{}),
)
funcmetric(requestsmetrics.Counter)endpoint.Middleware{
returnfunc(nextendpoint.Endpoint)endpoint.Endpoint{
returnfunc(ctxcontext.Context,requestinterface{})(interface{},error){
requests.Add(1)
returnnext(ctx,request)
}
}
}
package ratelimit
//NewTokenBucketLimiterreturnsanendpoint.Middlewarethatactsasarate
//limiterbasedonatoken-bucketalgorithm.Requeststhatwouldexceedthe
//maximumrequestratearesimplyrejectedwithanerror.
funcNewTokenBucketLimiter(tb*ratelimit.Bucket)endpoint.Middleware{
returnfunc(nextendpoint.Endpoint)endpoint.Endpoint{
returnfunc(ctxcontext.Context,requestinterface{})(interface{},error){
iftb.TakeAvailable(1)==0{
returnnil,ErrLimited
}
returnnext(ctx,request)
}
}
}
github.com/juju/ratelimit
e=makeUppercaseEndpoint(svc)
e=ratelimit.NewTokenBucketThrottler(jujuratelimit.NewBucketWithRate(1,1),s)(e)
package circuitbreaker
funcHandyBreaker(cbbreaker.Breaker)endpoint.Middleware{
returnfunc(nextendpoint.Endpoint)endpoint.Endpoint{
returnfunc(ctxcontext.Context,requestinterface{})(responseinterface{},errerror)
{
if!cb.Allow(){
returnnil,breaker.ErrCircuitOpen
}
deferfunc(begintime.Time){
iferr==nil{
cb.Success(time.Since(begin))
}else{
cb.Failure(time.Since(begin))
}
}(time.Now())
response,err=next(ctx,request)
return
}
}
}
http://martinfowler.com/bliki/CircuitBreaker.html
package loadbalancer
import(
"github.com/go-kit/kit/loadbalancer"
"github.com/go-kit/kit/loadbalancer/dnssrv"
)
funcmain(){
//Constructaloadbalancerforfoosvc,whichgetsfoosvcinstancesby
//pollingaspecificDNSSRVname.
p:=dnssrv.NewPublisher("foosvc.internal.domain",5*time.Second,fooFactory,logger)
lb:=loadbalancer.NewRoundRobin(p)
//Getanewendpointfromtheloadbalancer.
endpoint,err:=lb.Endpoint()
iferr!=nil{
panic(err)
}
//Usetheendpointtomakearequest.
response,err:=endpoint(ctx,request)
}
funcfooFactory(instancestring)(endpoint.Endpoint,error){
//Convertaninstance(host:port)toanendpoint,viaadefinedtransportbinding.
}
funcmain(){
p:=dnssrv.NewPublisher("foosvc.internal.domain",5*time.Second,fooFactory,logger)
lb:=loadbalancer.NewRoundRobin(p)
endpoint:=loadbalancer.Retry(3,5*time.Seconds,lb)
response,err:=endpoint(ctx,request)//requestswillbeautomaticallyloadbalanced
}
현재 dnssrv와 static지원
consul, etcd, zookeeper등 지원 예정
package tracing
funcAnnotateServer(newSpanNewSpanFunc,cCollector)endpoint.Middleware{
returnfunc(nextendpoint.Endpoint)endpoint.Endpoint{
returnfunc(ctxcontext.Context,requestinterface{})(interface{},error){
span,ok:=fromContext(ctx)
if!ok{
span=newSpan(newID(),newID(),0)
ctx=context.WithValue(ctx,SpanContextKey,span)
}
span.Annotate(ServerReceive)
deferfunc(){span.Annotate(ServerSend);c.Collect(span)}()
returnnext(ctx,request)
}
}
}
//Server-side
varserverendpoint.Endpoint
server=makeEndpoint()//foryourservice
server=zipkin.AnnotateServer(spanFunc,collector)(server)
goserveViaHTTP(server)
Appdash은 계획중
https://blog.twitter.com/2012/distributed-systems-tracing-with-zipkin
Thank you
anarcher
anarcher@gmail.com(mailto:anarcher@gmail.com)
Gokit

Weitere ähnliche Inhalte

Was ist angesagt?

TDD Boot Camp 東京 for C++ 進行
TDD Boot Camp 東京 for C++ 進行TDD Boot Camp 東京 for C++ 進行
TDD Boot Camp 東京 for C++ 進行
Takashi Imagire
 

Was ist angesagt? (20)

Beginning direct3d gameprogrammingcpp02_20160324_jintaeks
Beginning direct3d gameprogrammingcpp02_20160324_jintaeksBeginning direct3d gameprogrammingcpp02_20160324_jintaeks
Beginning direct3d gameprogrammingcpp02_20160324_jintaeks
 
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTRT3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
 
The Gradle in Ratpack: Dissected
The Gradle in Ratpack: DissectedThe Gradle in Ratpack: Dissected
The Gradle in Ratpack: Dissected
 
The Ring programming language version 1.9 book - Part 111 of 210
The Ring programming language version 1.9 book - Part 111 of 210The Ring programming language version 1.9 book - Part 111 of 210
The Ring programming language version 1.9 book - Part 111 of 210
 
Functional, Type-safe, Testable Microservices with ZIO and gRPC
Functional, Type-safe, Testable Microservices with ZIO and gRPCFunctional, Type-safe, Testable Microservices with ZIO and gRPC
Functional, Type-safe, Testable Microservices with ZIO and gRPC
 
HDTR images with Photoshop Javascript Scripting
HDTR images with Photoshop Javascript ScriptingHDTR images with Photoshop Javascript Scripting
HDTR images with Photoshop Javascript Scripting
 
TDD Boot Camp 東京 for C++ 進行
TDD Boot Camp 東京 for C++ 進行TDD Boot Camp 東京 for C++ 進行
TDD Boot Camp 東京 for C++ 進行
 
The Ring programming language version 1.7 book - Part 75 of 196
The Ring programming language version 1.7 book - Part 75 of 196The Ring programming language version 1.7 book - Part 75 of 196
The Ring programming language version 1.7 book - Part 75 of 196
 
Qt Widget In-Depth
Qt Widget In-DepthQt Widget In-Depth
Qt Widget In-Depth
 
Testing multi outputformat based mapreduce
Testing multi outputformat based mapreduceTesting multi outputformat based mapreduce
Testing multi outputformat based mapreduce
 
Tim Panton - Presentation at Emerging Communications Conference & Awards (eCo...
Tim Panton - Presentation at Emerging Communications Conference & Awards (eCo...Tim Panton - Presentation at Emerging Communications Conference & Awards (eCo...
Tim Panton - Presentation at Emerging Communications Conference & Awards (eCo...
 
The Ring programming language version 1.8 book - Part 77 of 202
The Ring programming language version 1.8 book - Part 77 of 202The Ring programming language version 1.8 book - Part 77 of 202
The Ring programming language version 1.8 book - Part 77 of 202
 
Asynchronní programování
Asynchronní programováníAsynchronní programování
Asynchronní programování
 
Javascript compilation execution
Javascript compilation executionJavascript compilation execution
Javascript compilation execution
 
«Продакшн в Kotlin DSL» Сергей Рыбалкин
«Продакшн в Kotlin DSL» Сергей Рыбалкин«Продакшн в Kotlin DSL» Сергей Рыбалкин
«Продакшн в Kotlin DSL» Сергей Рыбалкин
 
The Ring programming language version 1.5.4 book - Part 81 of 185
The Ring programming language version 1.5.4 book - Part 81 of 185The Ring programming language version 1.5.4 book - Part 81 of 185
The Ring programming language version 1.5.4 book - Part 81 of 185
 
The Ring programming language version 1.9 book - Part 108 of 210
The Ring programming language version 1.9 book - Part 108 of 210The Ring programming language version 1.9 book - Part 108 of 210
The Ring programming language version 1.9 book - Part 108 of 210
 
Smart Contract samples
Smart Contract samplesSmart Contract samples
Smart Contract samples
 
Exactly Once Semantics Revisited (Jason Gustafson, Confluent) Kafka Summit NY...
Exactly Once Semantics Revisited (Jason Gustafson, Confluent) Kafka Summit NY...Exactly Once Semantics Revisited (Jason Gustafson, Confluent) Kafka Summit NY...
Exactly Once Semantics Revisited (Jason Gustafson, Confluent) Kafka Summit NY...
 
PVS-Studio in 2019
PVS-Studio in 2019PVS-Studio in 2019
PVS-Studio in 2019
 

Ähnlich wie Gokit

Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
ShriKant Vashishtha
 
Java web programming
Java web programmingJava web programming
Java web programming
Ching Yi Chan
 

Ähnlich wie Gokit (20)

gRPC in Go
gRPC in GogRPC in Go
gRPC in Go
 
用 Go 語言打造多台機器 Scale 架構
用 Go 語言打造多台機器 Scale 架構用 Go 語言打造多台機器 Scale 架構
用 Go 語言打造多台機器 Scale 架構
 
SignalR
SignalRSignalR
SignalR
 
Protobuf & Code Generation + Go-Kit
Protobuf & Code Generation + Go-KitProtobuf & Code Generation + Go-Kit
Protobuf & Code Generation + Go-Kit
 
Building RESTful Services With Go and MongoDB
Building RESTful Services With Go and MongoDBBuilding RESTful Services With Go and MongoDB
Building RESTful Services With Go and MongoDB
 
GWT training session 3
GWT training session 3GWT training session 3
GWT training session 3
 
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
 
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
 
Gwt RPC
Gwt RPCGwt RPC
Gwt RPC
 
Microservices Communication Patterns with gRPC
Microservices Communication Patterns with gRPCMicroservices Communication Patterns with gRPC
Microservices Communication Patterns with gRPC
 
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
 
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
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
 
Android Libs - Retrofit
Android Libs - RetrofitAndroid Libs - Retrofit
Android Libs - Retrofit
 
Driving containerd operations with gRPC
Driving containerd operations with gRPCDriving containerd operations with gRPC
Driving containerd operations with gRPC
 
202107 - Orion introduction - COSCUP
202107 - Orion introduction - COSCUP202107 - Orion introduction - COSCUP
202107 - Orion introduction - COSCUP
 
WCF - In a Week
WCF - In a WeekWCF - In a Week
WCF - In a Week
 
Java web programming
Java web programmingJava web programming
Java web programming
 
twMVC#46 一探 C# 11 與 .NET 7 的神奇
twMVC#46 一探 C# 11 與 .NET 7 的神奇twMVC#46 一探 C# 11 與 .NET 7 的神奇
twMVC#46 一探 C# 11 與 .NET 7 的神奇
 

Kürzlich hochgeladen

Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Christo Ananth
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Christo Ananth
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
rknatarajan
 
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 

Kürzlich hochgeladen (20)

chapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineeringchapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineering
 
Double rodded leveling 1 pdf activity 01
Double rodded leveling 1 pdf activity 01Double rodded leveling 1 pdf activity 01
Double rodded leveling 1 pdf activity 01
 
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
 
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
 
PVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELL
PVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELLPVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELL
PVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELL
 
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 for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
 
Unit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdfUnit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdf
 
(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7
(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7
(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7
 
Thermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VThermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - V
 
(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7
(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7
(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
 
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
 
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...
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
 
NFPA 5000 2024 standard .
NFPA 5000 2024 standard                                  .NFPA 5000 2024 standard                                  .
NFPA 5000 2024 standard .
 
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghly
 

Gokit