Problem:
In my project, I need to call erlang functions inside python to fulfil some concurrent computing tasks.
在我的项目中,我需要调用erlang方法在python实现一些并行计算任务。
Solution:
module implement the erlang nodes protocol and use python twisted network engine. Now, it is possible to call erlang nodes in python scripts.
Twotp模块实现了erlang节点协议和python Twisted 网络引擎的使用。现在,可以在python脚本中调用erlang节点。
I also found an example . Unfortunately, there are errors in the python sources codes when you make remote procedure call from twotp.NodeClientFactory. I followed the examples with the twotp source codes, and make the rpc from twotp.Process. This works.
在这里我还发现了一个例子。不幸的是从twotp.NodeClientFactory远程过程调用时,python源码中出现了错误。我遵循twotp源码,通过twotp.Process实现rpc协议。
Step 1: Setup erlang nodes.
第一步:安装erlang节点。
- %% Demo erlang program.
- %% Return hello message.
- -module(demo).
- -export([hello/1, ping/0, start/0]).
- %% Hello function, return hello message.
- hello(Name) ->
- Message = "Hello, " ++ Name,
- io:format(Message ++ "~n", []),
- Message.
- %% ping loop, return the ping count.
- ping_loop(N) ->
- receive
- {get_id, From} ->
- From ! {pong, N},
- ping_loop(N+1)
- end.
- %% ping function.
- ping() ->
- pingsrv ! {get_id, self()},
- receive
- {pong, N} -> ok
- end,
- {pong, N}.
- %% start the server.
- start() ->
- Pid = spawn_link(fun() -> ping_loop(1) end),
- register(pingsrv, Pid).
Run the erlang program on “test” node.
运行erlang程序在“测试”节点。
- $ erl -sname test@localhost
- (test@localhost)1> demo:start().
- true
Step 2: Make rpc call in python.
第二步:在python调用rpc
- #!/usr/bin/env python
- #-*- coding: utf-8 -*-
- #
- # BSD License
- # Copyright (c) 2011, Wang Qiang
- # All rights reserved.
- """
- Main python program.
- I will call erlang function here.
- """
- import sys
- import twotp
- from twisted.internet import reactor
- def error(e):
- """
- errback for twisted defered.
- """
- print 'Error:'
- print e
- reactor.stop()
- def do_pingpong(process, remote):
- """
- rpc for demo:ping.
- """
- def handle_pong(result):
- """
- callback for handling the demo:ping result.
- """
- text, id_ = result[0].text, result[1]
- print "Got ping result: %s %d" % (text, id_)
- reactor.callLater(1, do_pingpong, process, remote)
- # Make rpc with two.Process.callRemote.
- # call demo:ping() in remote node.
- d = process.callRemote(remote, 'demo', 'ping')
- d.addCallback(handle_pong)
- d.addErrback(error)
- def call_hello(process, remote, name):
- """
- rpc for demo:hello.
- """
- def handle_hello(result):
- """
- callback for handling the demo:hello result.
- """
- print "Got hello results", result
- text = ''.join(chr(c) for c in result).decode('latin1')
- print 'String form:', text
- do_pingpong(process, remote)
- # Make rpc with two.Process.callRemote.
- # call demo:hello() with name arg in remote node.
- d = process.callRemote(remote, 'demo', 'hello', name)
- d.addCallback(handle_hello)
- d.addErrback(error)
- def main():
- # get the erlang node name
- remote = sys.argv[1]
- # additional args.
- name = sys.argv[2]
- # get the erlang node cookie and setup the twotp.Process.
- cookie = twotp.readCookie()
- this_node = twotp.buildNodeName('demo_client')
- process = twotp.Process(this_node, cookie)
- # start twisted reactor.
- reactor.callWhenRunning(call_hello, process, remote, name)
- reactor.run()
- if __name__ == "__main__":
- main()
Run python script and make it works.
运行python脚本并且使他工作。
- $ python main.py 'test' WangQiang
- Got hello results [72, 101, 108, 108, 111, 44, 32, 87, 97, 110, 103, 81, 105, 97, 110, 103]
- String form: Hello, WangQiang
- Got ping result: pong 2
- Got ping result: pong 3
- Got ping result: pong 4
- Got ping result: pong 5
- Got ping result: pong 6
- Got ping result: pong 7
- Got ping result: pong 8
- Got ping result: pong 9
- Got ping result: pong 10
from:
阅读(2027) | 评论(1) | 转发(0) |