google / ExoPlayer

This project is deprecated and stale. The latest ExoPlayer code is available in https://github.com/androidx/media
https://developer.android.com/media/media3/exoplayer
Apache License 2.0
21.7k stars 6.02k forks source link

DownloadIndex has not update status, when we got SQLiteFullException: database or disk is full #8756

Open KaplunSergey opened 3 years ago

KaplunSergey commented 3 years ago

Hello, I have a situation, when I tried to download multiple media items and my device didn't have enough memory for it. So, when memory is over, I got an event in DownloadManager.Listener.onDownloadChanged() - Download.STATE_FAILED and exception:

com.google.android.exoplayer2.upstream.cache.Cache$CacheException: com.google.android.exoplayer2.database.DatabaseIOException: android.database.sqlite.SQLiteException: cannot rollback - no transaction is active (code 1 SQLITE_ERROR)

Ok, but when I wanted to show current download state for all media items(I use downloadManager.downloadIndex.getDownloads() for it), I saw that my media Item didn't have STATE_FAILED status, it had previous status(STATE_DOWNLOADING).

Could you explain please, is it normal logic for this situation?

andrewlewis commented 3 years ago

@marcbaechinger @ojw28 Please could you take a look?

marcbaechinger commented 3 years ago

I'm not sure what exactly happens in your case. In general I think that when you instantiate the DownloadManager you need to provide a DatabaseProvider and a Cache. Given these two are configured in a way, that the database file and the cache directory is on the same volume, then the disk full you are experiencing may not only make the download fail, but also cause the database a problem that a change can not be written to the database file anymore.

The exception you are referring to above is a database exception, that indicates that the database had a problem. Later you are calling downloadManager.downloadIndex.getDownloads() which then may return the last state of the database that does not include the update of the state of the download that has been reported with DownloadManager.Listener.onDownloadChanged().

Could you explain please, is it normal logic for this situation?

Difficult to say with the information I'm having. I haven't try to repro this myself tbh.

The above is my guess what is happening. Can you confirm that the database index and the download directory is on the same volume and hence are probably both affected by the disk full situation?

KaplunSergey commented 3 years ago

you need to provide a DatabaseProvider and a Cache

Ye, I provided Databaseand Cache for DownloadManager.

Given these two are configured in a way, that the database file and the cache directory is on the same volume, then the disk full you are experiencing may not only make the download fail, but also cause the database a problem that a change can not be written to the database file anymore.

Yes, Database file and Cache are on the same volume. And I think, you are right about this situation, that memory not enough to save error state to the DownloadIndex.

Last question. What do you think, If I will not have available space on a device, I will be able to pause downloads by DownloadService.sendPauseDownloads()? Thank you