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会循环等待该

Go语言是谷歌推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发Go,是因为过去10多年间软件开发的难度令人沮丧。

Go是谷歌2009发布的第二款编程语言。2009年7月份,谷歌曾发布了Simple语言,它是用来开发Android应用的一种BASIC语言.

北京时间2010年1月10日,Go语言摘得了TIOBE公布的2009年年度大奖。该奖项授予在2009年市场份额增长最多的编程语言。

谷歌资深软件工程师罗布·派克(Rob Pike)表示,"Go让我体验到了从未有过的开发效率。"派克表示,今天的C++或C一样,Go是一种系统语言。他解释道,"使用它可以进行快速开发,同时它还是一个真正的编译语言,我们之所以现在将其开源,原因是我们认为它已经非常有用和强大。"

2007年,谷歌把Go作为一个20%项目开始研发,即让员工抽出本职工作之外时间的20%, 投入在该项目上。除了派克外,该项目的成员还有其他谷歌工程师也参与研发。

派克表示,编译后Go代码的运行速度与C语言非常接近,而且编译速度非常快,就像在使用一个交互式语言。现有编程语言均未专门对多核处理器进行优化。Go就是谷歌工程师为这类程序编写的一种语言。它不是针对编程初学者设计的,但学习使用它也不是非常困难。Go支持面向对象,而且具有真正的闭包(closures)和反射 (reflection)等功能。

在学习曲线方面,派克认为Go与Java类似,对于Java开发者来说,应该能够轻松学会 Go。之所以将Go作为一个开源项目发布,目的是让开源社区有机会创建更好的工具来使用该语言,例如 Eclipse IDE中的插件。

在谷歌公开发布的所有网络应用中,均没有使用Go,但是谷歌已经使用该语言开发了几个内部项目。派克表示,Go是否会对谷歌即将推出的Chrome OS产生影响,还言之尚早,不过Go的确可以和Native Client配合使用。他表示"Go可以让应用完美的运行在浏览器内。"例如,使用Go可以更高效的实现Wave,无论是在前端还是后台。

Go 同时具有两种编译器,一种是建立在GCC基础上的Gccgo,另外一种是分别针对64位x64和32位x86计算机的一套编译器(6g和8g)。谷歌目前正在研发其对ARM芯片和Android设备的支持。派克表示,"Android手机存在的问题是,我们一直没有一个数学协处理器。"