Menghubungkan Erlang, Julia, Elixir
Ini adalah proyek kecil ambisius saya untuk menghubungkan dunia Erlang/Elixir dan Julia yang berbeda:
Sekarang proses Erlang dan Elixir dapat saling mengirim pesan karena keduanya berjalan pada platform BEAM yang sama dan berbagi PID. Tapi bagaimana kalau mengirim pesan ke Julia dan kembali ke Erlang/Elixir?
Di Julia REPL kita memulai tugas pServer
, yang sesuai permintaan memunculkan tugas EvalServer
dengan namespace modulnya sendiri.
julia > using Erjulix, Sockets
julia > pServer ( 6000 )
Task (runnable) @ 0x0000000110b30ab0
Di Elixir REPL kami meminta Julia EvalServer
dan menggunakannya untuk mengevaluasi ekspresi Julia atau memanggil fungsi 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}}
Waktu terakhir menunjukkan bahwa ping-pong untuk memanggil fungsi fact
Julia yang dibuat dengan data dari Elixir dan mendapatkan kembali hasilnya memerlukan waktu sekitar 500 µs dengan kedua sesi berjalan pada mesin yang sama (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 , [ ] }
Kembali ke 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 ....
Jika kita memulai pServer
dengan alamat IP mesin dan kunci, komunikasi dengan klien jarak jauh akan dienkripsi SHA-256:
julia > getipaddr ()
ip " 192.168.2.113 "
julia > key = Erjulix . genpasswd ( 12 )
" 1XQeFem2NUNw "
julia > pServer ( getipaddr (), 6000 , key)
Task (runnable) @ 0x00000001110e7b90
Kami menggunakan alamat IP mesin dan kunci tersebut untuk mengakses pServer
dari Raspberry Pi di jaringan lokal:
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
menghasilkan kunci baru untuk akses jaringan terenkripsi ke Julia EvalServer
. Waktunya menunjukkan bahwa ping-pong jaringan membutuhkan waktu kurang dari 100 ms antara kedua mesin (tanpa enkripsi dibutuhkan sekitar 70 ms).
iex ( 9 ) > :ejx_udp . client ( jl , :exit )
{ :ok , :done }
Ini adalah prototipe interoperabilitas berdasarkan Term Format Erlang melalui UDP.
Keamanan thread: Tentu saja mengakses modul server seperti yang ditunjukkan tidak aman untuk thread dan oleh karena itu tidak boleh dilakukan secara bersamaan.
Keamanan: Jika Anda berbagi alamat dan port Server UDP, klien jarak jauh bisa mendapatkan akses ke sistem file. Jika Anda memberikan kunci ke pServer
, transmisi data akan menggunakan enkripsi SHA-256.
ErlangTerm.jl
.jwerl
, kompatibel dengan Erlang/OTP 24. Ada masalah saat memperbarui repo utama. Jika tersedia di registri Julia, Anda dapat menginstal paket dengan
pkg > add Erjulix
Jika tersedia dalam Hex, paket dapat diinstal di Elixir dengan menambahkan erjulix
ke daftar dependensi Anda di mix.exs
:
def deps do
[
{ :erjulix , "~> 0.1.0" }
]
end
Dokumentasi dapat dibuat dengan ExDoc dan dipublikasikan di HexDocs. Setelah diterbitkan, dokumennya dapat ditemukan di https://hexdocs.pm/erjulix.