mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-04-20 03:24:50 +00:00
WIP updating block for subscriptions
This commit is contained in:
parent
965e74c7e2
commit
dc9cc7b00f
2 changed files with 85 additions and 30 deletions
|
@ -19,6 +19,7 @@ import com.futo.platformplayer.stores.PluginIconStorage
|
|||
import com.futo.platformplayer.stores.PluginScriptsDirectory
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.Serializable
|
||||
|
@ -47,6 +48,8 @@ class StatePlugins {
|
|||
|
||||
private var _updatesAvailableMap: HashSet<String> = hashSetOf();
|
||||
|
||||
private val _isUpdating: HashSet<String> = hashSetOf();
|
||||
|
||||
fun getPluginIconOrNull(id: String): ImageVariable? {
|
||||
if(iconsDir.hasIcon(id))
|
||||
return iconsDir.getIconBinary(id);
|
||||
|
@ -58,6 +61,38 @@ class StatePlugins {
|
|||
.load();
|
||||
}
|
||||
|
||||
fun isUpdating(id: String): Boolean{
|
||||
synchronized(_isUpdating){
|
||||
return _isUpdating.contains(id);
|
||||
}
|
||||
}
|
||||
fun setIsUpdating(id: String, value: Boolean){
|
||||
synchronized(_isUpdating){
|
||||
if(value && !_isUpdating.contains(id)) {
|
||||
Logger.i(TAG, "PLUGIN [${id}] UPDATING");
|
||||
_isUpdating.add(id);
|
||||
}
|
||||
if(!value && _isUpdating.contains(id)) {
|
||||
Logger.i(TAG, "PLUGIN [${id}] NOT UPDATING");
|
||||
_isUpdating.remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
suspend fun whileUpdating(id: String, handle: suspend ()->Unit){
|
||||
try {
|
||||
setIsUpdating(id, true);
|
||||
handle();
|
||||
}
|
||||
finally {
|
||||
setIsUpdating(id, false);
|
||||
}
|
||||
}
|
||||
fun clearUpdating(){
|
||||
synchronized(_isUpdating) {
|
||||
_isUpdating.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
suspend fun checkForUpdates(): List<Pair<SourcePluginConfig, SourcePluginConfig>> = withContext(Dispatchers.IO) {
|
||||
var configs = mutableListOf<Pair<SourcePluginConfig, SourcePluginConfig>>()
|
||||
|
@ -430,42 +465,49 @@ class StatePlugins {
|
|||
|
||||
fun installPluginBackground(context: Context, scope: CoroutineScope, config: SourcePluginConfig, script: String, onProgress: (text: String, progress: Double)->Unit, onConcluded: (ex: Throwable?)->Unit) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
val client = ManagedHttpClient();
|
||||
try {
|
||||
whileUpdating(config.id) {
|
||||
withContext(Dispatchers.Main) {
|
||||
onProgress.invoke("Validating script", 0.25);
|
||||
onProgress.invoke("Waiting for plugins to finish", 0.1);
|
||||
}
|
||||
delay(500);
|
||||
|
||||
val tempDescriptor = SourcePluginDescriptor(config);
|
||||
val plugin = JSClient(context, tempDescriptor, null, script);
|
||||
plugin.validate();
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
onProgress.invoke("Downloading Icon", 0.5);
|
||||
}
|
||||
|
||||
val icon = config.absoluteIconUrl?.let { absIconUrl ->
|
||||
val client = ManagedHttpClient();
|
||||
try {
|
||||
withContext(Dispatchers.Main) {
|
||||
onProgress.invoke("Saving plugin", 0.75);
|
||||
onProgress.invoke("Validating script", 0.25);
|
||||
}
|
||||
val iconResp = client.get(absIconUrl);
|
||||
if(iconResp.isOk)
|
||||
return@let iconResp.body?.byteStream()?.use { it.readBytes() };
|
||||
return@let null;
|
||||
}
|
||||
val installEx = StatePlugins.instance.createPlugin(config, script, icon, true);
|
||||
if(installEx != null)
|
||||
throw installEx;
|
||||
StatePlatform.instance.updateAvailableClients(context);
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
onProgress.invoke("Finished", 1.0)
|
||||
onConcluded.invoke(null);
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Logger.e(TAG, ex.message ?: "null", ex);
|
||||
withContext(Dispatchers.Main) {
|
||||
onConcluded.invoke(ex);
|
||||
val tempDescriptor = SourcePluginDescriptor(config);
|
||||
val plugin = JSClient(context, tempDescriptor, null, script);
|
||||
plugin.validate();
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
onProgress.invoke("Downloading Icon", 0.5);
|
||||
}
|
||||
|
||||
val icon = config.absoluteIconUrl?.let { absIconUrl ->
|
||||
withContext(Dispatchers.Main) {
|
||||
onProgress.invoke("Saving plugin", 0.75);
|
||||
}
|
||||
val iconResp = client.get(absIconUrl);
|
||||
if (iconResp.isOk)
|
||||
return@let iconResp.body?.byteStream()?.use { it.readBytes() };
|
||||
return@let null;
|
||||
}
|
||||
val installEx = StatePlugins.instance.createPlugin(config, script, icon, true);
|
||||
if (installEx != null)
|
||||
throw installEx;
|
||||
StatePlatform.instance.updateAvailableClients(context);
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
onProgress.invoke("Finished", 1.0)
|
||||
onConcluded.invoke(null);
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Logger.e(TAG, ex.message ?: "null", ex);
|
||||
withContext(Dispatchers.Main) {
|
||||
onConcluded.invoke(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.futo.platformplayer.models.Subscription
|
|||
import com.futo.platformplayer.states.StateApp
|
||||
import com.futo.platformplayer.states.StateCache
|
||||
import com.futo.platformplayer.states.StatePlatform
|
||||
import com.futo.platformplayer.states.StatePlugins
|
||||
import com.futo.platformplayer.states.StateSubscriptions
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import java.time.OffsetDateTime
|
||||
|
@ -138,6 +139,18 @@ abstract class SubscriptionsTaskFetchAlgorithm(
|
|||
|
||||
for(task in tasks) {
|
||||
val forkTask = threadPool.submit<SubscriptionTaskResult> {
|
||||
if(StatePlugins.instance.isUpdating(task.client.id)){
|
||||
val isUpdatingException = ScriptCriticalException(task.client.config, "Plugin is updating");
|
||||
synchronized(failedPlugins) {
|
||||
//Fail all subscription calls to plugin if it has a critical issue
|
||||
if(isUpdatingException.config is SourcePluginConfig && !failedPlugins.contains(isUpdatingException.config.id)) {
|
||||
Logger.w(StateSubscriptions.TAG, "Subscriptions ignoring plugin [${isUpdatingException.config.name}] due to critical exception:\n" + isUpdatingException.message);
|
||||
failedPlugins.add(isUpdatingException.config.id);
|
||||
}
|
||||
}
|
||||
return@submit SubscriptionTaskResult(task, StateCache.instance.getChannelCachePager(task.sub.channel.url), isUpdatingException);
|
||||
}
|
||||
|
||||
if(task.fromPeek) {
|
||||
try {
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue