ربط إرلانج، جوليا، إليكسير
هذا هو مشروعي الصغير الطموح لربط عوالم Erlang/Elixir وJulia المختلفة:
الآن يمكن لعمليتي Erlang وElixir إرسال رسائل لبعضهما البعض حيث أنهما تعملان على نفس منصة BEAM وتتشاركان معرفات PID. ولكن ماذا عن إرسال الرسائل إلى جوليا والعودة إلى 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
التي تم إنشاؤها باستخدام بيانات من Elixir والحصول على النتيجة مرة أخرى تستغرق ما يقرب من 500 ميكروثانية مع تشغيل كلتا الجلستين على نفس الجهاز (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 , [ ] }
مرة أخرى في جوليا 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. هناك مشكلة في تحديث الريبو الرئيسي. عند توفرها في سجل Julia، يمكنك تثبيت الحزمة باستخدام
pkg > add Erjulix
إذا كانت متوفرة في Hex، فيمكن تثبيت الحزمة في Elixir عن طريق إضافة erjulix
إلى قائمة التبعيات الخاصة بك في mix.exs
:
def deps do
[
{ :erjulix , "~> 0.1.0" }
]
end
يمكن إنشاء الوثائق باستخدام ExDoc ونشرها على HexDocs. بمجرد نشر المستندات، يمكن العثور عليها على https://hexdocs.pm/erjulix.