ProgressTrackingFileWatcher.scala 3.94 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//
// Copyright (C) 2019 ESA, TU Darmstadt
//
// This file is part of Tapasco (TPC).
//
// Tapasco is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tapasco is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Tapasco.  If not, see <http://www.gnu.org/licenses/>.
//
package de.tu_darmstadt.cs.esa.tapasco.filemgmt

import de.tu_darmstadt.cs.esa.tapasco.Logging._
import de.tu_darmstadt.cs.esa.tapasco.util.Listener
import MultiFileWatcher._
import Events._
import ProgressTrackingFileWatcher._

27
import scala.concurrent.duration.Duration
28

29
30
31
32
33
34
35
/**
  * A [[MultiFileWatcher]] which tracks the overall logfile.
  * Using a FSM, the current state of the Compose Progression is Determined and Logged
  * to give the user an overview how far the compose-Task has progressed.
  * @param _logger Optional logger instance to use.
  * @param pollInterval Polling interval in ms (default: [[MultiFileWatcher.POLL_INTERVAL]]).
  */
36
37
38
39
40
class ProgressTrackingFileWatcher(_logger: Option[Logger] = None, pollInterval: Int = POLL_INTERVAL)
  extends MultiFileWatcher(POLL_INTERVAL) {
  private[this] final val logger = _logger getOrElse de.tu_darmstadt.cs.esa.tapasco.Logging.logger(getClass)

  var currentState: Int = -1
41
42
43
  val start: Long = System.currentTimeMillis()
  var stageStart: Long = System.currentTimeMillis()
  var lastLog: Long = 0
44
45
46

  private lazy val listener = new Listener[Event] {
    def update(e: MultiFileWatcher.Event): Unit = e match {
47
48
49
50
      case LinesAdded(src, ls) => {
        ls foreach {l =>
          checkState(l)
        }
51
52
53
54
      }
    }
  }

55
56
57
58
59
60
  /**
    * Checks whether a transition has occured depending on the current line of the log.
    * If so, the corresponding new state is logged.
    * Additionally, the finished State is also logged with its runtime.
    * @param string parsed String
    */
61
62
63
64
65
66
67
68
69
70
71
72
  private def checkState(string: String): Unit = {
    val old = currentState
    if(currentState == -1) {
      currentState = currentState + 1
    }
    for(i <- progressionStringsInfo.indices) {
      val progressionString = progressionStringsInfo(i)._1
      if(i == -1 || (currentState == i - 1 && string.contains(progressionString))){
        currentState = currentState + 1
      }
    }
    if(old != currentState) {
73
74
75
76
77
78
79
80
      if(old != -1) {
        val oldProgressionString = progressionStringsInfo(old)._2
        logger.info("Finished %s after %s (Total Elapsed: %s)".format(oldProgressionString, timeString(stageStart), timeString(start)))
      }
      val progressionString = progressionStringsInfo(currentState)._2
      logger.info("Started %s (Total Elapsed: %s)".format(progressionString, timeString(start)))
      stageStart = System.currentTimeMillis()

81
82
83
84
      //This ensures that this watcher will close all opened files if he reaches the final state.
      if(currentState == progressionStringsInfo.length) {
        closeAll()
      }
85
86


87
88
89
    }
  }

90
91
92
93
94
95
96
97
  /**
    * Calculates the time since a certain TimeStamp and transforms it into a hh:mm:ss-Formatted String.
    * @param since timestamp
    * @return TimeString
    */
  private def timeString(since: Long): String = {
    val now = System.currentTimeMillis()
    val dur = Duration(now-since, "millis")
Lukas Weber's avatar
Lukas Weber committed
98
    f"${dur.toHours}%d:${dur.toMinutes}%02d:${dur.toSeconds}%02d"
99
100
  }

101
102
103
104
105
  addListener(listener)
}

private object ProgressTrackingFileWatcher {
  val progressionStringsInfo = Seq(
106
107
    ("create_comp", "System Composition"),
    ("synth_design", "Synthesis"),
108
109
110
111
112
113
114
    ("place_design", "Placing"),
    ("route_design", "Routing"),
    ("write_bitstream", "Writing Bitstream")
  )


}