أدوات الدعم الفعال في ريلز

من موسوعة حسوب

الدعم الفعال هو جزء من نواة ريلز التي توفر ملحقات للغة روبي والأدوات المساعدة وغيرها من الأشياء. أحد الأشياء التي يتضمنها هو واجهة برمجية لأدوات قياس (instrumentation API) يمكن استخدامها داخل تطبيق لقياس إجراءات معينة تحدث داخل شيفرة روبي، مثل تلك الموجودة داخل تطبيق ريلز أو إطار العمل نفسه، إذ لا يقتصر ذلك على ريلز فقط. يمكن استخدامها بشكل مستقل في شيفرات روبي البرمجية الأخرى إذا كان ذلك مطلوبًا.

في هذا الدليل، ستتعلم كيفية استخدام الواجهة البرمجية لأدوات القياس (instrumentation API) داخل الدعم الفعال لقياس الأحداث داخل ريلز وغيرها من شيفرات روبي.

بعد قراءة هذا الدليل، ستتعلم:

  • ما هي الأدوات المتوافرة.
  • الخطافات داخل إطار ريلز لأدوات القياس.
  • إضافة مُشترِك (subscriber) إلى خطاف.
  • بناء تنفيذ مخصص لأداة قياس.

مقدمة إلى الأدوات

تسمح الواجهة البرمجية لأدوات القياس التي يوفرها الدعم الفعال لمطوري البرامج بتوفير خطافات يمكن لمطوري البرامج الآخرين استعمالها. هناك العديد منها في إطار ريلز. باستخدام واجهة برمجة التطبيقات هذه، يمكن للمطورين اختيار كيفية تنبيههم عند وقوع أحداث معينة داخل التطبيق أو في جزء آخر من شيفرة روبي.

على سبيل المثال، هناك خطاف يتوفر ضمن السجل الفعال يستدعى في كل مرة يستخدم السجل الفعال استعلام SQL في قاعدة بيانات. يمكن الاشتراك في هذا الخطاف واستخدامه لتتبع عدد طلبات البحث أثناء تنفيذ إجراء معين. هناك خطاف آخر حول معالجة إجراء وحدة التحكم. يمكن استخدام هذا، على سبيل المثال، لتتبع مدة تنفيذ إجراء معين.

يمكنك حتى إنشاء أحداثك الخاصة داخل تطبيقك والتي يمكنك الاشتراك فيها لاحقًا.

خطافات إطار ريلز

ضمن إطار ريلز، هناك عدد من الخطافات المتوافرة للأحداث الشائعة سنتظرق إليها في الأقسام الآتية.

وحدة التحكم

Write_fragment.action_controller

المفتاح القيمة
 ‎:key المفتاح الكامل.
{

 key: 'posts/1-dashboard-view'

}

Read_fragment.action_controller

المفتاح القيمة
 ‎:key المفتاح الكامل.
{

 key: 'posts/1-dashboard-view'

}

Expire_fragment.action_controller

المفتاح القيمة
 ‎:key المفتاح الكامل.
{

 key: 'posts/1-dashboard-view'

}

Exist_fragment?.action_controller

المفتاح القيمة
 ‎:key المفتاح الكامل.
{

 key: 'posts/1-dashboard-view'

}

 Write_page.action_controller

المفتاح القيمة
 ‎:key المفتاح الكامل.
{

 path: '/users/1'

}

Expire_page.action_controller

المفتاح القيمة
 ‎:path المسار الكامل.
{

 path: '/users/1'

}

Start_processing.action_controller

المفتاح القيمة
:controller اسم وحدة التحكم
:action الإجراء
:params جدول Hash من معاملات الطلب دون أي معامل مرشح
:headers ترويسات طلب
:format html/js/json/xml ...إلخ.
:method فعل طلب HTTP
:path طلب المسار
{
  controller: "PostsController",
  action: "new",
  params: { "action" => "new", "controller" => "posts" },
  headers: #<ActionDispatch::Http::Headers:0x0055a67a519b88>,
  format: :html,
  method: "GET",
  path: "/posts/new"
}

Process_action.action_controller

المفتاح القيمة
:controller اسم وحدة التحكم
:action الإجراء
:params جدول Hash لمعاملات الطلب من غير أي معامل مرشح
:headers ترويسات الطلب
:format html/js/json/xml ...إلخ.
:method فعل طلب HTTP
:path طلب المسار
:status رمز حالة HTTP
:view_runtime الكمية المستغرقة في واجهة العرض بالمللي ثانية.
:db_runtime الكمية المستغرقة لتنفيذ استعلامات قاعدة البيانات بالميللي ثانية.
{
  controller: "PostsController",
  action: "index",
  params: {"action" => "index", "controller" => "posts"},
  headers: #<ActionDispatch::Http::Headers:0x0055a67a519b88>,
  format: :html,
  method: "GET",
  path: "/posts",
  status: 200,
  view_runtime: 46.848,
  db_runtime: 0.157
}

Send_file.action_controller

المفتاح القيمة
 ‎:path المسار الكامل.

ملاحظة: يمكن إضافة مفاتيح إضافية من قبل المتصل.

Send_data.action_controller

ليس لدى المتحكم ActionController أي معلومات محددة للحمولة (payload). تُمرر جميع الخيارات إلى الحمولة (payload).

Redirect_to.action_controller

المفتاح القيمة
:status رمز استجابة HTTP
:location عنوان URL لإعادة التوجيه إليه
{
  status: 302,
  location: "http://localhost:3000/posts/new"
}

Halted_callback.action_controller

القيمة المفتاح
:filter المرشح الذي أوقف الإجراء.
{

 filter: ":halting_filter"

}

Unpermitted_parameters.action_controller

المفتاح القيمة
:keys المفاتيح غير مسموح بها.

إجراء العرض

Render_template.action_view

القيمة المفتاح
المسار الكامل للقالب. :identifier
تخطيط قابل للتطبيق. :layout
{

 identifier: "/Users/adam/projects/notifications/app/views/posts/index.html.erb",

 layout: "layouts/application"

}

Render_partial.action_view

القيمة المفتاح
المسار الكامل للقالب. :identifier
{

 identifier: "/Users/adam/projects/notifications/app/views/posts/_form.html.erb"

}

Render_collection.action_view

المفتاح القيمة
   :identifier المسار الكامل للقالب.
    :count حجم المجموعة.
 :cache_hits عدد الجزيئات التي جُلبت من ذاكرة التخزين المؤقت.

Cache_hits: يُضمن فقط إذا كانت المجموعة مقدمة مع cached: true.

{

 identifier: "/Users/adam/projects/notifications/app/views/posts/_post.html.erb",

 count: 3,

 cache_hits: 0

}

السجل النشط

Sql.active_record

القيمة المفتاح
جملة SQL. :sql
اسم العملية. :name
self.object_id :connection_id
معاملات الربط. :binds
تضاف true عند استخدام الاستعلامات المخبأة     :cached

ملاحظة: ستضيف المحولات البيانات الخاصة بها أيضًا.

{

 sql: "SELECT \"posts\".* FROM \"posts\" ",

 name: "Post Load",

 connection_id: 70307250813140,

 binds: []

}

Instantiation.active_record

القيمة المفتاح
عدد السجلات التي أُنشئت نسخ لها. :record_count
سجل الفئة. :class_name
{

 record_count: 1,

 class_name: "User"

}

إجراء الإرسال

Receive.action_mailer

المفتاح القيمة
:mailer اسم فئة الارسال.
:message_id معرف الرسالة، التي أُنشئت بواسطة جوهرة البريد.
:subject موضوع البريد.
:to لمعالجة (عناوين) البريد.
:from من عنوان البريد.
:bcc عناوين BCC للبريد.
:cc عناوين CC للبريد.
:date تاريخ البريد.
:mail شكل مشفر للبريد.
{

 mailer: "Notification",

 message_id: "4f5b5491f1774_181b23fc3d4434d38138e5@mba.local.mail",

 subject: "Rails Guides",

 to: ["users@rails.com", "dhh@rails.com"],

 from: ["me@rails.com"],

 date: Sat, 10 Mar 2012 14:18:09 +0100,

 mail: "..." # omitted for brevity

}

Deliver.action_mailer

المفتاح القيمة
:mailer اسم فئة الارسال.
:message_id معرف الرسالة، التي أُنشئت بواسطة جوهرة البريد.
:subject موضوع البريد.
:to لمعالجة (عناوين) البريد.
:from من عنوان البريد.
:bcc عناوين BCC للبريد.
:cc عناوين CC للبريد.
:date تاريخ البريد.
:mail شكل مشفر للبريد.
{

 mailer: "Notification",

 message_id: "4f5b5491f1774_181b23fc3d4434d38138e5@mba.local.mail",

 subject: "Rails Guides",

 to: ["users@rails.com", "dhh@rails.com"],

 from: ["me@rails.com"],

 date: Sat, 10 Mar 2012 14:18:09 +0100,

 mail: "..." # omitted for brevity

}

Process.action_mailer

القيمة المفتاح
اسم فئة الارسال. :mailer
الإجراء. :action
الحجج. :args
{

 mailer: "Notification",

 action: "welcome_email",

 args: []

}

الدعم الفعال

Cache_read.active_support

المفتاح القيمة
:key المفتاح المستخدم في المخزن.
:hit إذا كانت هذه القراءة هي النتيجة.
:super_operation #fetch  عند إضافة قراءة مع :fetch   

Cache_generate.active_support

يستخدم هذا الحدث فقط عندما تستدعى #fetch بعلامة.

القيمة المفتاح
المفتاح المستخدم في المخزن. :key

ملاحظة: تدمج الخيارات التي مُررت لجلب البيانات مع الحمولة عند الكتابة إلى المخزن.

{

 key: 'name-of-complicated-computation'

}

Cache_fetch_hit.active_support

يستخدم هذا الحدث فقط عندما تستدعى #fetch بعلامة.

القيمة المفتاح
المفتاح المستخدم في المخزن. :key

ملاحظة: ملاحظة: تدمج الخيارات التي مُررت لجلب البيانات مع الحمولة.

{

 key: 'name-of-complicated-computation'

}

Cache_write.active_support

القيمة المفتاح
المفتاح المستخدم في المخزن. :key

ملاحظة: قد تضيف مخازن ذاكرة التخزين المؤقت مفاتيحها الخاصة.

{

 key: 'name-of-complicated-computation'

}

Cache_delete.active_support

القيمة المفتاح
المفتاح المستخدم في المخزن. :key
{

 key: 'name-of-complicated-computation'

}

Cache_exist?.active_support

القيمة المفتاح
المفتاح المستخدم في المخزن. :key
{

 key: 'name-of-complicated-computation'

}

الوظيفة النشطة

Enqueue_at.active_job

القيمة المفتاح
كائن QueueAdapter يعالج الوظيفة. :adapter
كائن الوظيفة. :job

Enqueue.active_job

القيمة المفتاح
كائن QueueAdapter يعالج الوظيفة. :adapter
كائن الوظيفة. :job

Perform_start.active_job

القيمة المفتاح
كائن QueueAdapter يعالج الوظيفة. :adapter
كائن الوظيفة. :job

Perform.active_job

القيمة المفتاح
كائن QueueAdapter يعالج الوظيفة. :adapter
كائن الوظيفة. :job

كابل العمل

Perform_action.action_cable

القيمة المفتاح
اسم فئة القناة. :channel_class
الإجراء. :action
تجزئة البيانات. :data

Transmit.action_cable

القيمة المفتاح
اسم فئة القناة. :channel_class
تجزئة البيانات. :data
عبر. :via

Transmit_subscription_confirmation.action_cable

القيمة المفتاح
اسم فئة القناة. :channel_class

Transmit_subscription_rejection.action_cable

القيمة المفتاح
اسم فئة القناة. :channel_class

Broadcast.action_cable

المفتاح القيمة
:broadcasting بث مسمى.
:message تجزئة للرسالة.
:coder المبرمج.

التخزين النشط

Service_upload.active_storage

القيمة المفتاح
رمز آمن. :key
اسم الخدمة. :service
تدقيق لضمان السلامة. :checksum

Service_streaming_download.active_storage

القيمة المفتاح
رمز آمن. :key
اسم الخدمة. :service

Service_download.active_storage

القيمة المفتاح
رمز آمن. :key
اسم الخدمة. :service

Service_delete.active_storage

القيمة المفتاح
رمز آمن. :key
اسم الخدمة. :service

Service_delete_prefixed.active_storage

القيمة المفتاح
بادئة المفتاح. :prefix
اسم الخدمة. :service

Service_exist.active_storage

القيمة المفتاح
رمز آمن. :key
اسم الخدمة. :service
الملف أو السقوط موجود أم لا. :exist

Service_url.active_storage

القيمة المفتاح
رمز آمن. :key
اسم الخدمة. :service
عنوان URL أُنشأ. :url

Railties

Load_config_initializer.railties

القيمة المفتاح
المسار لتحميل مُهيئ من config / initializers. :initializer

Rails

Deprecation.rails

القيمة المفتاح
تحذير الانتقاص. :message
من اين جاء الانتقاص. :callstack

الاشتراك في الحدث

الاشتراك في حدث أمر سهل. استخدم ActiveSupport :: Notifications.subscribe مع كتلة للاستماع إلى أي إخطار.

يتلقى الكتلة الوسيطات التالية:

- اسم الحدث.

- الوقت عند البدء.

- الوقت عند الانتهاء.

- معرف فريد لهذا الحدث.

- الحمولة (الموضحة في الأقسام السابقة).

ActiveSupport::Notifications.subscribe "process_action.action_controller" do |name, started, finished, unique_id, data|

 # your own custom stuff

 Rails.logger.info "#{name} Received!"

End

تعريف كل وسيطات الكتلة هذه في كل مرة يمكن أن تكون مملة. يمكنك بسهولة إنشاء ActiveSupport :: Notifications :: Event من وسيطات حظر مثل هذا:

ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|

 event = ActiveSupport::Notifications::Event.new *args

 event.name      # => "process_action.action_controller"

 event.duration  # => 10 (in milliseconds)

 event.payload   # => {:extra=>information}

 Rails.logger.info "#{event} Received!"

End

في معظم الأحيان، لا تهتم إلا بالبيانات نفسها. هنا هو اختصار للحصول على البيانات فقط.

ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|

 data = args.extract_options!

 data # { extra: :information }

End

يمكنك أيضًا الاشتراك في الأحداث التي تتطابق مع تعبير عادي. يتيح لك هذا الاشتراك في أحداث متعددة في وقت واحد. هنا يمكنك الاشتراك في كل شيء من ActionController.

ActiveSupport::Notifications.subscribe /action_controller/ do |*args|

 # inspect all ActionController events

End

إنشاء أحداث مخصصة

إضافة الأحداث الخاصة بك من السهل كذلك. ActiveSupport::Notifications سيعتني بكل الرفع الثقيل من أجلك. ببساطة تستدعى  instrument مع الاسم والحمولة والكتلة. سيرسل الإخطار بعد إرجاع الكتلة. ينشئ ActiveSupport أوقات البدء والانتهاء بالإضافة إلى المعرف الفريد. جميع البيانات التي مُررت إلى استدعاء instrument تجعلها في الحمولة.

إليك مثال على ذلك:

ActiveSupport::Notifications.instrument "my.custom.event", this: :data do

 # do your custom stuff here

End

الآن يمكنك الاستماع إلى هذا الحدث مع:

ActiveSupport::Notifications.subscribe "my.custom.event" do |name, started, finished, unique_id, data|

 puts data.inspect # {:this=>:data}

End

يجب عليك اتباع معايير Rails عند تحديد الأحداث الخاصة بك. التنسيق هو: event.library. إذا كان تطبيقك يرسل التغريدات، فيجب إنشاء حدث باسم tweet.twitter.

مصادر