زنجیر کاری

WorkManager به شما امکان می‌دهد زنجیره‌ای از کارها را ایجاد و در صف قرار دهید که چندین وظیفه وابسته را مشخص می‌کند و ترتیب اجرای آنها را تعریف می‌کند. این قابلیت به ویژه زمانی مفید است که نیاز به اجرای چندین وظیفه با ترتیب خاص دارید.

برای ایجاد زنجیره‌ای از کارها، می‌توانید از WorkManager.beginWith(OneTimeWorkRequest) یا WorkManager.beginWith(List<OneTimeWorkRequest>) استفاده کنید که هر کدام نمونه‌ای از WorkContinuation برمی‌گردانند.

سپس می‌توان WorkContinuation برای افزودن نمونه‌های وابسته OneTimeWorkRequest با استفاده از then(OneTimeWorkRequest) یا then(List<OneTimeWorkRequest>) استفاده کرد.

هر فراخوانی WorkContinuation.then(...) یک نمونه جدید از WorkContinuation را برمی‌گرداند. اگر List از نمونه‌های OneTimeWorkRequest اضافه کنید، این درخواست‌ها می‌توانند به صورت موازی اجرا شوند.

در نهایت، می‌توانید از متد WorkContinuation.enqueue() برای enqueue() زنجیره‌ی WorkContinuation خود استفاده کنید.

بیایید به یک مثال نگاه کنیم. در این مثال، ۳ Worker job مختلف برای اجرا (به طور بالقوه به صورت موازی) پیکربندی شده‌اند. سپس نتایج این Workerها به هم متصل شده و به یک Worker job ذخیره سازی منتقل می‌شوند. در نهایت، خروجی آن کار به یک Worker آپلود منتقل می‌شود که نتایج را به یک سرور راه دور آپلود می‌کند.

کاتلین

WorkManager.getInstance(myContext)
   // Candidates to run in parallel
   .beginWith(listOf(plantName1, plantName2, plantName3))
   // Dependent work (only runs after all previous work in chain)
   .then(cache)
   .then(upload)
   // Call enqueue to kick things off
   .enqueue()

جاوا

WorkManager.getInstance(myContext)
   // Candidates to run in parallel
   .beginWith(Arrays.asList(plantName1, plantName2, plantName3))
   // Dependent work (only runs after all previous work in chain)
   .then(cache)
   .then(upload)
   // Call enqueue to kick things off
   .enqueue();

ادغام ورودی‌ها

وقتی نمونه‌های OneTimeWorkRequest را زنجیره می‌کنید، خروجی درخواست‌های کاری والد به عنوان ورودی به فرزندان ارسال می‌شود. بنابراین در مثال بالا، خروجی‌های plantName1 ، plantName2 و plantName3 به عنوان ورودی به درخواست cache ارسال می‌شوند.

برای مدیریت ورودی‌های چندین درخواست کاری والد، WorkManager از InputMerger استفاده می‌کند.

دو نوع مختلف از InputMerger توسط WorkManager ارائه می‌شود:

  • OverwritingInputMerger تلاش می‌کند تا تمام کلیدها را از تمام ورودی‌ها به خروجی اضافه کند. در صورت بروز تداخل، کلیدهای از پیش تنظیم شده را بازنویسی می‌کند.

  • ArrayCreatingInputMerger تلاش می‌کند ورودی‌ها را ادغام کند و در صورت لزوم آرایه ایجاد کند.

اگر مورد استفاده خاص‌تری دارید، می‌توانید با زیرکلاس کردن InputMerger مورد خودتان را بنویسید.

ادغام ورودی‌های بازنویسی‌شده

OverwritingInputMerger روش پیش‌فرض ادغام است. اگر در ادغام، تداخل کلید وجود داشته باشد، آخرین مقدار برای یک کلید، نسخه‌های قبلی را در داده‌های خروجی حاصل، بازنویسی می‌کند.

برای مثال، اگر ورودی‌های گیاه هر کدام یک کلید مطابق با نام متغیرهای مربوطه خود ( "plantName1" ، "plantName2" و "plantName3" ) داشته باشند، آنگاه داده‌های ارسالی به کارگر cache دارای سه جفت کلید-مقدار خواهند بود.

نموداری که سه کار را نشان می‌دهد که خروجی‌های مختلف را به کار بعدی در زنجیره منتقل می‌کنند. از آنجایی که سه خروجی همگی کلیدهای متفاوتی دارند، کار بعدی سه جفت کلید/مقدار دریافت می‌کند.

اگر تداخلی وجود داشته باشد، آخرین کارگر که کار را تمام کند «برنده» می‌شود و مقدار آن به cache منتقل می‌شود.

نموداری که سه کار را نشان می‌دهد که خروجی‌ها را به کار بعدی در زنجیره منتقل می‌کنند. در این حالت، دو تا از این کارها خروجی‌هایی با کلید یکسان تولید می‌کنند. در نتیجه، کار بعدی دو جفت کلید/مقدار دریافت می‌کند که یکی از خروجی‌های متضاد حذف می‌شود.

از آنجا که درخواست‌های کاری شما به صورت موازی اجرا می‌شوند، تضمینی برای ترتیب اجرای آنها ندارید. در مثال بالا، plantName1 می‌تواند مقدار "tulip" یا "elm" را در خود نگه دارد، بسته به اینکه کدام مقدار آخر نوشته شده باشد. اگر احتمال تداخل کلید وجود دارد و باید تمام داده‌های خروجی را در یک ادغام حفظ کنید، ArrayCreatingInputMerger ممکن است گزینه بهتری باشد.

ادغام ورودی آرایه

برای مثال بالا، با توجه به اینکه می‌خواهیم خروجی‌های همه کارگران با نام کارخانه را حفظ کنیم، باید از یک ArrayCreatingInputMerger استفاده کنیم.

کاتلین

val cache: OneTimeWorkRequest = OneTimeWorkRequestBuilder<PlantWorker>()
   .setInputMerger(ArrayCreatingInputMerger::class)
   .setConstraints(constraints)
   .build()

جاوا

OneTimeWorkRequest cache = new OneTimeWorkRequest.Builder(PlantWorker.class)
       .setInputMerger(ArrayCreatingInputMerger.class)
       .setConstraints(constraints)
       .build();

ArrayCreatingInputMerger هر کلید را با یک آرایه جفت می‌کند. اگر هر یک از کلیدها منحصر به فرد باشند، نتیجه شما مجموعه‌ای از آرایه‌های تک عنصری خواهد بود.

نموداری که سه کار را نشان می‌دهد که خروجی‌های مختلف را به کار بعدی در زنجیره ارسال می‌کنند. به کار بعدی سه آرایه ارسال می‌شود، یکی برای هر یک از کلیدهای خروجی. هر آرایه یک عضو دارد.

اگر هرگونه تداخل کلیدی وجود داشته باشد، مقادیر متناظر در یک آرایه گروه‌بندی می‌شوند.

نموداری که سه کار را نشان می‌دهد که خروجی‌ها را به کار بعدی در زنجیره منتقل می‌کنند. در این حالت، دو تا از این کارها خروجی‌هایی با کلید یکسان تولید می‌کنند. به کار بعدی دو آرایه، یکی برای هر کلید، ارسال می‌شود. یکی از آن آرایه‌ها دو عضو دارد، زیرا دو خروجی با آن کلید وجود داشته است.

وضعیت‌های زنجیره‌ای و کاری

زنجیره‌های OneTimeWorkRequest تا زمانی که کارشان با موفقیت انجام شود (یعنی Result.success() را برگردانند) به صورت متوالی اجرا می‌شوند. درخواست‌های کاری ممکن است در حین اجرا با شکست مواجه شوند یا لغو شوند، که این امر اثرات بعدی بر درخواست‌های کاری وابسته دارد.

وقتی اولین OneTimeWorkRequest در زنجیره‌ای از درخواست‌های کاری در صف قرار می‌گیرد، تمام درخواست‌های کاری بعدی تا زمان تکمیل کار آن درخواست کاری اول مسدود می‌شوند.

نموداری که زنجیره‌ای از کارها را نشان می‌دهد. اولین کار در صف قرار می‌گیرد؛ تمام کارهای بعدی تا زمان اتمام کار اول مسدود می‌شوند.

