Der einfachste Weg, Leerlaufverarbeitung in einem Scala Schauspieler zu tun?

StackOverflow https://stackoverflow.com/questions/1560402

  •  21-09-2019
  •  | 
  •  

Frage

Ich habe einen scala Schauspieler, der etwas Arbeit tut, wenn ein Kunde sie anfordert. Wenn, und nur dann, wenn kein Client aktiv ist, würde ich die Schauspieler gerne einige Hintergrundverarbeitung zu tun.

Was ist der einfachste Weg, dies zu tun? Ich kann mich zwei Ansätze:

  1. Spawn ein neuer Thread, dass die Zeiten und in regelmäßigen Abständen die Schauspieler aufwacht. Ein geradlinig Ansatz, aber ich würde einen anderen Thread zu vermeiden wie das Erstellen (den zusätzlichen Code zu vermeiden, Komplexität und Overhead).

  2. Die Schauspieler-Klasse hat eine reactWithin Methode, die sich von dem Schauspieler selbst zu Zeit verwendet werden könnten. Aber die Dokumentation sagt das Verfahren nicht zurück. Also, ich bin nicht sicher, wie es zu benutzen.

Bearbeiten; eine Klarstellung:

Nehmen wir an, die Hintergrundaufgabe in kleinere Einheiten werden abgebaut, die unabhängig voneinander bearbeitet werden können.

War es hilfreich?

Lösung

Ok, ich sehe, ich brauche meinen 2 Cent zu setzen. Aus der Antwort des Autors ich denke, die „Priorität erhalten“ Technik ist genau das, was hier gebraucht wird. Es ist möglich, die Diskussion zu finden in „ Erlang: Priorität Frage hier auf SO erhalten“. Die Idee ist, Nachrichten mit hohen Priorität zuerst zu akzeptieren und andere Nachrichten nur in Abwesenheit von hohen Priorität diejenigen zu akzeptieren.

Als Scala Schauspieler sehr ähnlich sind Erlang, eine triviale Code dies implementieren würde wie folgt aussehen:

def act = loop {
  reactWithin(0) {
    case msg: HighPriorityMessage => // process msg
    case TIMEOUT =>
      react {
        case msg: HighPriorityMessage => // process msg
        case msg: LowPriorityMessage => // process msg
      }
  }
}

Das funktioniert folgendermaßen wie. Ein Akteur hat eine Mailbox (queue) mit Meldungen. Das receive (oder receiveWithin) Argument ist eine Teilfunktion und Schauspieler Bibliothek sucht nach einer Nachricht in einer Mailbox, die auf diese Teilfunktion angewandt werden können. In unserem Fall wäre es nur ein Ziel HighPriorityMessage sein. Also, wenn Schauspieler Bibliothek eine solche Nachricht findet, gilt es unsere Teilfunktion und wir die Verarbeitung einer Nachricht von hoher Priorität. Andernfalls reactWithin mit Timeout 0 ruft unsere Teilfunktion mit dem Argument TIMEOUT und wir sofort versuchen, jede mögliche Nachricht aus der Warteschlange zu verarbeiten (wie es für eine Nachricht wartet, wir nicht eine Möglichkeit bekommen HighPriorityMessage ausschließen kann).

Andere Tipps

Es klingt wie das Problem, das Sie beschreiben, nicht gut geeignet, um den Schauspieler Subsystems . Ein Actor ist entworfen, um der Reihe nach seine Meldungswarteschlange zu verarbeiten:

  • Was soll passieren, wenn der Schauspieler Durchführung der Hintergrund Arbeit und eine neue Aufgabe kommt?

Ein Schauspieler kann nur herausfinden, darüber ist er kontinuierlich seine mailbox prüft, wie es die Aufgabe Hintergrund ausführt. Wie würden Sie diese (das heißt, wie Sie die Hintergrundaufgaben als Arbeitseinheit codieren würde, so dass der Schauspieler halten könnte zu unterbrechen und die Überprüfung der Mailbox) implementieren?

  • Was soll passieren, wenn der Schauspieler viele Hintergrundaufgaben in seiner Mailbox vor der Hauptaufgabe hat?

Sie diese Hintergrundaufgaben weg bekommen geworfen oder an einem anderen Akteur gesendet? Wenn letzteres der Fall, wie können Sie die CPU-Zeit verhindern, dass der Schauspieler gegeben werden, um die Aufgaben zu erfüllen?

Alles in allem, es klingt viel wie Sie brauchen eine raster Stil Software zu erkunden, die im Hintergrund (wie Daten Synapse) laufen können!

Unmittelbar nach der diese Frage habe ich versucht, etwas ganz whacky Code aus und es scheint zu funktionieren. Ich bin nicht sicher, obwohl, wenn es eine Gotcha drin.

import scala.actors._

object Idling

object Processor extends Actor {
  start

  import Actor._

  def act() = {
    loop {

      // here lie dragons >>>>>
      if (mailboxSize == 0) this ! Idling
      // <<<<<<

      react {
        case msg:NormalMsg => {
          // do the normal work
          reply(answer)
        }

        case Idling=> {
          // do the idle work in chunks
        }

        case msg => println("Rcvd unknown message:" + msg)
      }

    }
  }
}

Erklärung

Jeder Code in das Argument von loop aber vor dem Aufruf von react scheint genannt zu werden, wenn die Schauspieler über zu Warten auf eine Nachricht ist. Ich sende eine Nachricht an Idling Selbst hier. Im Handler für diese Meldung stelle ich sicher, dass die Mailbox-Größe 0, bevor die Verarbeitung zu tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top