Изменить статус элемента в базе данных с помощью RxJava2 - PullRequest
0 голосов
/ 17 января 2019

Мы используем Room базу данных для хранения списка элементов, которые ожидают загрузки, каждый элемент имеет статус загрузки (WAITING, UPLOADING, UPLOADED и FAILED), нам нужно загружать их последовательно. Таким образом, у нас есть вариант использования, чтобы получить первый элемент WAITING или UPLOADING, и если мы обнаружили, что в базе данных есть элемент с состоянием UPLOADING, то мы не будем загружать другой элемент до завершения загрузки, тогда мы получим первый элемент WAITING в базу данных для загрузки. Мы обновляем статус элемента следующим образом doOnSubscribe(UPLOADING), onSuccess(UPLOADED) и onError(FAILED). Нам нужно начать другую загрузку независимо от успеха или неудачи.

private fun startUpload() {
        compositeDisposable.add(
                // Check if another item is uploading
                getFirstDeviceMediaByUploadStatusUseCase.execute(
                        GetFirstDeviceMediaByUploadStatusUseCase
                                .Params
                                .create(UploadStatus.UPLOADING))
                        .subscribeOn(executionThread.getIOThread())
                        .observeOn(executionThread.getMainThread())
                        .subscribe({
                            // If another item is uploading we do nothing
                        }, {
                            // If there is item with UPLOADING status then we will start upload first item waiting for upload
                            if (it is EmptyResultSetException) {
                                getFirstDeviceMediaByUploadStatusUseCase.execute(
                                        GetFirstDeviceMediaByUploadStatusUseCase
                                                .Params
                                                .create(UploadStatus.WAITING))
                                        .subscribeOn(executionThread.getIOThread())
                                        .observeOn(executionThread.getMainThread())
                                        .subscribe({ deviceMedia ->
                                            // Start uploading
                                            uploadDeviceMedia(deviceMedia)
                                        }, {
                                            VCLogger.i("No waiting files we should stop upload service")
                                            stopForegroundService()
                                        })
                            }
                        }))
    }

    private fun uploadDeviceMedia(deviceMedia: DeviceMediaEntity) {
        compositeDisposable.add(
                uploadDeviceMediaUseCase.execute(UploadDeviceMediaUseCase.Params.create(deviceMedia))
                        .subscribeOn(executionThread.getIOThread())
                        .observeOn(executionThread.getMainThread())
                        .doOnSubscribe {
                            VCLogger.i("Uploading... ${deviceMedia.path}")
                            deviceMedia.updatedAt = Date()
                            deviceMedia.uploadStatus = UploadStatus.UPLOADING
                            // Update device media status to UPLOADING
                            compositeDisposable.add(
                                    updateDeviceMediaUseCase.execute(UpdateDeviceMediaUseCase.Params.create(deviceMedia))
                                            .subscribeOn(executionThread.getIOThread())
                                            .observeOn(executionThread.getMainThread())
                                            .subscribe()
                            )
                        }
                        .subscribe({
                            VCLogger.i("Uploaded ${deviceMedia.path}")
                            deviceMedia.updatedAt = Date()
                            deviceMedia.uploadStatus = UploadStatus.UPLOADED
                            // Update device media status to UPLOADED then start upload another one
                            compositeDisposable.add(
                                    updateDeviceMediaUseCase.execute(UpdateDeviceMediaUseCase.Params.create(deviceMedia))
                                            .subscribeOn(executionThread.getIOThread())
                                            .observeOn(executionThread.getMainThread())
                                            .subscribe {
                                                startUpload()
                                            }
                            )
                        }, {
                            VCLogger.i("Failed to upload ${deviceMedia.path}")
                            deviceMedia.updatedAt = Date()
                            deviceMedia.uploadStatus = UploadStatus.FAILED
                            // Update device media status to FAILED then start upload another one
                            compositeDisposable.add(
                                    updateDeviceMediaUseCase.execute(UpdateDeviceMediaUseCase.Params.create(deviceMedia))
                                            .subscribeOn(executionThread.getIOThread())
                                            .observeOn(executionThread.getMainThread())
                                            .subscribe {
                                                startUpload()
                                            }
                            )
                        })
        )
    }

    private fun stopForegroundService() {
        VCLogger.i("Stop foreground service.")

        // Stop foreground service and remove the notification.
        stopForeground(true)

        // Stop the foreground service.
        stopSelf()
    }

Каков наилучший подход для достижения такого поведения?

...