Coroutine Builder — Kotlin Coroutines ফাংশন যা করুটিন তৈরি এবং চালু করে, তাদের সম্পাদনের পদ্ধতি নির্ধারণ করে। বিল্ডার launch, async, runBlocking এবং produce বিভিন্ন পরিস্থিতি কভার করে: ব্যাকগ্রাউন্ড টাস্ক থেকে ফলাফল ফেরত সহ সমান্তরাল গণনা পর্যন্ত। JetBrains, 2024 অনুসারে, Coroutine Builder করুটিন মডেলের ভিত্তি, যা কাঠামোবদ্ধ সমবর্তিতা এবং জীবনচক্র ব্যবস্থাপনা প্রদান করে।
মূল পয়েন্ট
Coroutine Builder একটি Kotlin এক্সটেনশন ফাংশন যা CoroutineScope এবং একটি suspend ব্লক নেয়, একটি নতুন করুটিন তৈরি এবং চালু করে। প্রতিটি বিল্ডার নির্ধারণ করে করুটিন কীভাবে সম্পাদিত হবে: ফলাফল সহ বা ছাড়া, থ্রেড ব্লকিং সহ বা অ্যাসিঙ্ক্রোনাসভাবে। বিল্ডারগুলি ভাষার করুটিন মডেলের প্রবেশ পয়েন্ট।
সমস্ত বিল্ডার CoroutineScope-এর মাধ্যমে কাজ করে, যা চাইল্ড করুটিনের জীবনচক্র পরিচালনা করে। যখন কোনো স্কোপ বাতিল করা হয়, তখন এর মাধ্যমে চালু করা সমস্ত করুটিন স্বয়ংক্রিয়ভাবে বাতিল হয়ে যায় — এটি কাঠামোবদ্ধ সমবর্তিতার নীতি। এই পদ্ধতি করুটিন লিক প্রতিরোধ করে এবং পূর্বাভাসযোগ্য সমাপ্তি নিশ্চিত করে।
import kotlinx.coroutines.*
fun main() = runBlocking {
// বিল্ডারগুলি CoroutineScope-এর মধ্যে চলে
val job = launch {
delay(1000L)
println("বিশ্ব!")
}
println("হ্যালো,")
job.join()
}
Kotlin চারটি অন্তর্নির্মিত করুটিন বিল্ডার প্রদান করে: launch, async, runBlocking এবং produce। প্রতিটির নিজস্ব রিটার্ন টাইপ এবং প্রয়োগের ক্ষেত্র রয়েছে। Android মোবাইল ডেভেলপমেন্টের জন্য, প্রধান বিল্ডার হল launch এবং async — এগুলি অ-অবরোধকারী পদ্ধতিতে কাজ করে এবং আর্কিটেকচারাল উপাদানগুলির সাথে সংহত হয়।
| বিল্ডার | রিটার্ন টাইপ | থ্রেড ব্লকিং | পরিস্থিতি |
|---|---|---|---|
| launch | Job | না | Fire-and-forget কাজ |
| async | Deferred<T> | না | সমান্তরাল গণনা |
| runBlocking | T | হ্যাঁ | পরীক্ষা, main ফাংশন |
| produce | ReceiveChannel<E> | না | স্ট্রিমিং (অপ্রচলিত) |
প্রতিটি বিল্ডার অতিরিক্ত প্যারামিটার গ্রহণ করে: CoroutineStart (চালু কৌশল), CoroutineContext (ডিসপ্যাচার, ব্যতিক্রম) এবং একটি নামযুক্ত কোড ব্লক। ডিফল্টরূপে, করুটিন অবিলম্বে শুরু হয় (CoroutineStart.DEFAULT)।
launch Android ডেভেলপমেন্টে সবচেয়ে বেশি ব্যবহৃত বিল্ডার। এটি একটি করুটিন চালু করে যা ফলাফল ফেরত দেয় না, এবং তার জীবনচক্র পরিচালনার জন্য একটি Job অবজেক্ট ফেরত দেয়। এটি সেই অপারেশনগুলির জন্য আদর্শ পছন্দ যেখানে শুধুমাত্র পার্শ্ব প্রতিক্রিয়া প্রয়োজন: ডাটাবেসে সংরক্ষণ, অ্যানালিটিক্স পাঠানো, UI আপডেট করা।
launch বিল্ডার CoroutineScope, একটি ঐচ্ছিক CoroutineContext এবং একটি suspend ব্লক গ্রহণ করে। ফেরত দেওয়া Job করুটিন বাতিল করা, তার সমাপ্তির জন্য অপেক্ষা করা বা তার অবস্থা পরীক্ষা করার অনুমতি দেয়।
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
val job: Job = scope.launch(CoroutineStart.LAZY) {
val data = fetchFromNetwork()
saveToDatabase(data)
}
job.start()
job.join()
CoroutineStart.LAZY প্যারামিটার start() বা join()-এর স্পষ্ট কল পর্যন্ত সম্পাদন স্থগিত করে। এটি বিলম্বিত আরম্ভ এবং শর্তসাপেক্ষ সম্পাদনের জন্য দরকারী। মানক তাত্ক্ষণিক সম্পাদনের জন্য CoroutineStart.DEFAULT ব্যবহার করা হয় বা প্যারামিটার বাদ দেওয়া হয়।
async একটি বিল্ডার যা Deferred<T> ফেরত দেয় — ফলাফলের একটি অ্যাসিঙ্ক্রোনাস প্রতিশ্রুতি। await() কল করা ফলাফল প্রাপ্ত না হওয়া পর্যন্ত করুটিনকে স্থগিত করে, থ্রেড না ব্লক করে। এটি Kotlin করুটিনে সমান্তরাল কাজের জন্য প্রাথমিক প্রক্রিয়া।
async বিশেষভাবে কার্যকর যখন আপনাকে একসাথে Multiple স্বাধীন অপারেশন সম্পাদন করতে হয়। suspend ফাংশনের অনুক্রমিক কলের বিপরীতে, async করুটিনকে সমান্তরালে চালু করে, মোট সম্পাদন সময় হ্রাস করে।
suspend fun fetchUserData(): UserData {
val deferred1 = CoroutineScope(Dispatchers.IO).async { api.getProfile() }
val deferred2 = CoroutineScope(Dispatchers.IO).async { api.getSettings() }
val deferred3 = CoroutineScope(Dispatchers.IO).async { api.getNotifications() }
return UserData(
profile = deferred1.await(),
settings = deferred2.await(),
notifications = deferred3.await()
)
}
Deferred Job থেকে উত্তরাধিকার সূত্রে প্রাপ্ত, তাই async সমস্ত জীবনচক্র অপারেশন সমর্থন করে: বাতিলকরণ, সমাপ্তির অপেক্ষা, ব্যতিক্রম হ্যান্ডলিং। যখন একটি স্কোপ বাতিল করা হয়, চাইল্ড Deferred করুটিন স্বয়ংক্রিয়ভাবে বাতিল হয়ে যায়।
runBlocking একমাত্র বিল্ডার যা করুটিন সম্পূর্ণ না হওয়া পর্যন্ত বর্তমান থ্রেড ব্লক করে। এটি একটি নতুন CoroutineScope তৈরি করে এবং পাস করা করুটিন চালু করে, কলকারী থ্রেড ব্লক করে। এটি main() প্রবেশ পয়েন্টে, পরীক্ষায় এবং blocking কোডের সাথে সংহত করার সময় ব্যবহৃত হয়।
runBlocking তিনটি পরিস্থিতিতে ন্যায়সঙ্গত: অ্যাপ্লিকেশন প্রবেশ পয়েন্ট (main), suspend ফাংশনের ইউনিট পরীক্ষা এবং কলব্যাক-ভিত্তিক লাইব্রেরির সাথে সংহতকরণ যেখানে suspend ব্যবহার করা যায় না। প্রোডাকশন Android কোডে, প্রধান থ্রেডে runBlocking ব্যবহার দৃঢ়ভাবে সুপারিশ করা হয় না।
class CoroutineTest {
@Test
fun `test suspend function`() = runBlocking {
val result = mySuspendFunction()
assertEquals("expected", result)
}
}
পরীক্ষার জন্য, runBlocking-এর পরিবর্তে TestCoroutineDispatcher সহ kotlinx-coroutines-test ব্যবহার করার পরামর্শ দেওয়া হয় — এটি সময় নিয়ন্ত্রণ প্রদান করে এবং পরীক্ষার পরিবেশে ব্লকিং এড়ায়।
Coroutine Builder-এর পছন্দ ফেরত দেওয়া ফলাফল এবং সম্পাদন পরিস্থিতির উপর নির্ভর করে। যদি অপারেশনের ডেটা ফেরত দেওয়ার প্রয়োজন না হয় — launch ব্যবহার করুন। যদি আপনার অ্যাসিঙ্ক্রোনাস অপারেশনের ফলাফলের প্রয়োজন হয় — async ব্যবহার করুন। শুধুমাত্র ব্রিজিংয়ের জন্য runBlocking ব্যবহার করুন, এবং রিঅ্যাকটিভ স্ট্রিমের জন্য produce-কে Flow দিয়ে প্রতিস্থাপন করুন।
Kotlin Coroutines ব্যবহার করে Android প্রকল্পগুলিতে, বিল্ডারগুলির প্রধান জুটি হল launch এবং async। launch ViewModel এবং UseCases-এ করুটিন চালু করতে ব্যবহৃত হয়, যখন async নেটওয়ার্ক বা ডাটাবেসে সমান্তরাল অনুরোধের জন্য ব্যবহৃত হয়। আধুনিক লাইব্রেরি (Ktor, Room) ইতিমধ্যে suspend ফাংশন সমর্থন করে, যা async-এর সরাসরি ব্যবহারের প্রয়োজনীয়তা হ্রাস করে।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
launch Job ফেরত দেয় এবং সম্পাদনের ফলাফল ফেরত দেয় না, যখন async Deferred<T> ফেরত দেয় — একটি অবজেক্ট যা থেকে await()-এর মাধ্যমে ফলাফল পাওয়া যায়। launch fire-and-forget অপারেশনের জন্য, async ডেটা ফেরত দেয় এমন কাজের জন্য ব্যবহৃত হয়।
সুপারিশ করা হয় না। প্রধান থ্রেডে runBlocking ANR সৃষ্টি করে এবং UI ব্লক করে। Activity এবং Fragment-এর ভিতরে lifecycleScope.launch ব্যবহার করুন — এটি ব্লকিং ছাড়াই একটি অন্তর্নির্মিত সমাধান।
launch বিল্ডার একটি Job অবজেক্ট ফেরত দেয়, যা করুটিনের জীবনচক্র নিয়ন্ত্রণ করতে দেয়: বাতিল (cancel), সমাপ্তির অপেক্ষা (join), অবস্থা পরীক্ষা (isActive, isCompleted, isCancelled)।
Deferred<T> ফলাফলের একটি অ্যাসিঙ্ক্রোনাস প্রতিশ্রুতি, যা async বিল্ডার দ্বারা ফেরত দেওয়া হয়। এটি Job থেকে উত্তরাধিকার সূত্রে প্রাপ্ত এবং পদ্ধতি যোগ করে: ফলাফল পাওয়ার জন্য await(), নন-ব্লকিং অ্যাক্সেসের জন্য getCompleted(), এবং ব্যতিক্রম পরীক্ষার জন্য getCompletionExceptionOrNull()।
CoroutineStart.LAZY প্যারামিটার ব্যবহার করুন: scope.launch(start = CoroutineStart.LAZY) { ... }। তারপর প্রকৃত সম্পাদনের জন্য job.start() বা job.join() কল করুন। এটি বিলম্বিত আরম্ভ এবং শর্তসাপেক্ষ করুটিন সম্পাদনের জন্য দরকারী।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন