OOZOU
تواصلوا معنا
العودة إلى المدونة

استكشاف العمليات (processes) في Elixir

نبني على مثال FizzBuzz من المقالة السابقة ونطوّره.

16 ديسمبر 2014
4 دقائق للقراءة
استكشاف العمليات (processes) في Elixir

مرّت قرابة 3 أشهر على إصدار Elixir 1.0، وما زلنا متحمسين جدًا لهذه اللغة.

في هذه المقالة نبني على مثال FizzBuzz من المقالة السابقة، ونحوّله الآن إلى خادم.

خادم FizzBuzz

defmodule FizzBuzz do
  @moduledoc "A very simple FizzBuzz server"

  @doc """
    Computes and outputs the FizzBuzz value for the
    provided argument.
  """
  @spec compute(Integer) :: :ok
  def compute do
    receive do
      n -> IO.puts "#{n}: #{compute(n)}"
    end
    compute
  end

  defp compute(n) do
    case {rem(n, 3), rem(n, 5)} do
      {0, 0} -> :FizzBuzz
      {0, _} -> :Fizz
      {_, 0} -> :Buzz
      _      -> n
    end
  end
end
lang-elixir

هذا module بسيط، فيه بعض التوثيق وtypespec للدالة compute/0، التي تمثل نقطة الدخول الرئيسية إلى module الـ FizzBuzz. تستخدم الدالة receive/1 لجلب الرقم التالي من صندوق بريد العملية (mailbox)، ثم تحسب النتيجة (عبر الدالة الخاصة compute/1) وتطبعها، قبل أن تستدعي نفسها مجددًا لانتظار الرسالة التالية.

التواصل مع الخادم

لاستخدام الخادم الذي أنشأناه للتو، نبدأ تشغيله أولًا باستخدام spawn/3، التي تتوقع اسم module واسم الدالة المراد استدعاؤها ووسائط تلك الدالة. وتُرجع الـ pid الخاص بالعملية الجديدة، ونخزّنه في المتغير fb (تذكروا أن الأقواس حول وسائط الدوال اختيارية في Elixir).

fb = spawn FizzBuzz, :compute, []
lang-elixir

بعد ذلك يمكننا استخدام send/2 لإرسال رسالة إلى الخادم:

send fb, 3
lang-elixir

سيطبع هذا "3: Fizz" ويُرجع 3. لنرسل الآن عدة رسائل للتأكد من أن الاستدعاء التكراري في compute/0 يعمل كما هو متوقع:

10..15 |> Enum.map(&send(fb, &1))
lang-elixir

نستخدم هنا عامل الـ pipe في Elixir (|>/2) لإرسال Range الأرقام من 10 إلى 15 إلى Enum.map/2، التي تستخدم نسخة مطبّقة جزئيًا من send/2 مع وسيط مجهول (&1). والناتج كما توقعنا:

10: Buzz
11: 11
12: Fizz
13: 13
14: 14
15: FizzBuzz
lang-elixir

التعامل مع الأخطاء

قد يتساءل القراء الأكثر انتباهًا الآن: ماذا يحدث لو أرسلنا إلى FizzBuzz.compute/0 نوع بيانات آخر بدلًا من عدد صحيح؟ لنجرب:

send fb, 1.0
lang-elixir

يؤدي هذا إلى رسالة الخطأ التالية:

14:25:32.742 [error] Error in process <0.95.0> with exit value: {badarith,[{'Elixir.FizzBuzz',compute,1,[{file,"fizzbuzz.ex"},{line,10}]},{'Elixir.FizzBuzz',compute,0,[{file,"fizzbuzz.ex"},{line,4}]}]}
lang-elixir

يعني هذا أن خادم FizzBuzz قد تعطل. لكن بما أننا نتعامل مع عملية غير مرتبطة (unlinked)، فإن برنامجنا الرئيسي (وهو في هذه الحالة جلسة iex) لا يتأثر بذلك. لنشغّل الخادم مجددًا، لكن هذه المرة كعملية مرتبطة باستخدام spawn_link/3:

fb = spawn_link FizzBuzz, :compute, []
lang-elixir

الآن ستنتقل أي مشكلة في خادم FizzBuzz إلى الأعلى وتُنهي العملية الرئيسية أيضًا:

14:33:40.426 [error] Error in process <0.119.0> with exit value: {badarith,[{'Elixir.FizzBuzz',compute,1,[{file,"fizzbuzz.ex"},{line,10}]},{'Elixir.FizzBuzz',compute,0,[{file,"fizzbuzz.ex"},{line,4}]}]}

