improve relay UI logs

pull/3627/head
Thibault Duplessis 2017-10-05 00:59:35 -05:00
parent fd95537740
commit b4f9a12b19
5 changed files with 39 additions and 15 deletions

View File

@ -43,10 +43,10 @@ private final class RelayFetch(
else fetcher(relay.sync.upstream) flatMap { games =>
sync(relay, games)
.withTimeout(300 millis, LilaException("In progress"))(context.system)
} flatMap { res =>
addLog(relay.id, SyncLog.event(none)) inject res
} flatMap { nbMoves =>
addLog(relay.id, SyncLog.event(nbMoves, none))
} recover {
case e: Exception => addLog(relay.id, SyncLog.event(e.some))
case e: Exception => addLog(relay.id, SyncLog.event(0, e.some))
}
}.sequenceFu.chronometer
.result addEffectAnyway scheduleNext

View File

@ -10,25 +10,28 @@ private final class RelaySync(
chapterRepo: ChapterRepo
) {
def apply(relay: Relay, games: RelayGames): Funit = studyApi byId relay.studyId flatMap {
private type NbMoves = Int
def apply(relay: Relay, games: RelayGames): Fu[NbMoves] = studyApi byId relay.studyId flatMap {
_ ?? { study =>
for {
chapters <- chapterRepo orderedByStudy study.id
_ <- lila.common.Future.traverseSequentially(games) { game =>
movesPerGame <- lila.common.Future.traverseSequentially(games) { game =>
chapters.find(_.tags(idTag) has game.id) match {
case Some(chapter) => updateChapter(study, chapter, game)
case None => createChapter(study, game) flatMap { chapter =>
chapters.find(_.isEmptyInitial).ifTrue(chapter.order == 2) ?? { initial =>
chapters.find(_.isEmptyInitial).ifTrue(chapter.order == 2).?? { initial =>
studyApi.deleteChapter(study.ownerId, study.id, initial.id, socketUid)
}
} inject chapter.root.mainline.size
}
}
}
} yield ()
nbMoves = movesPerGame.foldLeft(0)(_ + _)
} yield nbMoves
}
}
private def updateChapter(study: Study, chapter: Chapter, game: RelayGame): Funit = {
private def updateChapter(study: Study, chapter: Chapter, game: RelayGame): Fu[NbMoves] = {
game.root.mainline.foldLeft(Path.root -> none[Node]) {
case ((parentPath, None), gameNode) =>
val path = parentPath + gameNode
@ -55,8 +58,8 @@ private final class RelaySync(
position = Position(chapter, path).ref,
toMainline = true,
uid = socketUid
)
case (path, None) => funit // no new nodes were found
) inject 0
case (path, None) => fuccess(0) // no new nodes were found
case (path, Some(node)) => // append new nodes to the chapter
lila.common.Future.fold(node.mainline)(Position(chapter, path)) {
case (position, n) => studyApi.doAddNode(
@ -67,7 +70,7 @@ private final class RelaySync(
uid = socketUid,
opts = moveOpts.copy(clock = n.clock)
) flatten s"Can't add relay node $position $node"
} void
} inject node.mainline.size
}
}

View File

@ -16,6 +16,7 @@ object SyncLog {
val historySize = 5
case class Event(
moves: Int,
error: Option[String],
at: DateTime
) {
@ -23,7 +24,8 @@ object SyncLog {
def isKo = error.nonEmpty
}
def event(e: Option[Exception]) = Event(
def event(moves: Int, e: Option[Exception]) = Event(
moves = moves,
error = e map {
case e: java.util.concurrent.TimeoutException => "Request timeout"
case e: Exception => e.getMessage take 100

View File

@ -11,6 +11,7 @@ export interface RelaySync {
}
export interface LogEvent {
moves: number;
error?: string;
at: number;
}

View File

@ -2,6 +2,7 @@ import { h } from 'snabbdom';
import { VNode } from 'snabbdom/vnode';
import RelayCtrl from './relayCtrl';
import { iconTag, bind } from '../../util';
import { LogEvent } from './interfaces';
export default function(ctrl: RelayCtrl): VNode | undefined {
const d = ctrl.data;
@ -22,6 +23,13 @@ export default function(ctrl: RelayCtrl): VNode | undefined {
]);
}
function logSuccess(e: LogEvent) {
return [
e.moves ? h('strong', '' + e.moves) : e.moves,
` new move${e.moves > 1 ? 's' : ''}`
];
}
function renderLog(ctrl: RelayCtrl) {
console.log(ctrl.loading());
const logLines = ctrl.data.sync.log.slice(0).reverse().map(e => {
@ -36,8 +44,8 @@ function renderLog(ctrl: RelayCtrl) {
}, [
iconTag(err ? 'j' : 'E'),
h('div', [
err || 'Success',
h('time', window.lichess.timeago.absolute(e.at))
...(err ? [err] : logSuccess(e)),
h('time', dateFormatter(new Date(e.at)))
])
]);
});
@ -75,3 +83,13 @@ function stateOff(ctrl: RelayCtrl) {
h('div.fat', 'Click to connect')
]);
}
const dateFormatter: (date: Date) => string =
(window.Intl && Intl.DateTimeFormat) ?
new Intl.DateTimeFormat(document.documentElement.lang, {
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
}).format : function(d) { return d.toLocaleString(); }