پس از قرار گرفتن در صف و برآورده شدن تمام محدودیت‌های کاری، اولین درخواست کار شروع به اجرا می‌کند. اگر کار با موفقیت در OneTimeWorkRequest ریشه یا List<OneTimeWorkRequest> تکمیل شود (یعنی Result.success() را برگرداند)، مجموعه بعدی درخواست‌های کار وابسته در صف قرار می‌گیرند.

نموداری که زنجیره‌ای از کارها را نشان می‌دهد. اولین کار با موفقیت انجام شده است و دو کار بعدی بلافاصله پس از آن در صف قرار گرفته‌اند. کارهای باقی‌مانده پس از اتمام کارهای قبلی مسدود شده‌اند.

مادامی که هر درخواست کار با موفقیت تکمیل شود، همین الگو در بقیه زنجیره درخواست‌های کار شما منتشر می‌شود تا زمانی که همه کارهای موجود در زنجیره تکمیل شوند. اگرچه این ساده‌ترین و اغلب مورد ترجیح است، اما مدیریت حالت‌های خطا نیز به همان اندازه مهم است.

وقتی خطایی هنگام پردازش درخواست کاری شما توسط یک worker رخ می‌دهد، می‌توانید آن درخواست را طبق سیاست backoff که تعریف می‌کنید، دوباره امتحان کنید. امتحان مجدد درخواستی که بخشی از یک زنجیره است به این معنی است که فقط آن درخواست با داده‌های ورودی ارائه شده به آن دوباره امتحان می‌شود. هر کاری که به صورت موازی اجرا می‌شود، تحت تأثیر قرار نخواهد گرفت.

نموداری که زنجیره‌ای از کارها را نشان می‌دهد. یکی از کارها با شکست مواجه شد، اما سیاست عقب‌نشینی برای آن تعریف شده بود. آن کار پس از گذشت مدت زمان مناسب دوباره اجرا خواهد شد. کارهای بعد از آن در زنجیره تا زمانی که با موفقیت اجرا شود، مسدود می‌شوند.

برای اطلاعات بیشتر در مورد تعریف استراتژی‌های سفارشی تلاش مجدد، به سیاست تلاش مجدد و بازگشت به عقب مراجعه کنید.

اگر آن سیاست تلاش مجدد تعریف نشده یا تمام شده باشد، یا به هر دلیلی به وضعیتی برسید که در آن یک OneTimeWorkRequest Result.failure() را برگرداند، آن درخواست کار و تمام درخواست‌های کار وابسته به عنوان FAILED.

نموداری که زنجیره‌ای از کارها را نشان می‌دهد. یک کار شکست خورده و قابل تکرار نیست. در نتیجه، تمام کارهای بعد از آن در زنجیره نیز شکست می‌خورند.

همین منطق در مورد لغو یک درخواست کاری OneTimeWorkRequest نیز صدق می‌کند. هر درخواست کاری وابسته نیز CANCELLED علامت‌گذاری می‌شود و کار آنها اجرا نخواهد شد.

نموداری که زنجیره‌ای از کارها را نشان می‌دهد. یک کار لغو شده است. در نتیجه، تمام کارهای بعد از آن در زنجیره نیز لغو شده‌اند.

توجه داشته باشید که اگر بخواهید درخواست‌های کاری بیشتری را به زنجیره‌ای که درخواست‌های کاری آن ناموفق یا لغو شده است، اضافه کنید، درخواست کاری که اخیراً اضافه کرده‌اید نیز به ترتیب با عنوان FAILED یا CANCELLED علامت‌گذاری خواهد شد. اگر می‌خواهید کار یک زنجیره موجود را گسترش دهید، به APPEND_OR_REPLACE در ExistingWorkPolicy مراجعه کنید.

هنگام ایجاد زنجیره‌هایی از درخواست‌های کاری، درخواست‌های کاری وابسته باید سیاست‌های تلاش مجدد را تعریف کنند تا اطمینان حاصل شود که کار همیشه به موقع تکمیل می‌شود. درخواست‌های کاری ناموفق می‌توانند منجر به زنجیره‌های ناقص و/یا وضعیت غیرمنتظره شوند.

برای اطلاعات بیشتر، به بخش لغو و توقف کار مراجعه کنید.