เชื่อมต่อ Erlang, Julia, Elixir
นี่เป็นโปรเจ็กต์เล็กๆ ที่มีความทะเยอทะยานของฉันในการเชื่อมโยงโลกที่แตกต่างของ Erlang/Elixir และ Julia:
ขณะนี้กระบวนการ Erlang และ Elixir สามารถส่งข้อความหากันได้ เนื่องจากทำงานบนแพลตฟอร์ม BEAM เดียวกันและแบ่งปัน PID แต่การส่งข้อความถึง Julia และกลับไปยัง Erlang/Elixir ล่ะ
ใน Julia REPL เราเริ่มงาน pServer
ซึ่งจะสร้างงาน EvalServer
ด้วยเนมสเปซโมดูลของตัวเองตามความต้องการ
julia > using Erjulix, Sockets
julia > pServer ( 6000 )
Task (runnable) @ 0x0000000110b30ab0
ใน Elixir REPL เราขอ Julia EvalServer
และใช้เพื่อประเมินนิพจน์ Julia หรือเรียกใช้ฟังก์ชัน Julia
iex ( 1 ) > { :ok , jl , _ } = :ejx_udp . srv ( 6000 ) # get an eval server from Julia
{ :ok , { { 127 , 0 , 0 , 1 } , 54465 } , "Main.##esm#257" }
iex ( 2 ) > :ejx_udp . eval ( jl , "using .Threads" )
{ :ok , [ ] }
iex ( 3 ) > :ejx_udp . call ( jl , :threadid )
{ :ok , 3 }
iex ( 4 ) > :ejx_udp . call ( jl , :factorial , [ 50 ] )
{ :error ,
"OverflowError( " 50 is too large to look up in the table; consider using `factorial(big(50))` instead " )" }
iex ( 5 ) > :ejx_udp . eval ( jl , """ # define a function on the Julia server
...(5)> function fact(x)
...(5)> factorial(big(x))
...(5)> end
...(5)> """)
{:ok, "Main.##esm#257.fact"}
iex(6)> :ejx_udp.call(jl, :fact, [50])
{:ok, 30414093201713378043612608166064768844377641568960512000000000000}
iex(7)> :timer.tc(:ejx_udp, :call, [jl, :fact, [55]])
{527,
{:ok,
12696403353658275925965100847566516959580321051449436762275840000000000000}}
เวลาสุดท้ายแสดงให้เห็นว่าปิงปองสำหรับการเรียกใช้ฟังก์ชัน fact
Julia ที่สร้างขึ้นด้วยข้อมูลจาก Elixir และการรับผลลัพธ์กลับใช้เวลาประมาณ 500 µs โดยทั้งสองเซสชันทำงานบนเครื่องเดียวกัน (MacBook Pro)
iex ( 8 ) > a = Enum . map ( 1 .. 10 , fn _ -> :rand . uniform ( ) end )
[ 0.9414436609049482 , 0.08244595999142224 , 0.6727398779368937 ,
0.18612089183158875 , 0.7414592106015152 , 0.7340558985797445 ,
0.9511971092470349 , 0.7139960750204088 , 0.31514816254491884 , 0.94168140313657 ]
iex ( 9 ) > :ejx_udp . set ( jl , :a , a ) # create variable a on the Julia server
{ :ok , [ ] }
ย้อนกลับไปใน Julia REPL:
julia > exmod = Erjulix . _ESM[ 1 ] # get access to the server module
Main. # #esm#257
julia > exmod . a # and to the created variable a
10 - element Vector{Any} :
0.9414436609049482
0.08244595999142224
0.6727398779368937
0.18612089183158875
⋮
0.9511971092470349
0.7139960750204088
0.31514816254491884
0.94168140313657
julia > using Plots ....
หากเราเริ่มต้น pServer
ด้วยที่อยู่ IP ของเครื่องและคีย์ การสื่อสารกับไคลเอนต์ระยะไกลจะได้รับการเข้ารหัส SHA-256:
julia > getipaddr ()
ip " 192.168.2.113 "
julia > key = Erjulix . genpasswd ( 12 )
" 1XQeFem2NUNw "
julia > pServer ( getipaddr (), 6000 , key)
Task (runnable) @ 0x00000001110e7b90
เราใช้ที่อยู่ IP ของเครื่องและคีย์นั้นเพื่อเข้าถึง pServer
จาก Raspberry Pi ในเครือข่ายท้องถิ่น:
iex ( 1 ) > :inet . gethostname ( )
{ :ok , 'raspberrypi' }
iex ( 2 ) > key = "1XQeFem2NUNw"
"1XQeFem2NUNw"
iex ( 3 ) > { :ok , jl , _ } = :ejx_udp . srv ( { { 192 , 168 , 2 , 113 } , 6000 , key } )
{ :ok , { { 192 , 168 , 2 , 113 } , 55052 , "j8Gh3G6dPfJm28UpthL0dXew" } , "Main.##esm#258" }
iex ( 4 ) > :ejx_udp . call ( jl , :factorial , [ 20 ] )
{ :ok , 2432902008176640000 }
iex ( 5 ) > :timer . tc ( :ejx_udp , :call , [ jl , :factorial , [ 20 ] ] )
{ 86620 , { :ok , 2432902008176640000 } }
pServer
สร้างคีย์ใหม่สำหรับการเข้าถึงเครือข่ายที่เข้ารหัสไปยัง Julia EvalServer
ระยะเวลาแสดงให้เห็นว่าปิงปองเครือข่ายใช้เวลาประมาณ 100 มิลลิวินาทีระหว่างเครื่องทั้งสองเครื่อง (หากไม่มีการเข้ารหัสจะใช้เวลาประมาณ 70 มิลลิวินาที)
iex ( 9 ) > :ejx_udp . client ( jl , :exit )
{ :ok , :done }
นี่คือต้นแบบสำหรับการทำงานร่วมกันโดยอิงตามรูปแบบคำของ Erlang บน UDP
ความปลอดภัยของเธรด: แน่นอนว่าการเข้าถึงโมดูลเซิร์ฟเวอร์ดังที่แสดงไว้นั้นไม่ปลอดภัยสำหรับเธรด ดังนั้นจึงไม่ควรทำพร้อมกัน
ความปลอดภัย: หากคุณแชร์ที่อยู่และพอร์ตเซิร์ฟเวอร์ UDP ไคลเอนต์ระยะไกลจะสามารถเข้าถึงระบบไฟล์ได้ หากคุณระบุคีย์ให้กับ pServer
การส่งข้อมูลจะใช้การเข้ารหัส SHA-256
ErlangTerm.jl
jwerl
ซึ่งเข้ากันได้กับ Erlang/OTP 24 มีปัญหาในการอัปเดต repo หลัก เมื่อพร้อมใช้งานในรีจิสทรี Julia คุณสามารถติดตั้งแพ็คเกจได้
pkg > add Erjulix
หากมีใน Hex สามารถติดตั้งแพ็คเกจใน Elixir ได้โดยเพิ่ม erjulix
ในรายการการขึ้นต่อกันของคุณใน mix.exs
:
def deps do
[
{ :erjulix , "~> 0.1.0" }
]
end
สามารถสร้างเอกสารประกอบได้ด้วย ExDoc และเผยแพร่บน HexDocs เมื่อเผยแพร่แล้ว สามารถดูเอกสารได้ที่ https://hexdocs.pm/erjulix