- 上一篇文章站在vdsmd对外提供服务的角度讨论了vdsm接口。本篇文章站在客户端(vdsm-client)的角度
讨论对vdsm接口的调用。
2. 涉及的代码主要有
/usr/lib/python3.6/site-packages/yajsonrpc/__init__.py
/usr/lib/python3.6/site-packages/yajsonrpc/betterAsyncore.py
/usr/lib/python3.6/site-packages/yajsonrpc/exception.py
/usr/lib/python3.6/site-packages/yajsonrpc/stomp.py
/usr/lib/python3.6/site-packages/yajsonrpc/stompclient.py
/usr/lib/python3.6/site-packages/yajsonrpc/stompserver.py
/usr/lib/python3.6/site-packages/yajsonrpc/jsonrpcclient.py
上述代码来自 vdsm-yajsonrpc-4.40.40-1.el8.noarch,注意并不在vdsm的目录中。
上述代码是有逻辑层次的。其中最底层的是betterAsyncore.py它封装了epoll(或者select,poll,关键在于参数的选择,为了叙述方便,后面一直会说成epoll)。相关背景知识请一定阅读参考文献。
中间层次是在epoll之上的stomp协议实现,其中stomp.py提供了协议公共的部分。stompclient.py提供了客户端的实现代码。stompserver.py提供了端的代码实现。
逻辑最上层的是jsonrpc协议实现。它的实现是架构在stomp协议之上的。其中jsonrpcclient.py提供了客户端的实现,__init__.py提供了server端的实现。 所以基本的数据流是这样的
/usr/lib/python3.6/site-packages/vdsmclient/client.py
/usr/lib/python3.6/site-packages/vdsm/client.py
其中vdsm-client命令的入口是vdsmclient/client.py ,进一步的调用是vdsm/client.py。
jsonrpc, stomp, epoll之间的关系,类似传输层–>ip层–>arp层的关系。
3. 我们关注一些代码细节
- vdsmclient/client.py 做了2件事情。
其一是通过vdsm-api.yml来获取命令行的相关参数,说明以及接口细节,具体是通过vdsmapi实现的。
另一个便是调用vdsm/client.py, 并获取返回值,提供给调用者。
- 我们进入vdsm/client.py
可以看到def connect ()函数。它首先创建一个
client = stompclient.SimpleClient,然后使用这个client 创建并返回一个_Client类。而这个类中,通过
_create_namespaces函数,设置namespace,method的属性。与此对应,如上图片所示,当vdsmclient/client.py获取对应属性并且调用时候(command = getattr….),将调用到_Client类的_call函数,此函数将创建jsonrpc的request,并且通过stomplcient发送出去。从而完成客户端的调用。
- 关注dispatch这个角色。
yajsonrpc出现了很多dispatch。dispatch最初是asyncore针对socket的一个抽象(betterAsyncore.py)。在此代码逻辑中,stomp在此基础上完成一个AsyncoreDispatch抽象(stomp.py)。后续所有基于stomp协议的操作,都是基于这个AsyncoreDispatch抽象的再次实现。例如客户端实现了一个AsyncClient ,服务端实现了一个StompAdapterImpl 。通过这些dispatcher将整个协议的收发串联了起来。
- jsonclient是通过一个适配器完成了对stompclient的调用。细节参考stompclient.py。
参考文献
asyncore
https://www.cnblogs.com/doudouyoutang/p/4541369.html
eventfs
https://eventfd.readthedocs.io/en/latest/
STOMP