github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/node/service.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 //</624450102638940160> 11 12 13 package node 14 15 import ( 16 "reflect" 17 18 "github.com/ethereum/go-ethereum/accounts" 19 "github.com/ethereum/go-ethereum/ethdb" 20 "github.com/ethereum/go-ethereum/event" 21 "github.com/ethereum/go-ethereum/p2p" 22 "github.com/ethereum/go-ethereum/rpc" 23 ) 24 25 //ServiceContext是从继承的与服务无关的选项的集合 26 //协议栈,它被传递给所有的构造器以供选择使用; 27 //以及在服务环境中操作的实用方法。 28 type ServiceContext struct { 29 config *Config 30 services map[reflect.Type]Service //已建服务索引 31 EventMux *event.TypeMux //用于分离通知的事件多路复用器 32 AccountManager *accounts.Manager //节点创建的客户经理。 33 } 34 35 //opendatabase打开具有给定名称的现有数据库(或创建一个 36 //如果在节点的数据目录中找不到上一个)。如果 37 //节点是短暂的,返回内存数据库。 38 func (ctx *ServiceContext) OpenDatabase(name string, cache int, handles int) (ethdb.Database, error) { 39 if ctx.config.DataDir == "" { 40 return ethdb.NewMemDatabase(), nil 41 } 42 db, err := ethdb.NewLDBDatabase(ctx.config.ResolvePath(name), cache, handles) 43 if err != nil { 44 return nil, err 45 } 46 return db, nil 47 } 48 49 //resolvepath将用户路径解析为数据目录(如果该路径是相对的) 50 //如果用户实际使用持久存储。它将返回空字符串 51 //对于临时存储和用户自己的绝对路径输入。 52 func (ctx *ServiceContext) ResolvePath(path string) string { 53 return ctx.config.ResolvePath(path) 54 } 55 56 //服务检索当前正在运行的特定类型的注册服务。 57 func (ctx *ServiceContext) Service(service interface{}) error { 58 element := reflect.ValueOf(service).Elem() 59 if running, ok := ctx.services[element.Type()]; ok { 60 element.Set(reflect.ValueOf(running)) 61 return nil 62 } 63 return ErrServiceUnknown 64 } 65 66 //ServiceConstructor是需要 67 //已注册服务实例化。 68 type ServiceConstructor func(ctx *ServiceContext) (Service, error) 69 70 //服务是可以注册到节点中的单个协议。 71 // 72 //笔记: 73 // 74 //•将服务生命周期管理委托给节点。允许服务 75 //创建时初始化自身,但不应在 76 //启动方法。 77 // 78 //•不需要重新启动逻辑,因为节点将创建新实例 79 //每次启动服务时。 80 type Service interface { 81 //协议检索服务希望启动的P2P协议。 82 Protocols() []p2p.Protocol 83 84 //API检索服务提供的RPC描述符列表 85 APIs() []rpc.API 86 87 //在构建所有服务和网络之后调用Start 88 //层也被初始化以生成服务所需的任何goroutine。 89 Start(server *p2p.Server) error 90 91 //stop终止属于服务的所有goroutine,阻塞直到它们 92 //全部终止。 93 Stop() error 94 } 95