github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/node/utils_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:40</date> 10 //</624450102731214848> 11 12 13 //包含测试使用的一批实用程序类型声明。作为节点 14 //在独特的类型上操作,需要很多类型来检查各种特性。 15 16 package node 17 18 import ( 19 "reflect" 20 21 "github.com/ethereum/go-ethereum/p2p" 22 "github.com/ethereum/go-ethereum/rpc" 23 ) 24 25 //noopservice是服务接口的一个简单实现。 26 type NoopService struct{} 27 28 func (s *NoopService) Protocols() []p2p.Protocol { return nil } 29 func (s *NoopService) APIs() []rpc.API { return nil } 30 func (s *NoopService) Start(*p2p.Server) error { return nil } 31 func (s *NoopService) Stop() error { return nil } 32 33 func NewNoopService(*ServiceContext) (Service, error) { return new(NoopService), nil } 34 35 //一组服务都包装基NoopService,从而产生相同的方法 36 //签名,但外部类型不同。 37 type NoopServiceA struct{ NoopService } 38 type NoopServiceB struct{ NoopService } 39 type NoopServiceC struct{ NoopService } 40 41 func NewNoopServiceA(*ServiceContext) (Service, error) { return new(NoopServiceA), nil } 42 func NewNoopServiceB(*ServiceContext) (Service, error) { return new(NoopServiceB), nil } 43 func NewNoopServiceC(*ServiceContext) (Service, error) { return new(NoopServiceC), nil } 44 45 //instructedService是一种服务的实现,所有接口 46 //方法既可以检测返回值,也可以检测事件挂钩。 47 type InstrumentedService struct { 48 protocols []p2p.Protocol 49 apis []rpc.API 50 start error 51 stop error 52 53 protocolsHook func() 54 startHook func(*p2p.Server) 55 stopHook func() 56 } 57 58 func NewInstrumentedService(*ServiceContext) (Service, error) { return new(InstrumentedService), nil } 59 60 func (s *InstrumentedService) Protocols() []p2p.Protocol { 61 if s.protocolsHook != nil { 62 s.protocolsHook() 63 } 64 return s.protocols 65 } 66 67 func (s *InstrumentedService) APIs() []rpc.API { 68 return s.apis 69 } 70 71 func (s *InstrumentedService) Start(server *p2p.Server) error { 72 if s.startHook != nil { 73 s.startHook(server) 74 } 75 return s.start 76 } 77 78 func (s *InstrumentedService) Stop() error { 79 if s.stopHook != nil { 80 s.stopHook() 81 } 82 return s.stop 83 } 84 85 //instructingwrapper是一种专门化返回的服务构造函数的方法 86 //将通用的检测服务转换为返回包装特定服务的服务。 87 type InstrumentingWrapper func(base ServiceConstructor) ServiceConstructor 88 89 func InstrumentingWrapperMaker(base ServiceConstructor, kind reflect.Type) ServiceConstructor { 90 return func(ctx *ServiceContext) (Service, error) { 91 obj, err := base(ctx) 92 if err != nil { 93 return nil, err 94 } 95 wrapper := reflect.New(kind) 96 wrapper.Elem().Field(0).Set(reflect.ValueOf(obj).Elem()) 97 98 return wrapper.Interface().(Service), nil 99 } 100 } 101 102 //一组服务,所有这些服务都包装基本的instructedService,导致 103 //方法签名相同,但外部类型不同。 104 type InstrumentedServiceA struct{ InstrumentedService } 105 type InstrumentedServiceB struct{ InstrumentedService } 106 type InstrumentedServiceC struct{ InstrumentedService } 107 108 func InstrumentedServiceMakerA(base ServiceConstructor) ServiceConstructor { 109 return InstrumentingWrapperMaker(base, reflect.TypeOf(InstrumentedServiceA{})) 110 } 111 112 func InstrumentedServiceMakerB(base ServiceConstructor) ServiceConstructor { 113 return InstrumentingWrapperMaker(base, reflect.TypeOf(InstrumentedServiceB{})) 114 } 115 116 func InstrumentedServiceMakerC(base ServiceConstructor) ServiceConstructor { 117 return InstrumentingWrapperMaker(base, reflect.TypeOf(InstrumentedServiceC{})) 118 } 119 120 //OneMethodAPI是测试服务返回的单个方法API处理程序。 121 type OneMethodAPI struct { 122 fun func() 123 } 124 125 func (api *OneMethodAPI) TheOneMethod() { 126 if api.fun != nil { 127 api.fun() 128 } 129 } 130