diff --git a/app/src/main/java/com/bartlomiejpluta/ttsserver/core/lua/loader/EndpointLoader.kt b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/lua/loader/EndpointLoader.kt index 4e20b67..6655344 100644 --- a/app/src/main/java/com/bartlomiejpluta/ttsserver/core/lua/loader/EndpointLoader.kt +++ b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/lua/loader/EndpointLoader.kt @@ -8,6 +8,7 @@ import com.bartlomiejpluta.ttsserver.core.lua.sandbox.SandboxFactory import com.bartlomiejpluta.ttsserver.core.web.endpoint.DefaultEndpoint import com.bartlomiejpluta.ttsserver.core.web.endpoint.Endpoint import com.bartlomiejpluta.ttsserver.core.web.endpoint.QueuedEndpoint +import com.bartlomiejpluta.ttsserver.core.web.queue.TasksQueueFactory import com.bartlomiejpluta.ttsserver.core.web.uri.UriTemplate import com.bartlomiejpluta.ttsserver.ui.main.MainActivity import fi.iki.elonen.NanoHTTPD.Method @@ -17,7 +18,8 @@ import java.io.File class EndpointLoader( private val context: Context, - private val sandboxFactory: SandboxFactory + private val sandboxFactory: SandboxFactory, + private val tasksQueueFactory: TasksQueueFactory ) { fun loadEndpoints(): List { @@ -57,18 +59,19 @@ class EndpointLoader( } private fun createDefaultEndpoint(luaTable: LuaTable): Endpoint = DefaultEndpoint( + consumer = parseConsumer(luaTable), uri = parseUri(luaTable), method = parseMethod(luaTable), - accepts = parseAccepts(luaTable), - consumer = parseConsumer(luaTable) + accepts = parseAccepts(luaTable) ) private fun createQueuedEndpoint(luaTable: LuaTable): Endpoint = QueuedEndpoint( context = context, + queue = tasksQueueFactory.create(), + consumer = parseConsumer(luaTable), uri = parseUri(luaTable), method = parseMethod(luaTable), - accepts = parseAccepts(luaTable), - consumer = parseConsumer(luaTable) + accepts = parseAccepts(luaTable) ) private fun parseUri(luaTable: LuaTable) = luaTable.get("path").checkjstring() diff --git a/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/endpoint/DefaultEndpoint.kt b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/endpoint/DefaultEndpoint.kt index 13609f1..d8c347f 100644 --- a/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/endpoint/DefaultEndpoint.kt +++ b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/endpoint/DefaultEndpoint.kt @@ -10,10 +10,10 @@ import java.io.File import java.io.FileInputStream class DefaultEndpoint( + private val consumer: LuaClosure, uri: UriTemplate, - accepts: String?, method: Method, - private val consumer: LuaClosure + accepts: String? ) : AbstractEndpoint(uri, accepts, method) { override fun safeHit(request: Request) = request.luaTable diff --git a/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/endpoint/QueuedEndpoint.kt b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/endpoint/QueuedEndpoint.kt index 6a4d291..de3020e 100644 --- a/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/endpoint/QueuedEndpoint.kt +++ b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/endpoint/QueuedEndpoint.kt @@ -2,31 +2,29 @@ package com.bartlomiejpluta.ttsserver.core.web.endpoint import android.content.Context import com.bartlomiejpluta.ttsserver.core.web.dto.Request +import com.bartlomiejpluta.ttsserver.core.web.queue.TasksQueue +import com.bartlomiejpluta.ttsserver.core.web.task.QueueableTask import com.bartlomiejpluta.ttsserver.core.web.uri.UriTemplate -import com.bartlomiejpluta.ttsserver.core.web.worker.Worker import fi.iki.elonen.NanoHTTPD import fi.iki.elonen.NanoHTTPD.newFixedLengthResponse import org.luaj.vm2.LuaClosure -import java.util.concurrent.LinkedBlockingQueue class QueuedEndpoint( - context: Context, + private val context: Context, + private val queue: TasksQueue, + private val consumer: LuaClosure, uri: UriTemplate, - accepts: String?, method: NanoHTTPD.Method, - consumer: LuaClosure + accepts: String? ) : AbstractEndpoint(uri, accepts, method) { - private val queue = LinkedBlockingQueue() - private val worker = Thread(Worker(context, queue, consumer)).also { it.name = uri.template } - override fun safeHit(request: Request): NanoHTTPD.Response? { - queue.add(request) + val task = QueueableTask(context, consumer, request, queue) + queue.push(task) return newFixedLengthResponse(NanoHTTPD.Response.Status.ACCEPTED, "text/plain", "") } - fun runWorker() = worker.start() - fun stopWorker() = worker.interrupt() + fun shutdownQueue() = queue.shutdown() override fun toString() = "Q[${uri.template}]" } \ No newline at end of file diff --git a/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/queue/TasksQueue.kt b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/queue/TasksQueue.kt new file mode 100644 index 0000000..79f177b --- /dev/null +++ b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/queue/TasksQueue.kt @@ -0,0 +1,9 @@ +package com.bartlomiejpluta.ttsserver.core.web.queue + +import com.bartlomiejpluta.ttsserver.core.web.task.QueueableTask + +interface TasksQueue { + fun push(queueableTask: QueueableTask) + fun shutdown() + val size: Int +} \ No newline at end of file diff --git a/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/queue/TasksQueueFactory.kt b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/queue/TasksQueueFactory.kt new file mode 100644 index 0000000..725afed --- /dev/null +++ b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/queue/TasksQueueFactory.kt @@ -0,0 +1,5 @@ +package com.bartlomiejpluta.ttsserver.core.web.queue + +class TasksQueueFactory { + fun create() = ThreadPoolBasedTasksQueue() +} \ No newline at end of file diff --git a/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/queue/ThreadPoolBasedTasksQueue.kt b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/queue/ThreadPoolBasedTasksQueue.kt new file mode 100644 index 0000000..89546ee --- /dev/null +++ b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/queue/ThreadPoolBasedTasksQueue.kt @@ -0,0 +1,22 @@ +package com.bartlomiejpluta.ttsserver.core.web.queue + +import com.bartlomiejpluta.ttsserver.core.web.task.QueueableTask +import java.util.concurrent.LinkedBlockingQueue +import java.util.concurrent.ThreadPoolExecutor +import java.util.concurrent.TimeUnit + +class ThreadPoolBasedTasksQueue : TasksQueue { + private val executor = ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, LinkedBlockingQueue()) + + override fun push(queueableTask: QueueableTask) { + executor.execute(queueableTask) + } + + override fun shutdown() { + executor.shutdown() + executor.awaitTermination(5L, TimeUnit.SECONDS) + } + + override val size: Int + get() = executor.queue.size +} \ No newline at end of file diff --git a/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/server/WebServer.kt b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/server/WebServer.kt index 9e8c008..489377d 100644 --- a/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/server/WebServer.kt +++ b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/server/WebServer.kt @@ -75,7 +75,6 @@ class WebServer( override fun start() { super.start() - queuedEndpoints.forEach { it.runWorker() } LocalBroadcastManager .getInstance(context) @@ -86,7 +85,7 @@ class WebServer( override fun stop() { super.stop() - queuedEndpoints.forEach { it.stopWorker() } + queuedEndpoints.forEach { it.shutdownQueue() } LocalBroadcastManager .getInstance(context) diff --git a/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/worker/Worker.kt b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/task/QueueableTask.kt similarity index 53% rename from app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/worker/Worker.kt rename to app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/task/QueueableTask.kt index a534d18..c03695a 100644 --- a/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/worker/Worker.kt +++ b/app/src/main/java/com/bartlomiejpluta/ttsserver/core/web/task/QueueableTask.kt @@ -1,38 +1,33 @@ -package com.bartlomiejpluta.ttsserver.core.web.worker +package com.bartlomiejpluta.ttsserver.core.web.task import android.content.Context import android.content.Intent import androidx.localbroadcastmanager.content.LocalBroadcastManager import com.bartlomiejpluta.R import com.bartlomiejpluta.ttsserver.core.web.dto.Request -import com.bartlomiejpluta.ttsserver.service.foreground.ForegroundService -import com.bartlomiejpluta.ttsserver.service.state.ServiceState +import com.bartlomiejpluta.ttsserver.core.web.queue.TasksQueue import com.bartlomiejpluta.ttsserver.ui.main.MainActivity import org.luaj.vm2.LuaClosure import org.luaj.vm2.LuaError import org.luaj.vm2.LuaInteger import org.luaj.vm2.LuaValue import org.luaj.vm2.lib.ZeroArgFunction -import java.util.concurrent.BlockingQueue -class Worker( +class QueueableTask( private val context: Context, - private val queue: BlockingQueue, - private val consumer: LuaClosure + private val consumer: LuaClosure, + private val request: Request, + private val queue: TasksQueue ) : Runnable { - override fun run() = try { - while (ForegroundService.state == ServiceState.RUNNING) { - consume(queue.take()) + + override fun run() { + try { + consumer.call(request.luaTable, QueueSizeFunction(queue)) + } catch (e: LuaError) { + handleLuaError(e) } - } catch (e: InterruptedException) { - Thread.currentThread().interrupt() } - private fun consume(request: Request) = try { - consumer.call(request.luaTable, QueueSizeFunction(queue)) - } catch (e: LuaError) { - handleLuaError(e) - } private fun handleLuaError(exception: LuaError) { LocalBroadcastManager @@ -43,7 +38,7 @@ class Worker( }) } - class QueueSizeFunction(private val queue: BlockingQueue) : ZeroArgFunction() { + class QueueSizeFunction(private val queue: TasksQueue) : ZeroArgFunction() { override fun call(): LuaInteger = LuaValue.valueOf(queue.size) } } \ No newline at end of file diff --git a/app/src/main/java/com/bartlomiejpluta/ttsserver/di/module/LuaModule.kt b/app/src/main/java/com/bartlomiejpluta/ttsserver/di/module/LuaModule.kt index a2f43a4..de69ca0 100644 --- a/app/src/main/java/com/bartlomiejpluta/ttsserver/di/module/LuaModule.kt +++ b/app/src/main/java/com/bartlomiejpluta/ttsserver/di/module/LuaModule.kt @@ -8,6 +8,7 @@ import com.bartlomiejpluta.ttsserver.core.lua.loader.EndpointLoader import com.bartlomiejpluta.ttsserver.core.lua.sandbox.SandboxFactory import com.bartlomiejpluta.ttsserver.core.tts.engine.TTSEngine import com.bartlomiejpluta.ttsserver.core.util.NetworkUtil +import com.bartlomiejpluta.ttsserver.core.web.queue.TasksQueueFactory import com.bartlomiejpluta.ttsserver.initializer.ScriptsInitializer import dagger.Module import dagger.Provides @@ -18,8 +19,12 @@ class LuaModule { @Provides @Singleton - fun endpointLoader(context: Context, sandboxFactory: SandboxFactory) = - EndpointLoader(context, sandboxFactory) + fun endpointLoader( + context: Context, + sandboxFactory: SandboxFactory, + tasksQueueFactory: TasksQueueFactory + ) = + EndpointLoader(context, sandboxFactory, tasksQueueFactory) @Provides @Singleton @@ -45,6 +50,10 @@ class LuaModule { sonosLibrary ) + @Provides + @Singleton + fun tasksQueueFactory() = TasksQueueFactory() + @Provides @Singleton fun threadLibrary() = ThreadLibrary() diff --git a/app/src/main/java/com/bartlomiejpluta/ttsserver/di/module/TTSModule.kt b/app/src/main/java/com/bartlomiejpluta/ttsserver/di/module/TTSModule.kt index d63528f..15b494d 100644 --- a/app/src/main/java/com/bartlomiejpluta/ttsserver/di/module/TTSModule.kt +++ b/app/src/main/java/com/bartlomiejpluta/ttsserver/di/module/TTSModule.kt @@ -62,7 +62,7 @@ class TTSModule { @Provides @Singleton - fun adudioConverter(context: Context) = AudioConverter(context) + fun audioConverter(context: Context) = AudioConverter(context) @Provides @Singleton