blob: 84600f51c2c19085bec9866f1d4221ab8c48b1ed [file] [log] [blame]
package io.prediction.commons.settings
import io.prediction.commons.Common
import com.github.nscala_time.time.Imports._
import org.json4s._
import org.json4s.native.Serialization
/**
* Algo object.
*
* @param id ID.
* @param engineid App ID that owns this engine.
* @param name Algo name.
* @param infoid AlgoInfo ID
* @param command Command template for running the algo.
* @param params Algo parameters as key-value pairs.
* @param settings Algo settings as key-value pairs.
* @param modelset Indicates which model output set to be used by the API.
* @param createtime Creation time of this Algo.
* @param updatetime Last update time of this Algo's settings.
* @param status The status of the algo. eg "ready", "tuning".
* @param offlineevalid The id of OfflineEval which uses this algo for offline evaluation
* @param offlinetuneid The id of OfflineTune
* @param loop The iteration number used by auto tune. (NOTE: loop=0 reserved for baseline algo)
* @param paramset The param generation set number
* @param lasttraintime Time of last successful training.
*/
case class Algo(
id: Int,
engineid: Int,
name: String,
infoid: String,
command: String,
params: Map[String, Any] = Map(),
settings: Map[String, Any] = Map(),
modelset: Boolean,
createtime: DateTime,
updatetime: DateTime,
status: String = "",
offlineevalid: Option[Int] = None,
offlinetuneid: Option[Int] = None,
loop: Option[Int] = None,
paramset: Option[Int] = None,
lasttraintime: Option[DateTime] = None)
/** Base trait for implementations that interact with algos in the backend data store. */
trait Algos extends Common {
/** Inserts an algo. */
def insert(algo: Algo): Int
/** Get an algo by its ID. */
def get(id: Int): Option[Algo]
/** Get all algos. */
def getAll(): Iterator[Algo]
/** Get algos by engine ID. */
def getByEngineid(engineid: Int): Iterator[Algo]
/** Get deployed algos by engine ID. */
def getDeployedByEngineid(engineid: Int): Iterator[Algo]
/** Get by OfflineEval ID. */
def getByOfflineEvalid(evalid: Int, loop: Option[Int] = None, paramset: Option[Int] = None): Iterator[Algo]
/** Get the auto tune subject by OfflineTune ID. */
def getTuneSubjectByOfflineTuneid(tuneid: Int): Option[Algo]
/** Get the algo by its ID and engine ID. */
def getByIdAndEngineid(id: Int, engineid: Int): Option[Algo]
/** Update an algo. */
def update(algo: Algo, upsert: Boolean = false)
/** Delete an algo by its ID. */
def delete(id: Int)
/**
* Check existence of an algo by its engine ID and name.
* Algos that are part of an offline evaluation or tuning are not counted.
*/
def existsByEngineidAndName(engineid: Int, name: String): Boolean
implicit val formats = Serialization.formats(NoTypeHints) + new AlgoSerializer
/** Backup all Algos as a byte array. */
def backup(): Array[Byte] = Serialization.write(getAll().toSeq).getBytes("UTF-8")
/** Restore Algos from a byte array backup created by the current or the immediate previous version of commons. */
def restore(bytes: Array[Byte], inplace: Boolean = false, upgrade: Boolean = false): Option[Seq[Algo]] = {
try {
val rdata = Serialization.read[Seq[Algo]](new String(bytes, "UTF-8"))
if (inplace) rdata foreach { update(_, true) }
Some(rdata)
} catch {
case e: MappingException => None
}
}
}
/** json4s serializer for the Algo class. */
class AlgoSerializer extends CustomSerializer[Algo](format => (
{
case x: JObject =>
implicit val formats = Serialization.formats(NoTypeHints) ++ org.json4s.ext.JodaTimeSerializers.all
Algo(
id = (x \ "id").extract[Int],
engineid = (x \ "engineid").extract[Int],
name = (x \ "name").extract[String],
infoid = (x \ "infoid").extract[String],
command = (x \ "command").extract[String],
params = Common.sanitize((x \ "params").asInstanceOf[JObject].values),
settings = Common.sanitize((x \ "settings").asInstanceOf[JObject].values),
modelset = (x \ "modelset").extract[Boolean],
createtime = (x \ "createtime").extract[DateTime],
updatetime = (x \ "updatetime").extract[DateTime],
status = (x \ "status").extract[String],
offlineevalid = (x \ "offlineevalid").extract[Option[Int]],
offlinetuneid = (x \ "offlinetuneid").extract[Option[Int]],
loop = (x \ "loop").extract[Option[Int]],
paramset = (x \ "paramset").extract[Option[Int]],
lasttraintime = (x \ "lasttraintime").extract[Option[DateTime]])
},
{
case x: Algo =>
implicit val formats = Serialization.formats(NoTypeHints) ++ org.json4s.ext.JodaTimeSerializers.all
JObject(
JField("id", Extraction.decompose(x.id)) ::
JField("engineid", Extraction.decompose(x.engineid)) ::
JField("name", Extraction.decompose(x.name)) ::
JField("infoid", Extraction.decompose(x.infoid)) ::
JField("command", Extraction.decompose(x.command)) ::
JField("params", Extraction.decompose(x.params)) ::
JField("settings", Extraction.decompose(x.settings)) ::
JField("modelset", Extraction.decompose(x.modelset)) ::
JField("createtime", Extraction.decompose(x.createtime)) ::
JField("updatetime", Extraction.decompose(x.updatetime)) ::
JField("status", Extraction.decompose(x.status)) ::
JField("offlineevalid", Extraction.decompose(x.offlineevalid)) ::
JField("offlinetuneid", Extraction.decompose(x.offlinetuneid)) ::
JField("loop", Extraction.decompose(x.loop)) ::
JField("paramset", Extraction.decompose(x.paramset)) ::
JField("lasttraintime", Extraction.decompose(x.lasttraintime)) :: Nil)
})
)