Ich spiele mit der GPars-Bibliothek herum, während ich daran arbeite, die Skalierbarkeit eines Matching-Systems zu verbessern. Ich möchte in der Lage sein, die Datenbank abzufragen und sofort die Datenbank abzufragen, während die Ergebnisse gleichzeitig verarbeitet werden. Der Engpass ist das Lesen aus der Datenbank, also möchte ich die Datenbank die ganze Zeit beschäftigen, während ich die Ergebnisse asynchron verarbeite, sobald sie verfügbar sind. Mir ist klar, dass ich möglicherweise einige grundlegende Missverständnisse bezüglich der Funktionsweise des Actor-Frameworks habe, und ich würde mich freuen, wenn man mich korrigiert!
In Pseudocode versuche ich, Folgendes zu tun:
Definieren Sie zwei Akteure, einen für die Ausführung von Selects in der Datenbank und einen weiteren für die Verarbeitung der Datensätze.
- queryActor fragt die Datenbank ab und sendet die Ergebnisse an processorActor
- queryActor fragt die Datenbank sofort erneut ab, ohne auf das Ende von processorActor zu warten
Ich könnte den einfachen Anwendungsfall wahrscheinlich auch ohne die Verwendung von Akteuren erreichen, aber mein Endziel ist es, einen Akteurspool zu haben, der immer an neuen Abfragen mit potenziell unterschiedlichen Datenquellen arbeitet, um den Durchsatz des Systems im Allgemeinen zu erhöhen.
Der verarbeitende Akteur wird immer viel schneller sein als die Datenbankabfrage, daher möchte ich in Zukunft mehrere Replikate gleichzeitig abfragen.
def processor = actor {
loop {
react {querySet ->
println "processing recordset"
if (querySet instanceof Object[]) {
MatcherDataRowProcessor matcher = new MatcherDataRowProcessor(matchedRecords, matchedRecordSet);
matchedRecords = matcher.processRecordset(querySet);
reply matchedRecords
}
else {
println 'processor fed nothing, halting processor actor'
stop()
}
}
}
}
def dbqueryer = actor {
println "dbqueryer has started"
while (batchNum.longValue() <= loopLimiter) {
println "hitting db"
Object[] querySet
def thisRuleBatch = new MatchRuleBatch(targetuidFrom, targetuidTo)
thisRuleBatch.targetuidFrom = batchNum * perBatch - perBatch
thisRuleBatch.targetuidTo = thisRuleBatch.targetuidFrom + perBatch
thisRuleBatch.targetName = targetName
thisRuleBatch.whereClause = whereClause
querySet = dao.getRecordSet(thisRuleBatch)
processor.send querySet
batchNum++
}
react { processedRecords ->
processor.send false
}
}