** (EXIT from #PID<0.116.0>) an exception was raised:
** (ArithmeticError) bad argument in arithmetic expression
fizzbuzz.ex:10: FizzBuzz.compute/1
fizzbuzz.ex:4: FizzBuzz.compute/0
lang-elixir

يمكن معالجة ذلك بإضافة guard clause إلى compute/0 في FizzBuzz على هذا النحو:

def compute do
  receive do
    n when is_integer(n) -> IO.puts "#{n}: #{compute(n)}"
    _ -> IO.puts "Invalid argument"
  end
  compute
end
lang-elixir

ينجح هذا الحل، لكنه يتعارض مع أحد أهم مبادئ Erlang: "let it crash" (دعها تتعطل). فبدلًا من البرمجة الدفاعية، تُنهي الأخطاء العملية ببساطة، وتُترك معالجة الموقف لعمليات المراقبة (إن وُجدت).

المراقبة (Monitoring)

إحدى طرق التعامل مع ما سبق هي إعداد monitor. وعلى عكس الـ link، فهذه علاقة أحادية الاتجاه بين العمليات. لإنشاء monitor، نشغّل خادم FizzBuzz باستخدام spawn_monitor/3، التي تُرجع مرجع مراقبة (monitoring reference) إضافة إلى الـ pid. لا نستخدم هذا المرجع في المثال التالي، لكنه مفيد لإيقاف المراقبة يدويًا عبر استدعاء demonitor/2.

الآن إذا توقف الخادم، تُرسل رسالة إلى عملية المراقبة:

{fb, ref} = spawn_monitor FizzBuzz, :compute, []
send fb, 1.0
lang-elixir

بما أننا لم نستخدم receive/1 لإعداد مستقبِل رسائل في جلسة iex، سنحتاج إلى استدعاء الدالة المساعدة flush/0 يدويًا لرؤية تنبيه المراقبة:

{:DOWN, #Reference<0.0.0.262>, :process, #PID<0.79.0>,
  {:badarith,
    [{FizzBuzz, :compute, 1, [file: 'fizzbuzz.ex', line: 16]},
    {FizzBuzz, :compute, 0, [file: 'fizzbuzz.ex', line: 10]}]}}
lang-elixir

ما التالي؟

التعامل مع العمليات في Elixir سهل جدًا. لكن بتنفيذ خادم FizzBuzz من الصفر، لا نستفيد بالكامل من القوة التي توفرها أسس Erlang/OTP للغة Elixir. لذا سنعود في الجزء القادم من هذه السلسلة إلى خادم FizzBuzz، لكن هذه المرة باستخدام سلوكيات OTP gen_server وsupervisor. تابعونا!

Related Articles

كيف أصمّم برمجيات؟ دليل المبتدئين لأصحاب الأعمال

كيف أصمّم برمجيات؟ دليل المبتدئين لأصحاب الأعمال

تصميم البرمجيات عملية ممتعة لكنها معقدة، تتطلب الإبداع والتفكير المنطقي ومهارات حل المشكلات.

اقرأوا المزيد
مستقبل الحوسبة الطرفية: ما تحتاج الشركات إلى معرفته

مستقبل الحوسبة الطرفية: ما تحتاج الشركات إلى معرفته

يتطور المشهد الرقمي بسرعة، وعلى الشركات أن تتكيّف لتواكب الطلب المتزايد على السرعة والكفاءة والمعالجة في الوقت الفعلي.

اقرأوا المزيد
مستقبل قطاع التجزئة: الذكاء الاصطناعي والواقع المعزّز واتجاهات التحوّل الرقمي

مستقبل قطاع التجزئة: الذكاء الاصطناعي والواقع المعزّز واتجاهات التحوّل الرقمي

يتطور قطاع التجزئة بوتيرة غير مسبوقة بفضل الذكاء الاصطناعي (AI) والواقع المعزّز (AR) وتقنيات التحوّل الرقمي. فلم تعد المتاجر التقليدية مجرد أماكن لبيع المنتجات، بل أصبحت متاجر ذكية وتفاعلية.

اقرأوا المزيد

Have a Project in Mind?

Let's discuss how we can help bring your ideas to life with our expertise in web and mobile development.

ابدأوا المحادثةhello@oozou.com
OOZOU Logo

بانكوك · سنغافورة · هونغ كونغ

X
Facebook
Instagram
LinkedIn
OOZOU Co., Ltd.
548 One City Centre
Ploenchit Road
Bangkok 10330
Thailand
+66 2544 0000
hello@oozou.com

الخدمات

  • تطوير الويب
  • وكلاء الذكاء الاصطناعي والذكاء الاصطناعي التوليدي
  • تطوير تطبيقات الجوال
  • تحليلات البيانات وهندستها
  • تصميم تجربة المستخدم وواجهته (UX/UI) وتصميم المنتجات
  • التحوّل الرقمي

الشركة

  • من نحن
  • الوظائف
  • المدونة
  • دراسات الحالة
  • عروض حية
  • تعلّمت اليوم
  • تواصل معنا

المزيد

  • القطاعات
  • شبكة الشركاء
© 2026 OOZOU. جميع الحقوق محفوظة.
سياسة الخصوصيةمدونة قواعد السلوكسياسة مكافحة الرشوة والفساد