All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.synhaptein.migmongo.MigmongoEngine.scala Maven / Gradle / Ivy

package com.synhaptein.migmongo

import commands._
import collection.mutable
import commands.AsyncChangeSet
import dao.MigmongoDao
import org.slf4j.LoggerFactory
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import reactivemongo.api.{MongoConnection, DefaultDB, MongoDriver}
import scala.concurrent.{Future, Await}
import scala.util.{Failure, Success}
import akka.actor.ActorSystem

object Migmongo {
  private val loggerName = "migmongo"
  lazy val logger = LoggerFactory.getLogger(loggerName)
}

trait MigmongoEngine {
  import Migmongo.logger

  private val changeGroups = mutable.MutableList[ChangeGroup]()
  private lazy val dao = MigmongoDao(db)
  val db: DefaultDB

  def process(timeout: Duration = Duration(1000, MINUTES)) = {
    logger.info("Running db changeSets...")
    dao.ensureIndex
    val results = for {
      changeGroup <- changeGroups
      changeSet <- changeGroup.changeSets
    }
    yield {
      val wasExecuted = dao.wasExecuted(changeGroup.group, changeSet)

      val result = changeSet match {
        case changeSet: AsyncChangeSet =>
          wasExecuted flatMap {
            case true =>
              Future.successful(false)
            case _ =>
              logger.info("Start async ChangeSet " + changeSet.changeId)
              Future.sequence(changeSet.changes(db) map (_.map(_ => true))) map (_ => true)
          }
        case changeSet: SyncChangeSet =>
          val isExecute = !Await.result(wasExecuted, Duration(30, SECONDS))
          if(isExecute) {
            logger.info("Start sync ChangeSet " + changeSet.changeId)
            changeSet.changes(db).foreach { change =>
              Await.result(change, changeSet.timeout.getOrElse(timeout))
            }
          }

          Future.successful(isExecute)
      }

      val fresult = result flatMap { r =>
        if(r) {
          dao.logChangeSet(changeGroup.group, changeSet) map { _ =>
            logger.info("ChangeSet " + changeSet.changeId + " has been executed")
            r
          }
        }
        else {
          Future.successful(r)
        }
      }

      fresult.onFailure {
        case e: Throwable =>
          logger.info("ChangeSet " + changeSet.changeId + " could not be executed", e)
          throw e
      }

      fresult
    }

    val mergedResults = Future.sequence(results.toList) map (l => l.filter(r => r).size)

    mergedResults foreach { _ =>
      logger.info("Migrations finished")
    }

    mergedResults
  }

  protected def changeGroups(changeGroups: ChangeGroup*) {
    this.changeGroups ++= changeGroups
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy