كيفية استخدام قائمة انتظار مهام App Engine (سحب المهام) في تطبيقات Flask (الوحدة 18)

1. نظرة عامة

تهدف سلسلة الدروس التطبيقية حول الترميز بدون خادم (البرامج التعليمية العملية) والفيديوهات ذات الصلة إلى مساعدة مطوّري Google Cloud الذين لا يستخدمون خوادم على تحديث تطبيقاتهم من خلال إرشادهم خلال عملية واحدة أو أكثر من عمليات نقل البيانات، بعيدًا عن الخدمات القديمة في المقام الأول. يؤدي ذلك إلى تسهيل حمل التطبيقات وتوفير المزيد من الخيارات والمرونة، ما يتيح لك الدمج مع مجموعة أكبر من منتجات Cloud والوصول إليها والترقية بسهولة إلى الإصدارات الأحدث باللغات. مع تركيزنا في البداية على مستخدمي Cloud الأوائل، لا سيما مطوّري App Engine (البيئة العادية)، فإنّ هذه السلسلة واسعة بما يكفي لتشمل أنظمة أساسية أخرى بدون خادم، مثل Cloud Functions وCloud Run أو أي منصة أخرى إن وُجدت.

يشرح لك هذا الدرس التطبيقي حول الترميز كيفية تضمين واستخدام مهام سحب قائمة انتظار المهام في App Engine إلى نموذج التطبيق من الدرس التطبيقي حول الترميز للوحدة 1. أضفنا استخدام مهام Pull في هذا الدليل التوجيهي للوحدة 18، ثم ننقل هذا الاستخدام إلى Cloud Pub/Sub في الوحدة 19. وبدلاً من ذلك، سيتم نقل المستخدمين الذين يستخدمون قوائم انتظار المهام لتنفيذ مهام الدفع إلى "مهام Cloud" وعليك الرجوع إلى الوحدات من 7 إلى 9 بدلاً من ذلك.

ستتعرَّف على كيفية إجراء ما يلي:

  • استخدام واجهة برمجة التطبيقات لقائمة انتظار مهام App Engine أو الخدمة المجمّعة
  • إضافة استخدام قائمة انتظار السحب إلى تطبيق NDB الأساسي على Python 2 Flask

المتطلبات

استطلاع

كيف ستستخدم هذا البرنامج التعليمي؟

القراءة فقط اقرأها وأكمِل التمارين

كيف تقيّم تجربتك مع Python؟

حديث متوسط بارع

ما هو تقييمك لتجربتك في استخدام خدمات Google Cloud؟

حديث متوسط بارع

2. الخلفية

للانتقال من مهام السحب في قائمة انتظار مهام App Engine، أضِف استخدامه إلى تطبيق Flask وتطبيق App Engine الحالي NDB الناتج عن الدرس التطبيقي حول الترميز للوحدة 1. يعرض نموذج التطبيق أحدث الزيارات للمستخدم النهائي. لا بأس في ذلك، ولكن الأمر الأكثر إثارة للاهتمام أيضًا هو تتبّع الزوّار لمعرفة الأشخاص الذين يزورونه أكثر من غيره.

في حين أنه يمكننا استخدام المهام الفورية لأعداد الزوار هذه، نريد تقسيم المسؤولية بين نموذج التطبيق الذي تتمثل وظيفته في تسجيل الزيارات والاستجابة الفورية للمستخدمين، و"عامل" معيّن. تتمثل مهمته في حساب عدد الزائرين خارج سير العمل المعتاد والاستجابة للطلب.

ولتنفيذ هذا التصميم، سنضيف استخدام قوائم الانتظار المخصّصة للسحب إلى التطبيق الرئيسي بالإضافة إلى دعم وظائف العامل. يمكن أن يعمل العامل كعملية منفصلة (مثل مثيل واجهة خلفية أو رمز يعمل على جهاز افتراضي (VM) دائم التشغيل"، أو مَهمّة cron، أو طلب HTTP أساسي من سطر أوامر باستخدام curl أو wget. بعد إتمام عملية الدمج هذه، يمكنك نقل التطبيق إلى Cloud Pub/Sub في الدرس التطبيقي التالي (الوحدة 19).

يتضمن هذا الدليل التوجيهي الخطوات التالية:

  1. الإعداد/التمهيد
  2. تعديل الإعدادات
  3. تعديل رمز التطبيق

3- الإعداد/التمهيد

يوضّح هذا القسم كيفية تنفيذ ما يلي:

  1. إعداد مشروعك على Google Cloud
  2. الحصول على نموذج تطبيق أساسي
  3. (إعادة) نشر التطبيق الأساسي والتحقّق من صحته

تضمن هذه الخطوات بدء العمل بالتعليمة البرمجية.

1. إعداد المشروع

إذا أكملت الدرس التطبيقي حول ترميز الوحدة 1، أعِد استخدام المشروع نفسه (والرمز البرمجي). ويمكنك بدلاً من ذلك إنشاء مشروع جديد أو إعادة استخدام مشروع حالي آخر. تأكَّد من أنّ المشروع يتضمّن حساب فوترة نشطًا وتطبيق App Engine مفعَّل. ابحث عن رقم تعريف مشروعك، لأنّك ستحتاج إليه عدة مرات في هذا الدرس التطبيقي حول الترميز، واستخدامه عندما تواجه المتغيّر PROJECT_ID.

2. الحصول على نموذج تطبيق أساسي

أحد المتطلّبات الأساسية لهذا الدرس التطبيقي حول الترميز هو أن يكون لديك تطبيق App Engine صالح للوحدة 1. أكمِل الدرس التطبيقي حول ترميز الوحدة 1 (يُنصح به) أو انسخ تطبيق الوحدة 1 من المستودع. سواء كنت تستخدم رمزك أو رمزنا، فإن رمز الوحدة 1 هو المكان الذي سوف "تبدأ" فيه. يرشدك هذا الدرس التطبيقي في كل خطوة، إلى الختام بتعليمة برمجية تشبه ما هو موجود في مجلد Module 18 repo "FINISH".

بغض النظر عن تطبيق الوحدة 1 الذي تستخدمه، يجب أن يبدو المجلد مثل النتيجة أدناه، على الأرجح مع مجلد lib أيضًا:

$ ls
README.md               appengine_config.py     requirements.txt
app.yaml                main.py                 templates

3- (إعادة نشر التطبيق الأساسي)

نفِّذ الخطوات التالية لنشر تطبيق الوحدة 1:

  1. احذف مجلد "lib" في حال توفّره وشغِّل: pip install -t lib -r requirements.txt لإعادة تعبئة "lib". قد تحتاج إلى استخدام الأمر pip2 بدلاً من ذلك في حال تثبيت Python 2 وPython 3.
  2. تأكد من تثبيت أداة سطر الأوامر gcloud وإعدادها ومراجعة استخدامها.
  3. عليك إعداد مشروعك على Google Cloud باستخدام gcloud config set project PROJECT_ID إذا كنت لا تريد إدخال PROJECT_ID مع كل أمر gcloud يتم إصداره.
  4. نشر نموذج التطبيق باستخدام "gcloud app deploy"
  5. التأكّد من تشغيل تطبيق الوحدة 1 على النحو المتوقع وعرض أحدث الزيارات (الموضّح أدناه)

a7a9d2b80d706a2b.png

4. تعديل الإعدادات

لا يلزم إجراء أي تغييرات على ملفات إعداد App Engine العادية (app.yaml، وrequirements.txt، وappengine_config.py). بدلاً من ذلك، أضِف ملف إعداد جديدًا، queue.yaml، يتضمّن المحتوى التالي، مع وضعه في دليل المستوى الأعلى نفسه:

queue:
- name: pullq
  mode: pull

يحدّد ملف queue.yaml جميع قوائم انتظار المهام المتوفّرة لتطبيقك (باستثناء قائمة انتظار default [push] التي يتم إنشاؤها تلقائيًا بواسطة App Engine). في هذه الحالة، لا توجد سوى قائمة انتظار سحب تسمى pullq. يتطلّب App Engine تحديد التوجيه mode على أنّه pull، وإلا سيتم إنشاء قائمة انتظار دفع بشكل تلقائي. يمكنك الاطّلاع على المزيد من المعلومات حول إنشاء قوائم انتظار السحب في المستندات. يمكنك الاطّلاع أيضًا على صفحة المراجع queue.yaml للاطّلاع على خيارات أخرى.

انشر هذا الملف بشكل منفصل عن تطبيقك. ستظل تستخدم gcloud app deploy، ولكن عليك أيضًا توفير queue.yaml في سطر الأوامر:

$ gcloud app deploy queue.yaml
Configurations to update:

descriptor:      [/tmp/mod18-gaepull/queue.yaml]
type:            [task queues]
target project:  [my-project]

WARNING: Caution: You are updating queue configuration. This will override any changes performed using 'gcloud tasks'. More details at
https://cloud.google.com/tasks/docs/queue-yaml

Do you want to continue (Y/n)?

Updating config [queue]...⠹WARNING: We are using the App Engine app location (us-central1) as the default location. Please use the "--location" flag if you want to use a different location.
Updating config [queue]...done.

Task queues have been updated.

Visit the Cloud Platform Console Task Queues page to view your queues and cron jobs.
$

5- تعديل رمز التطبيق

يعرض هذا القسم تحديثات للملفات التالية:

  • main.py: يمكنك إضافة استخدام قوائم الانتظار الخاصة بالسحب إلى التطبيق الرئيسي.
  • templates/index.html: عدِّل نموذج الويب لعرض البيانات الجديدة.

الواردات والثوابت

تتمثل الخطوة الأولى في إضافة عملية استيراد واحدة جديدة وعدة ثوابت لدعم قوائم انتظار السحب:

  • إضافة عملية استيراد من مكتبة قائمة انتظار المهام، google.appengine.api.taskqueue
  • أضف ثلاثة ثوابت لتوفير إمكانية استئجار الحد الأقصى لعدد مهام السحب (TASKS) لمدة ساعة (HOUR) من قائمة انتظار السحب (QUEUE).
  • أضف ثابتًا لعرض أحدث الزيارات وكذلك أهم الزوار (LIMIT).

في ما يلي الرمز الأصلي وكيف يبدو بعد إجراء هذه التحديثات:

قبل:

from flask import Flask, render_template, request
from google.appengine.ext import ndb

app = Flask(__name__)

بعد:

from flask import Flask, render_template, request
from google.appengine.api import taskqueue
from google.appengine.ext import ndb

HOUR = 3600
LIMIT = 10
TASKS = 1000
QNAME = 'pullq'
QUEUE = taskqueue.Queue(QNAME)
app = Flask(__name__)

إضافة مهمة سحب (جمع بيانات للمهمة وإنشاء مهمة في قائمة انتظار السحب)

يظل نموذج البيانات "Visit" كما هو، تمامًا كما في طلبات البحث عن الزيارات التي يتم عرضها في "fetch_visits()". التغيير الوحيد المطلوب في هذا الجزء من الرمز هو store_visit(). إضافةً إلى تسجيل الزيارة، أضف مهمة إلى قائمة انتظار السحب مع عنوان IP للزائر حتى يتمكن العامل من زيادة عداد الزائرين.

قبل:

class Visit(ndb.Model):
    'Visit entity registers visitor IP address & timestamp'
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)

