golang p2p网

Python013

golang p2p网,第1张

继续进入下一个初始化

n.netService, err = nebnet.NewNebService(n)

if err != nil {

logging.CLog().WithFields(logrus.Fields{

"err": err,

}).Fatal("Failed to setup net service.")

}

netservice有两个成员

type NebServicestruct {

node      *Node

dispatcher *Dispatcher

}

跳出stup()函数

先进入start()函数看一看

if err := n.netService.Start()err != nil {

logging.CLog().WithFields(logrus.Fields{

"err": err,

}).Fatal("Failed to start net service.")

}

进入netservice.start()

func (ns *NebService) Start() error {

logging.CLog().Info("Starting NebService...")

// start dispatcher.

  ns.dispatcher.Start()

// start node.

  if err := ns.node.Start()err != nil {

ns.dispatcher.Stop()

logging.CLog().WithFields(logrus.Fields{

"err": err,

}).Error("Failed to start NebService.")

return err

}

logging.CLog().Info("Started NebService.")

return nil

}

可以看到第一个start()的函数是dispatcher.start()

进入dispatch.start()

func (dp *Dispatcher) Start() {

logging.CLog().Info("Starting NebService Dispatcher...")

go dp.loop()

}

然后就出现一个新的线程、goruntime

go dp.loop()

进入该线程,看它干了些什么

timerChan := time.NewTicker(time.Second).C

for {

select {

case <-timerChan:

metricsDispatcherCached.Update(int64(len(dp.receivedMessageCh)))

case <-dp.quitCh:

logging.CLog().Info("Stoped NebService Dispatcher.")

return

  case msg := <-dp.receivedMessageCh:

msgType := msg.MessageType()

v, _ := dp.subscribersMap.Load(msgType)

if v == nil {

continue

      }

m, _ := v.(*sync.Map)

m.Range(func(key, valueinterface{}) bool {

select {

case key.(*Subscriber).msgChan <- msg:

default:

logging.VLog().WithFields(logrus.Fields{

"msgType": msgType,

}).Warn("timeout to dispatch message.")

}

return true

      })

}

}

一个有点长的循环

metricsDispatcherCached.Update(int64(len(dp.receivedMessageCh)))一秒钟刷新一次缓冲区

case msg := <-dp.receivedMessageCh:

msgType := msg.MessageType()如果能取出dp.receivedMessageCh

msgType := msg.MessageType()首先判断取出的信息类型

v, _ := dp.subscribersMap.Load(msgType)

if v == nil {

continue

}

根据类型取出相应的map

如果取不出,那么使用continue结束这个case

m, _ := v.(*sync.Map)

断言

m.Range(func(key, valueinterface{}) bool {

select {

case key.(*Subscriber).msgChan <- msg:

default:

logging.VLog().WithFields(logrus.Fields{

"msgType": msgType,

}).Warn("timeout to dispa+tch message.")

}

return true

})

将msg推入其他管道里面去。其他goruntime会循环等待该

当您对外部模块的存储库进行了 fork (例如修复模块代码中的问题或添加功能)时,您可以让 Go 工具将您的 fork 用于模块的源代码。这对于测试您自己的代码的更改很有用。

为此,您可以使用go.mod 文件中的replace指令将外部模块的原始模块路径替换为存储库中 fork 的路径。这指示 Go 工具在编译时使用替换路径(fork 的位置),例如,同时允许您保留import 原始模块路径中的语句不变。

在以下 go.mod 文件示例中,当前模块需要外部模块example.com/theirmodule。然后该replace指令将原始模块路径替换为example.com/myfork/theirmodule模块自己的存储库的分支。

设置require/replace对时,使用 Go 工具命令确保文件描述的需求保持一致。使用go list命令获取当前模块正在使用的版本。然后使用go mod edit命令将需要的模块替换为fork:

注意: 当您使用该replace指令时,Go 工具不会像添加依赖项中所述对外部模块进行身份验证。

您可以使用go get命令从其存储库中的特定提交为模块添加未发布的代码。

为此,您使用go get命令,用符号@指定您想要的代码 。当您使用go get时,该命令将向您的 go.mod 文件添加一个 需要外部模块的require指令,使用基于有关提交的详细信息的伪版本号。

以下示例提供了一些说明。这些基于源位于 git 存储库中的模块。

当您的代码不再使用模块中的任何包时,您可以停止将该模块作为依赖项进行跟踪。

要停止跟踪所有未使用的模块,请运行go mod tidy 命令。此命令还可能添加在模块中构建包所需的缺失依赖项。

要删除特定依赖项,请使用go get,指定模块的模块路径并附加 @none,如下例所示:

go get命令还将降级或删除依赖于已删除模块的其他依赖项。

当您使用 Go 工具处理模块时,这些工具默认从 proxy.golang.org(一个公共的 Google 运行的模块镜像)或直接从模块的存储库下载模块。您可以指定 Go 工具应该使用另一个代理服务器来下载和验证模块。

如果您(或您的团队)已经设置或选择了您想要使用的不同模块代理服务器,您可能想要这样做。例如,有些人设置了模块代理服务器,以便更好地控制依赖项的使用方式。

要为 Go 工具指定另一个模块代理服务器,请将GOPROXY 环境变量设置为一个或多个服务器的 URL。Go 工具将按照您指定的顺序尝试每个 URL。默认情况下,GOPROXY首先指定一个公共的 Google 运行模块代理,然后从模块的存储库直接下载(在其模块路径中指定):

您可以将变量设置为其他模块代理服务器的 URL,用逗号或管道分隔 URL。

Go 模块经常在公共互联网上不可用的版本控制服务器和模块代理上开发和分发。您可以设置 GOPRIVATE环境变量。您可以设置GOPRIVATE环境变量来配置go命令以从私有源下载和构建模块。然后 go 命令可以从私有源下载和构建模块。

GOPRIVATE或环境变量可以设置为匹配模块前缀的全局模式列表,这些GONOPROXY前缀是私有的,不应从任何代理请求。例如: