尝试构建简易 Event Bus

April 12, 2019
Go

开一个坑在这儿,慢慢把遇到的问题和一些解决方案都扔这儿吧。

毕设这个玩意儿,说起来和我想的还是有点区别。

本以为至少也是什么研究性的内容,但是这个应该是算工程类吧。到时候还得头疼怎么写论文嘞。

相关的东西要学的不少。比如了解 Go 对Routine的管理 The Go scheduler,以及官方的 Effective Go 又或者是针对Routine的 M:N 模型中的 How Stacks are Handled in GoContiguous stacks 等等等等。。。不过时间上好像来不及了,目前最重要的还是能把这玩意跑起来。

Event Driven

事件驱动 算是比较常见的一种编程模型吧。常见的有 Nginx 之类的,都是用的这种模型写出来的。多的废话也不扯了,网上一搜一大把。

毕设这个课题,校外导师原本的东西是由 Python 写的,嗯,这里也不是说 Python 不好,不过当初毕竟还是想试水一下 Go,于是就打算用 Go 来实现一遍,反正只要文档到位,他们日后重构的时候也不会很麻烦。

事件驱动的架构借鉴了 medium 上的这篇文章(利用channel实现 callback),至于为了实现对不确定数目的 channelselect 操作,在参考了 Stackoverflow 上的这篇以及这篇之后,暂定选择使用 reflect 中的 select函数来实现。不过目前还未尝试。

目前采用了先 launch 对应的Routine,然后再向channel送数据。不过这样好像不如直接把channel换成 interface 得了。暂时观望,后期有问题再改吧。。。

这样带来的问题,便是在 main 函数退出时,其余的Routine也会被 Terminated。这就要用到 sync.WaitGroup

直接用reflect.Value传 interface 了,不用再单独开一个循环。

HTTP, Async, Non-Blocking

个人随笔网站 中写过一篇针对 NodeJs 创始人 Ryan 访谈的小小感想

其中提到了,Go 这种类似 Green Thread 的策略,以及在面向编程者的 Blocking 模式。以及在 Stackoverflow 上的一篇回答。以及

When a Go program executes what looks like a blocking I/O operation, the Go runtime actually suspends the goroutine and resumes it when an event indicates that some result is available. In the meantime other goroutines have been scheduled for execution. We therefore have the scalability benefits of asynchronous programming with a synchronous programming model.

然后就是 net/http

这个库的思路是,写一个针对 Request 的 Handle,然后为该函数注册一个地址,在 Runtime 接收到新的 http 请求时,就会创建一个新的 Routine 并找到注册了对应 URL 的 Handle 来处理这个请求。

上述过程在 Runtime 层面上是异步的,非阻塞的,很遗憾,提供给你的接口是阻塞的。

这样,就没法实现利用 Event 的 Async 和 callback 处理了。

当然,网上也有 Go 的事件驱动库。其中的样例带了一个简易的 http 实现。根据我看代码的结论,以及初步的模仿实现,这个就是在 Transport Layer 上自己造了一个 http 的轮子。

以及在 Hacker News 上的讨论

What this does instead is give a Go program direct access to the event loop. The benefit is that it bypasses all of the stuff that Go wraps around the internal event loop call that allows it to implement the way it offers a thread-like interface for you, and integrates with the channel and concurrency primitives, and maintains your position in the call stack between events, etc. The penalty is… the exact same thing, that you lose all the nice stuff that the Go runtime offers to you to implement the thread-like interface, etc., and are back to a lower-level interface that offers less services.

emmmm,这批评的声音,让我不禁觉得是不是我本来路子就选错了。

不过网上各种项目满天飞,甚至重新造了个轮子的这种东西也不在少数。所以这大概并不是我当前层面所应该考虑的东西。如果犯错误就将错就错吧。

于是,仅仅使用 net 库,自己照着上面的 http 例子,以及 W3C 的文档,撸了个简单的 http 服务

跑通是没问题,但是想到今后的工作量,简直头大。

WebSocket

如果闷头开始造轮子的话,也就不会到这一部分了。

在尝试大量关键词后,我发现了一个第三方 websocket 项目

这样就可以简单地迎合我的需求了。

To Be Continued……..

Digging Into Go Routines

April 16, 2019
Go

Go's Slice Tricks

December 28, 2018
Go

Golang 的 GOPATH

November 25, 2018
Go
comments powered by Disqus.
Can't load? Check your connectivity and try again.