前言
之前的一篇文章介绍了openedge-function模块(下面简称function模块)进行初始化的部分,下面整体过一下启动一个函数的流程。
接收到消息
之前介绍过,ruler是整个function模块的核心,其负责进行接收启动函数的命令以及向master模块请求启动模块,并将函数运行后的结果发送至hub模块中。
下面看一下接收到消息的代码:
func (rr *ruler) start() error {
rr.fd.SetCallback(func(pkt *packet.Publish) {
···
if pkt.Message.Payload != nil {
···
err := rr.md.Send(pkt)
···
}
···
})
h := mqtt.Handler{}
h.ProcessPublish = func(p *packet.Publish) error {
return rr.fd.Invoke(p)
}
···
return rr.md.Start(h)
}
里面由两个重要点,一个是callback方法,另一个是ProcessPublish方法。其中,ProcessPublish就是接收到Publish的消息后的处理方法,我们接着看rr.fd.Invoke(p)
方法:(fd我们就暂时称为Function Dispatcher好了)
// Invoke invokes a function
func (d *Dispatcher) Invoke(pkt *packet.Publish) error {
select {
case d.buffer <- struct{}{}:
case <-d.tomb.Dying():
return ErrDispatcherClosed
}
go func(pub *packet.Publish) {
msg := &runtime.Message{
QOS: uint32(pub.Message.QOS),
Topic: pub.Message.Topic,
Payload: pub.Message.Payload,
}
msg, err := d.function.Invoke(msg)
if err != nil {
pub.Message.Payload = utils.MakeErrorPayload(pub, err)
} else {
pub.Message.Payload = msg.Payload
}
if d.callback != nil {
d.callback(pub)
}
<-d.buffer
}(pkt)
return nil
}
首先其使用function.Invoke(msg)方法,然后调用了callback方法,这个callback是函数模块执行完毕后返回的值,在讲返回的时候再讲这里。下面看看function.Invoke(msg)方法:
// Invoke call funtion to handle message and return result message
func (f *Function) Invoke(msg *runtime.Message) (*runtime.Message, error) {
item, err := f.pool.BorrowObject(context.Background())
···
fl := item.(*funclet)
res, err := fl.handle(msg)
···
f.pool.ReturnObject(context.Background(), item)
return res, nil
}
</