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

sss.openstar.message.MessageProcessorUtils.scala Maven / Gradle / Ivy

package sss.openstar.message

import sss.ancillary.{Guid, Logging}
import sss.openstar.message.MessageDownloadActor.PublishUnProcessedMessages
import sss.openstar.message.MessageInBoxActor.{InBoxAdd, InBoxAddSent, InBoxUpdate}
import sss.openstar.message.payloads.UtxoWatcher
import sss.openstar.network.MessageEventBus
import sss.openstar.util.TryAndLog

import scala.annotation.tailrec
import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}

object MessageProcessorUtils extends Logging with TryAndLog {

  def syncToAsync(m: MessageProcessor)(implicit ec: ExecutionContext): AsyncMessageProcessor = m.andThen(Future(_))

  val messageDecoder: MessageDecoder = m =>
    DecodedMessageCache(m).getOrElse(throw new Exception(s"Could not decode $m"))

  def comsumeMessageSent(msg: Message, messageDecoder: MessageDecoder): Seq[ConsumeResult] =
    consumeWatcher(messageDecoder(msg)) :+ AddSent(msg)

  def comsumeMessage(msg: Message, messageDecoder: MessageDecoder): Seq[ConsumeResult] =
    consumeWatcher(messageDecoder(msg)) :+ Add(msg)

  private def consumeWatcher(msg: MessageComposite): ConsumeResults = msg match {
    case w: UtxoWatcher => w.watch.map(Watch)
    case _              => Seq.empty
  }

  def comsumeMessageSentWithParent(parent: Message, msg: Message, messageDecoder: MessageDecoder): ConsumeResults = {
    val decodedChildMsg = messageDecoder(msg)
    val decodedParent = messageDecoder(parent)
    consumeWatcher(decodedChildMsg) ++
      mergeMessagesSent(
        decodedChildMsg,
        msg.guid,
        msg.msgPayload,
        decodedParent,
        parent.guid
      )
  }

  def comsumeMessageWithParent(parent: Message, msg: Message, messageDecoder: MessageDecoder): ConsumeResults = {
    val decodedChildMsg = messageDecoder(msg)
    val decodedParent = messageDecoder(parent)
    consumeWatcher(decodedChildMsg) ++
      mergeMessages(
        decodedChildMsg,
        msg.guid,
        msg.msgPayload,
        decodedParent,
        parent.guid
      )
  }

  def mergeMessagesSent(
                     msg: MessageComposite,
                     guid: Guid,
                     payload: MessagePayload,
                     parentMsg: MessageComposite,
                     parentGuid: Guid
                   ): Seq[ConsumeResult] =
    Seq(
      AddSent(
        Message(
          payload,
          guid,
          Some(parentGuid)
        )
      ),
      Update(
        guid,
        parentGuid
      )
    )

  def mergeMessages(
    msg: MessageComposite,
    guid: Guid,
    payload: MessagePayload,
    parentMsg: MessageComposite,
    parentGuid: Guid
  ): Seq[ConsumeResult] =
    Seq(
      Add(
        Message(
          payload,
          guid,
          Some(parentGuid)
        )
      ),
      Update(
        guid,
        parentGuid
      )
    )
  @tailrec
  def defaultHandleConsumeResults(
    results: ConsumeResults
  )(implicit inBox: MessageInBox, events: MessageEventBus, watch: UtxoWatch): Unit =
    results.headOption.map {
      case AddSent(msg) =>
        inBox addNew msg foreach (_ =>
          events publish InBoxAddSent(
            inBox.owner,
            msg
          )
        )
      case Add(msg) =>
        inBox addNew msg foreach (_ =>
          events publish InBoxAdd(
            inBox.owner,
            msg
          )
        )
      case Update(msgG, parentG) =>
        tryAndLog {
          (for {
            msg           <- inBox.find(msgG)
            parentMsg     <- inBox.find(parentG)
            decodedParent <- DecodedMessageCache(parentMsg.msg)
            decodedChild  <- DecodedMessageCache(msg.msg)
          } yield {
            Message(
              MessagePayloadDecoder.toPayload(decodedParent(decodedChild)),
              parentG,
              parentMsg.msg.parentGuid
            )
          }).foreach { updateMsg =>
            DecodedMessageCache update updateMsg
            inBox update updateMsg
            events publish InBoxUpdate(
              inBox.owner,
              updateMsg
            )
          }

        }

      case Rejected(msg) =>
        inBox addJunk msg
      case TempRejected =>
        events publish PublishUnProcessedMessages(
          inBox.owner,
          Some(1.second)
        )
      case Delete(guid) =>
        inBox delete guid
        DecodedMessageCache remove guid
      case Watch(index) =>
        watch(index)

    } match {
      case None =>
      case _    => defaultHandleConsumeResults(results.tail)
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy