Removed mutex from tab state

Workaround to make rebase interactive work again as it runs simultaneous operations
This commit is contained in:
Abdelilah El Aissaoui 2022-07-10 16:18:25 +02:00
parent d93e634a5c
commit d6a8b93026

View File

@ -34,7 +34,7 @@ class TabState @Inject constructor(
return git return git
} }
private val mutex = Mutex() // private val mutex = Mutex()
private val _refreshData = MutableSharedFlow<RefreshType>() private val _refreshData = MutableSharedFlow<RefreshType>()
val refreshData: Flow<RefreshType> = _refreshData val refreshData: Flow<RefreshType> = _refreshData
@ -46,9 +46,6 @@ class TabState @Inject constructor(
*/ */
@set:Synchronized @set:Synchronized
var operationRunning = false var operationRunning = false
get() {
return field || mutex.isLocked
}
private val _processing = MutableStateFlow(false) private val _processing = MutableStateFlow(false)
val processing: StateFlow<Boolean> = _processing val processing: StateFlow<Boolean> = _processing
@ -60,52 +57,49 @@ class TabState @Inject constructor(
callback: suspend (git: Git) -> Unit callback: suspend (git: Git) -> Unit
) = ) =
managerScope.launch(Dispatchers.IO) { managerScope.launch(Dispatchers.IO) {
mutex.withLock { var hasProcessFailed = false
var hasProcessFailed = false operationRunning = true
operationRunning = true
try { try {
delayedStateChange( delayedStateChange(
delayMs = 300, delayMs = 300,
onDelayTriggered = { onDelayTriggered = {
_processing.value = true _processing.value = true
}
) {
callback(safeGit)
} }
} catch (ex: Exception) { ) {
hasProcessFailed = true callback(safeGit)
ex.printStackTrace()
if (showError)
errorsManager.addError(newErrorNow(ex, ex.message.orEmpty()))
} finally {
_processing.value = false
operationRunning = false
if (refreshType != RefreshType.NONE && (!hasProcessFailed || refreshEvenIfCrashes))
_refreshData.emit(refreshType)
} }
} catch (ex: Exception) {
hasProcessFailed = true
ex.printStackTrace()
if (showError)
errorsManager.addError(newErrorNow(ex, ex.message.orEmpty()))
} finally {
_processing.value = false
operationRunning = false
if (refreshType != RefreshType.NONE && (!hasProcessFailed || refreshEvenIfCrashes))
_refreshData.emit(refreshType)
} }
} }
fun safeProcessingWihoutGit(showError: Boolean = true, callback: suspend CoroutineScope.() -> Unit) = fun safeProcessingWihoutGit(showError: Boolean = true, callback: suspend CoroutineScope.() -> Unit) =
managerScope.launch(Dispatchers.IO) { managerScope.launch(Dispatchers.IO) {
mutex.withLock { _processing.value = true
_processing.value = true operationRunning = true
operationRunning = true
try { try {
this.callback() this.callback()
} catch (ex: Exception) { } catch (ex: Exception) {
ex.printStackTrace() ex.printStackTrace()
if (showError) if (showError)
errorsManager.addError(newErrorNow(ex, ex.localizedMessage)) errorsManager.addError(newErrorNow(ex, ex.localizedMessage))
} finally { } finally {
_processing.value = false _processing.value = false
operationRunning = false operationRunning = false
}
} }
} }
@ -115,36 +109,34 @@ class TabState @Inject constructor(
refreshEvenIfCrashes: Boolean = false, refreshEvenIfCrashes: Boolean = false,
block: suspend (git: Git) -> Unit block: suspend (git: Git) -> Unit
) = managerScope.launch(Dispatchers.IO) { ) = managerScope.launch(Dispatchers.IO) {
mutex.withLock { var hasProcessFailed = false
var hasProcessFailed = false
operationRunning = true operationRunning = true
try { try {
block(safeGit) block(safeGit)
if (refreshType != RefreshType.NONE) if (refreshType != RefreshType.NONE)
_refreshData.emit(refreshType) _refreshData.emit(refreshType)
} catch (ex: Exception) { } catch (ex: Exception) {
ex.printStackTrace() ex.printStackTrace()
hasProcessFailed = true hasProcessFailed = true
if (showError) if (showError)
errorsManager.addError(newErrorNow(ex, ex.localizedMessage)) errorsManager.addError(newErrorNow(ex, ex.localizedMessage))
} finally { } finally {
launch { launch {
// Add a slight delay because sometimes the file watcher takes a few moments to notify a change in the // Add a slight delay because sometimes the file watcher takes a few moments to notify a change in the
// filesystem, therefore notifying late and being operationRunning already false (which leads to a full // filesystem, therefore notifying late and being operationRunning already false (which leads to a full
// refresh because there have been changes in the git dir). This can be easily triggered by interactive // refresh because there have been changes in the git dir). This can be easily triggered by interactive
// rebase. // rebase.
delay(500) delay(500)
operationRunning = false operationRunning = false
}
if (refreshType != RefreshType.NONE && (!hasProcessFailed || refreshEvenIfCrashes))
_refreshData.emit(refreshType)
} }
if (refreshType != RefreshType.NONE && (!hasProcessFailed || refreshEvenIfCrashes))
_refreshData.emit(refreshType)
} }
} }
@ -154,36 +146,34 @@ class TabState @Inject constructor(
refreshEvenIfCrashes: Boolean = false, refreshEvenIfCrashes: Boolean = false,
block: suspend (git: Git) -> Unit block: suspend (git: Git) -> Unit
) = withContext(Dispatchers.IO) { ) = withContext(Dispatchers.IO) {
mutex.withLock { var hasProcessFailed = false
var hasProcessFailed = false
operationRunning = true operationRunning = true
try { try {
block(safeGit) block(safeGit)
if (refreshType != RefreshType.NONE) if (refreshType != RefreshType.NONE)
_refreshData.emit(refreshType) _refreshData.emit(refreshType)
} catch (ex: Exception) { } catch (ex: Exception) {
ex.printStackTrace() ex.printStackTrace()
hasProcessFailed = true hasProcessFailed = true
if (showError) if (showError)
errorsManager.addError(newErrorNow(ex, ex.localizedMessage)) errorsManager.addError(newErrorNow(ex, ex.localizedMessage))
} finally { } finally {
launch { launch {
// Add a slight delay because sometimes the file watcher takes a few moments to notify a change in the // Add a slight delay because sometimes the file watcher takes a few moments to notify a change in the
// filesystem, therefore notifying late and being operationRunning already false (which leads to a full // filesystem, therefore notifying late and being operationRunning already false (which leads to a full
// refresh because there have been changes in the git dir). This can be easily triggered by interactive // refresh because there have been changes in the git dir). This can be easily triggered by interactive
// rebase. // rebase.
delay(500) delay(500)
operationRunning = false operationRunning = false
}
if (refreshType != RefreshType.NONE && (!hasProcessFailed || refreshEvenIfCrashes))
_refreshData.emit(refreshType)
} }
if (refreshType != RefreshType.NONE && (!hasProcessFailed || refreshEvenIfCrashes))
_refreshData.emit(refreshType)
} }
} }