def store_visit(remote_addr, user_agent):
    'create new Visit entity in Datastore'
    Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

def fetch_visits(limit):
    'get most recent visits'
    return Visit.query().order(-Visit.timestamp).fetch(limit)

بعد:

class Visit(ndb.Model):
    'Visit entity registers visitor IP address & timestamp'
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)

def store_visit(remote_addr, user_agent):
    'create new Visit in Datastore and queue request to bump visitor count'
    Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
    QUEUE.add(taskqueue.Task(payload=remote_addr, method='PULL'))

def fetch_visits(limit):
    'get most recent visits'
    return Visit.query().order(-Visit.timestamp).fetch(limit)

إنشاء نموذج بيانات ودالة طلب لتتبُّع الزوار

إضافة نموذج بيانات "VisitorCount" لتتبُّع الزوّار يجب أن يحتوي على حقول visitor نفسه بالإضافة إلى عدد صحيح counter لتتبُّع عدد الزيارات. بعد ذلك، أضِف دالة جديدة (بدلاً من ذلك، يمكن أن تكون دالة classmethod في Python) باسم fetch_counts() لطلب البحث عن أبرز الزوّار وعرضها بترتيب من الأكثر إلى الأقل. أضِف الفئة والدالة أسفل نص fetch_visits() مباشرةً:

class VisitorCount(ndb.Model):
    visitor = ndb.StringProperty(repeated=False, required=True)
    counter = ndb.IntegerProperty()

def fetch_counts(limit):
    'get top visitors'
    return VisitCount.query().order(-VisitCount.counter).fetch(limit)

إضافة رمز عامل

أضف دالة جديدة log_visitors() لتسجيل الزائرين من خلال طلب GET إلى /log. وهو يستخدم قاموسًا/تجزئة لتتبُّع أحدث أعداد الزوّار، وتأجير أكبر عدد ممكن من المهام لمدة ساعة. وبالنسبة إلى كل مهمة، يتم تسجيل جميع الزيارات التي أجراها الزائر نفسه. من خلال استخدام التعدادات، يعدِّل التطبيق جميع كيانات VisitorCount المقابلة المتوفّرة في "مخزن البيانات" أو ينشئ عناصر جديدة إذا لزم الأمر. وتعرض الخطوة الأخيرة رسالة نصية عادية تشير إلى عدد الزوار الذين تم تسجيلهم من خلال عدد المهام التي تمت معالجتها. أضِف هذه الدالة إلى main.py أسفل fetch_counts() مباشرةً:

@app.route('/log')
def log_visitors():
    'worker processes recent visitor counts and updates them in Datastore'
    # tally recent visitor counts from queue then delete those tasks
    tallies = {}
    tasks = QUEUE.lease_tasks(HOUR, TASKS)
    for task in tasks:
        visitor = task.payload
        tallies[visitor] = tallies.get(visitor, 0) + 1
    if tasks:
        QUEUE.delete_tasks(tasks)

    # increment those counts in Datastore and return
    for visitor in tallies:
        counter = VisitorCount.query(VisitorCount.visitor == visitor).get()
        if not counter:
            counter = VisitorCount(visitor=visitor, counter=0)
            counter.put()
        counter.counter += tallies[visitor]
        counter.put()
    return 'DONE (with %d task[s] logging %d visitor[s])\r\n' % (
            len(tasks), len(tallies))

تعديل المعالج الرئيسي باستخدام بيانات العرض الجديدة

لعرض أهم الزوّار، عدِّل المعالج الرئيسي root() لاستدعاء fetch_counts(). إضافةً إلى ذلك، سيتم تعديل النموذج لعرض عدد أهم الزوّار والزيارات الأخيرة. يمكنك تجميع عدد الزائرين مع الزيارات الأخيرة من المكالمة إلى fetch_visits() وإفلاتها في context واحد للانتقال إلى نموذج الويب. في ما يلي الرمز قبل إجراء هذا التغيير وبعده:

قبل:

@app.route('/')
def root():
    'main application (GET) handler'
    store_visit(request.remote_addr, request.user_agent)
    visits = fetch_visits(10)
    return render_template('index.html', visits=visits)

بعد:

@app.route('/')
def root():
    'main application (GET) handler'
    store_visit(request.remote_addr, request.user_agent)
    context = {
        'limit':  LIMIT,
        'visits': fetch_visits(LIMIT),
        'counts': fetch_counts(LIMIT),
    }
    return render_template('index.html', **context)

في ما يلي جميع التغييرات المطلوبة على main.py، وفي ما يلي عرض مصوّر لتلك التعديلات لأغراض التوضيح لمنحك فكرة عامة عن التغييرات التي تجريها على main.py:

ad5fd3345efc13d0.png

تعديل نموذج الويب باستخدام بيانات العرض الجديدة

يتطلب نموذج الويب templates/index.html تحديثًا لعرض أهم الزوّار بالإضافة إلى الحمل العادي لأحدث الزوّار. إسقاط أهم الزوار وأعدادهم في جدول أعلى الصفحة ومواصلة عرض أحدث الزيارات كما في السابق. التغيير الوحيد الآخر هو تحديد الرقم المعروض من خلال متغير limit بدلاً من الترميز الثابت للرقم. وفي ما يلي التعديلات التي يجب إجراؤها على نموذج الويب:

قبل:

<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>

<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
    <li>{{ visit.timestamp.ctime() }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>

بعد:

<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>

<h1>VisitMe example</h1>

<h3>Top {{ limit }} visitors</h3>
<table border=1 cellspacing=0 cellpadding=2>
    <tr><th>Visitor</th><th>Visits</th></tr>
{% for count in counts %}
    <tr><td>{{ count.visitor|e }}</td><td align="center">{{ count.counter }}</td></tr>
{% endfor %}
</table>

<h3>Last {{ limit }} visits</h3>
<ul>
{% for visit in visits %}
    <li>{{ visit.timestamp.ctime() }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>

وبهذا نختتم التغييرات الضرورية التي تضيف استخدام مهام السحب في قائمة انتظار مهام App Engine إلى نموذج تطبيق الوحدة 1. يمثل الدليل الآن نموذج التطبيق للوحدة 18 ويجب أن يحتوي على الملفات التالية:

$ ls
README.md               appengine_config.py     queue.yaml              templates
app.yaml                main.py                 requirements.txt

6- الملخّص/تنظيف البيانات

يلخّص هذا القسم هذا الدرس التطبيقي حول الترميز من خلال نشر التطبيق، والتأكّد من أنّه يعمل على النحو المطلوب وفي أي نتائج أخرى. تشغيل العامل بشكل منفصل لمعالجة عدد الزائرين. بعد التحقّق من صحة التطبيق، نفِّذ أي خطوات تنظيف وفكِّر في الخطوات التالية.

نشر التطبيق والتحقق منه

يُرجى التأكّد من إعداد قائمة انتظار السحب كما فعلنا في الجزء العلوي من هذا الدرس التطبيقي مع gcloud app deploy queue.yaml. إذا اكتمل ذلك وكان نموذج التطبيق جاهزًا للاستخدام، انشر تطبيقك باستخدام gcloud app deploy. ينبغي أن تكون النتيجة مماثلة لتطبيق الوحدة 1 باستثناء أنه يعرض الآن "أهم الزوّار" الجدول في الجزء العلوي:

b667551dcbab1a09.png

على الرغم من أنّ الواجهة الأمامية الجديدة للويب تعرض أهم الزوّار وأحدث الزيارات، أدرك أنّ أعداد الزوّار لا تشمل الزيارة هذه. يعرض التطبيق عدد الزائرين السابقين مع إسقاط مهمة جديدة تزيد من عدد الزائرين في قائمة انتظار السحب، وهي مهمة تنتظر معالجتها.

يمكنك تنفيذ المهمة من خلال طلب الرقم /log، بعدة طرق:

على سبيل المثال، إذا استخدمت curl لإرسال طلب GET إلى /log، ستبدو الناتج على النحو التالي، لأنّك قدّمت PROJECT_ID:

$ curl https://PROJECT_ID.appspot.com/log
DONE (with 1 task[s] logging 1 visitor[s])

وبعد ذلك، سيظهر العدد المعدَّل في الزيارة التالية إلى الموقع الإلكتروني. هذا كل شيء!

تهانينا على إكمال هذا الدرس التطبيقي حول الترميز لإضافة استخدام خدمة قائمة انتظار السحب في قائمة مهام App Engine إلى نموذج التطبيق بنجاح. وهو جاهز الآن للنقل إلى Cloud Pub/Sub وCloud NDB وPython 3 في الوحدة 19.

تَنظيم

بنود عامة

إذا كنت قد انتهيت الآن، ننصحك بإيقاف تطبيق App Engine لتجنُّب تحمُّل تكلفة الفوترة. ومع ذلك، إذا أردت إجراء المزيد من الاختبارات أو التجارب، فمنصة App Engine لها حصة مجانية، ولن يتم تحصيل أي رسوم منك طالما أنك لا تتجاوز فئة الاستخدام هذه. هذه المعلومات متعلقة بالحوسبة، ولكن قد يتم أيضًا فرض رسوم على خدمات App Engine ذات الصلة، لذا يُرجى التحقق من صفحة الأسعار للحصول على مزيد من المعلومات. وإذا كانت عملية النقل هذه تشمل خدمات Cloud أخرى، يتم تحصيل الرسوم منها بشكل منفصل. وفي كلتا الحالتين، يمكنك الاطّلاع على قسم "الدروس التطبيقية حول الترميز" إذا كان ذلك منطبقًا. أدناه.

للإفصاح الكامل عن المعلومات، يتحمّل النشر على منصة حوسبة بدون خادم في Google Cloud مثل App Engine تكاليف بسيطة لإنشاء المحتوى وتخزينه. تمتلك خدمة Cloud Build حصتها المجانية الخاصة، كما هي الحال في Cloud Storage. يستهلك تخزين تلك الصورة بعضًا من هذه الحصة. ومع ذلك، قد تكون مقيمًا في منطقة لا يتوفر بها هذا المستوى المجاني، لذا عليك الانتباه إلى استخدام مساحة التخزين لتقليل التكاليف المحتملة. "مجلدات" محددة في Cloud Storage التي يجب عليك مراجعتها ما يلي:

  • console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
  • console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
  • تعتمد روابط مساحة التخزين أعلاه على PROJECT_ID و *LOC*، على سبيل المثال "us". إذا كان التطبيق مستضافًا في الولايات المتحدة الأمريكية

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

خصوصيّة هذا الدرس التطبيقي حول الترميز

الخدمات المدرَجة أدناه هي خدمات فريدة لهذا الدرس التطبيقي حول الترميز. ارجع إلى وثائق كل منتج لمزيد من المعلومات:

الخطوات التالية

في "النقل" هذا، لقد أضفت استخدام قائمة انتظار المهام إلى نموذج التطبيق للوحدة 1، عن طريق إضافة دعم لتتبع الزائرين، وبالتالي تنفيذ نموذج التطبيق للوحدة 18. في عملية النقل التالية، ستتم ترقية مهام سحب App Engine إلى Cloud Pub/Sub. اعتبارًا من أواخر عام 2021، لم يعُد مطلوبًا المستخدمين الانتقال إلى Cloud Pub/Sub عند الترقية إلى Python 3. يمكنك قراءة المزيد من المعلومات عن هذا الموضوع في القسم التالي.

لنقل البيانات إلى Cloud Pub/Sub، يُرجى الاطّلاع على الدرس التطبيقي حول الترميز للوحدة 19. بالإضافة إلى عمليات النقل الإضافية التي يجب أخذها في الاعتبار، مثل "مخزن البيانات في السحابة الإلكترونية" أو "مخزن الذاكرة في السحابة الإلكترونية" أو "مهام Cloud" أو "مهام Cloud" (قوائم انتظار الدفع) هناك أيضًا عمليات نقل على مستوى منتجات متعددة إلى Cloud Run وCloud Functions. يمكن الوصول إلى كل محتوى محطة النقل بدون خادم (الدروس التطبيقية حول الترميز والفيديوهات ورمز المصدر [في حال توفّره]) من خلال مستودع المصدر المفتوح التابع لها.

7. النقل إلى Python 3

في خريف 2021، وسّع فريق App Engine دعم العديد من الخدمات المجمّعة إلى بيئات تشغيل من الجيل الثاني (تتضمّن بيئة تشغيل من الجيل الأول). ونتيجةً لذلك، لم تعُد بحاجة إلى الانتقال من الخدمات المجمّعة، مثل قائمة انتظار مهام App Engine إلى خدمات السحابة الإلكترونية المستقلة أو الخدمات التابعة لجهات خارجية، مثل Cloud Pub/Sub، وذلك عند نقل تطبيقك إلى Python 3. بمعنى آخر، يمكنك الاستمرار في استخدام قائمة انتظار المهام في تطبيقات Python 3 App Engine طالما أنك تجري تعديلاً للرمز البرمجي للوصول إلى الخدمات المجمّعة من الجيل التالي من بيئات التشغيل.

يمكنك الاطّلاع على المزيد من المعلومات حول كيفية نقل استخدام الخدمات المجمّعة إلى Python 3 في الدرس التطبيقي حول ترميز الوحدة 17 والفيديو المقابل لها. في حين أن هذا الموضوع خارج نطاق الوحدة 18، إلا أن الروابط أدناه هي إصدارات Python 3 من تطبيق الوحدة 1 التي تم نقلها إلى Python 3 ولا يزال يستخدم App Engine NDB. (في مرحلة ما، سيتم أيضًا توفير إصدار Python 3 من تطبيق Module 18.)

8. مراجع إضافية

في ما يلي مراجع إضافية لمساعدة المطوّرين الذين يستكشفون وحدة نقل البيانات هذه أو وحدة النقل ذات الصلة بها وكذلك المنتجات ذات الصلة. يشمل ذلك أماكن لتقديم ملاحظات حول هذا المحتوى وروابط إلى التعليمات البرمجية ومستندات مختلفة قد تجدها مفيدة.

المشاكل/الملاحظات في الدرس التطبيقي حول الترميز

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

موارد نقل البيانات

يمكن العثور على روابط لمجلدات repo للوحدة 1 (START) والوحدة 18 (FINISH) في الجدول أدناه. ويمكن أيضًا الوصول إليها من المستودع لجميع عمليات نقل الدروس التطبيقية حول الترميز في App Engine. استنساخ الملف أو تنزيل ملف ZIP.

Codelab

Python 2

Python 3

الوحدة 1

الرموز البرمجية

code (الرمز) (غير مدرَج في هذا البرنامج التعليمي)

الوحدة 18 (هذا الدرس التطبيقي حول الترميز)

الرموز البرمجية

لا ينطبق

مراجع على الإنترنت

في ما يلي الموارد ذات الصلة بهذا البرنامج التعليمي:

قائمة مهام App Engine

منصة App Engine

مستندات App Engine

وقت تشغيل Python 2 App Engine (بيئة عادية)

وقت تشغيل Python 3 App Engine (بيئة عادية)

الاختلافات بين Python 2 3 بيئات تشغيل App Engine (بيئة عادية)

دليل نقل البيانات من الإصدار 2 إلى 3 من App Engine (البيئة العادية)

معلومات حول الأسعار والحصص في App Engine

إطلاق الجيل الثاني من منصة App Engine (2018)

إتاحة بيئات التشغيل القديمة على المدى الطويل

نماذج نقل بيانات المستندات

معلومات أخرى عن السحابة الإلكترونية

الفيديوهات

الترخيص

هذا العمل مرخّص بموجب رخصة المشاع الإبداعي 2.0 مع نسب العمل إلى مؤلف عام.