Skip to content
Snippets Groups Projects
Commit 70bb05f6 authored by Clément Pit-Claudel's avatar Clément Pit-Claudel
Browse files

server: Stop clock when no users are connected

parent 5f1472db
Branches
Tags
1 merge request!31server: Add a GarbageCollection
......@@ -10,8 +10,6 @@ import scala.collection.mutable
import scala.util.{Success, Failure, Try}
import scala.concurrent.duration.Duration
import cask.endpoints.WsChannelActor
case class BroadcastException(ex: Throwable) extends Throwable
/** Server-side apps definition and abstractions */
......@@ -86,8 +84,7 @@ private[web] abstract class ServerApp:
handleMessage(userId, ujson.read(data))
}
def disconnect(userId: UserId, channel: WsChannelActor): Unit = instanceLock.synchronized:
recordActivity()
def disconnect(userId: UserId, channel: cask.endpoints.WsChannelActor): Unit = instanceLock.synchronized:
channels(userId).remove(channel)
if channels(userId).isEmpty then channels.remove(userId)
println(f"[${appInfo.id}/$instanceId] client \"$userId\" disconnected")
......@@ -96,11 +93,14 @@ private[web] abstract class ServerApp:
def connectedClients: Seq[UserId] = instanceLock.synchronized:
channels.keysIterator.toSeq
def hasClients = instanceLock.synchronized:
channels.nonEmpty
def shutdown() = instanceLock.synchronized:
for channels <- channels.values
channel <- channels
do
channel.send(cask.Ws.Close())
for channels <- channels.values
channel <- channels
do
channel.send(cask.Ws.Close())
/** Sends a message to a specific client. */
private def send(userId: UserId)(message: ujson.Value): Unit = instanceLock.synchronized:
......@@ -178,8 +178,6 @@ private[web] final class ClockDrivenStateMachineServerApp[E, S, V](
val name = f"${appInfo.id}/$instanceId/clock"
Clock(name, sm.clockPeriodMs)(handleClockTick)
clock.start()
def handleClockTick: Unit = instanceLock.synchronized:
try
val event = Left(Tick(System.currentTimeMillis))
......@@ -189,6 +187,17 @@ private[web] final class ClockDrivenStateMachineServerApp[E, S, V](
catch ex =>
println(f"[${appInfo.id}/$instanceId] Uncaught exception in clock action: $ex")
override def connect(userId: UserId)
(implicit cc: castor.Context, log: cask.Logger)
: cask.WebsocketResult = instanceLock.synchronized:
if !hasClients then clock.start()
super.connect(userId)
override def disconnect(userId: UserId, channel: cask.endpoints.WsChannelActor)
: Unit = instanceLock.synchronized:
super.disconnect(userId, channel)
if !hasClients then clock.shutdown()
override def shutdown(): Unit =
clock.shutdown()
super.shutdown()
......@@ -60,12 +60,12 @@ object WebServer:
private[web] def createInstance(appId: AppId, registeredUserIds: Seq[UserId]): InstanceId =
withFreshInstanceId: instanceId =>
instances(instanceId) = appDirectory(appId).init(instanceId, registeredUserIds)
println(f"[$appId] instance created $instanceId")
println(f"[$appId/$instanceId] instance created")
instanceId
private[web] def shutdownApp(instanceId: InstanceId): Unit =
instances.remove(instanceId).map: app =>
app.shutdown()
println(s"[${app.appInfo.id}][$instanceId] shut down")
println(f"[${app.appInfo.id}/$instanceId] instance shut down")
GarbageCollector.start()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment