Avoiding a race conditions between two coroutine operations

I have two operations that are done using corroutines. Fetching from a preferences Datastore, and making an api (retrofit) call. The network call is dependent on knowing what type of Unit the user prefers (Fahrenheit, Celsius), so I need to get this data first before launching the network call.

I am not sure if I am creating a race condition here or if calling the suspend function like shown below is always going to follow the correct call order.

private suspend fun getUnits(): Units {
    var openWeatherUnits: Units = Units.FAHRENHEIT // default
    // Get Units
    dataStore.readStringDataStore(UNITS_KEY).first().let { units ->
        if (units != null) {
            println("units: $units")
            openWeatherUnits = Units.valueOf(units)
        }
    }
    return openWeatherUnits
}

private fun getWeatherData() {
    viewModelScope.launch(Dispatchers.IO) {
        val units = getUnits()

        // Make API call
        val response = apiService.getCurrentWeather(
            BuildConfig.OPEN_WEATHER_KEY,
            units.value
        )

    }
}

4

When you call the funstion getWeatherData() it launches a coroutine in viewModelScope. Internally getUnits(), containing another coroutine, is called so there are two coroutines right now ‘getWeatherData’ and ‘getUnits’.

Here the statement ‘val units = getUnits()’ will suspend ‘getWeatherData’ execution until ‘getUnits’ result is received. Once received it will go ahead.

So no race conditions here.

1

Your code will work perfectly fine, Api call will be made after the call getUnits() returns. But if you want to know how actually the problem can be generated here. I give you the example

// Note: Avoid this type of coding,
// this will launch two coroutines running at the same time.
// Here your API can be called even before getUnits() finishes.
fun getWeatherData() {
    var units: Units = Units.FAHRENHEIT // default
    // getUnits() function call here
    viewModelScope.launch(Dispatchers.IO) {
        units = getUnits()
    }
    // Api call here, it will not wait for the above code to be finished
    viewModelScope.launch(Dispatchers.IO) {
        val response = apiService.getCurrentWeather(
            BuildConfig.OPEN_WEATHER_KEY,
            units.value
        )
    }
}

calling suspend functions in different coroutines can create the problem in your case. but here you are right.

In sort, If you have 3 different suspend function and you want to execute them parallel your code could be

viewModelScope.launch(Dispatchers.IO) { fun1() }
viewModelScope.launch(Dispatchers.IO) { fun2() }
viewModelScope.launch(Dispatchers.IO) { fun3() }

this is helpful if you want to call three different API at the same time which are total independent from each other,

But if you want call the suspend function one after other, you can write something like this. e.g. if you want to call fun2() first then fun3() and fun1() at last

viewModelScope.launch(Dispatchers.IO) { 
    fun2() 
    fun3() // will be called after fun2() finished
    fun1() // will be called after fun1() finished
}

Note: You are right with your code, my code is only for information. do not consider this as the solution of your question

2

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật