2016-08-09 62 views
1

Ich versuche, meine Anwendung zu erweitern, um eine andere Cassandra Tabelle für die Speicherung der Transaktionen enthalten in jedem Block enthalten.Fehler: Phantom-dsl BatchQuery nicht mit überladener Methode

Ich habe versucht, die Code-Snippets prägnant und relevant zu halten. Wenn ein weiterer Code-Kontext erforderlich ist, lassen Sie es mich wissen.

phantomVersion = "1.22.0" cassandraVersion = "2.1.4"


Ich erhalte die folgende Zusammenstellung Fehler mit dem Code unten aufgeführt. Einblicke sehr geschätzt.

[error] /home/dan/projects/open-blockchain/scanner/src/main/scala/org/dyne/danielsan/openblockchain/data/database/Database.scala:30: overloaded method value add with alternatives: 
[error] (batch: com.websudos.phantom.batch.BatchQuery[_])com.websudos.phantom.batch.BatchQuery[com.websudos.phantom.builder.Unspecified] <and> 
[error] (queries: Iterator[com.websudos.phantom.builder.query.Batchable with com.websudos.phantom.builder.query.ExecutableStatement])(implicit session: com.datastax.driver.core.Session)com.websudos.phantom.batch.BatchQuery[com.websudos.phantom.builder.Unspecified] <and> 
[error] (queries: com.websudos.phantom.builder.query.Batchable with com.websudos.phantom.builder.query.ExecutableStatement*)(implicit session: com.datastax.driver.core.Session)com.websudos.phantom.batch.BatchQuery[com.websudos.phantom.builder.Unspecified] <and> 
[error] (query: com.websudos.phantom.builder.query.Batchable with com.websudos.phantom.builder.query.ExecutableStatement)(implicit session: com.datastax.driver.core.Session)com.websudos.phantom.batch.BatchQuery[com.websudos.phantom.builder.Unspecified] 
[error] cannot be applied to (scala.concurrent.Future[com.datastax.driver.core.ResultSet]) 
[error]  .add(ChainDatabase.bt.insertNewBlockTransaction(bt)) 
[error]  ^
[error] one error found 
[error] (compile:compileIncremental) Compilation failed 
[error] Total time: 6 s, completed Aug 9, 2016 2:42:30 PM 

GenericBlockModel.scala:

case class BlockTransaction(hash: String, txid: String) 

sealed class BlockTransactionModel extends CassandraTable[BlockTransactionModel, BlockTransaction] { 

    override def fromRow(r: Row): BlockTransaction = { 
    BlockTransaction(
     hash(r), 
     txid(r) 
    ) 
    } 

    object hash extends StringColumn(this) with PartitionKey[String] 

    object txid extends StringColumn(this) with ClusteringOrder[String] with Descending 

} 

abstract class ConcreteBlockTransactionModel extends BlockTransactionModel with RootConnector { 

    override val tableName = "block_transactions" 

    def insertNewBlockTransaction(bt: BlockTransaction): Future[ResultSet] = insertNewRecord(bt).future() 

    def insertNewRecord(bt: BlockTransaction) = { 
    insert 
     .value(_.hash, bt.hash) 
     .value(_.txid, bt.txid) 
    } 
} 

Database.scala

class Database(val keyspace: KeySpaceDef) extends DatabaseImpl(keyspace) { 

    def insertBlock(block: Block) = { 
    Batch.logged 
     .add(ChainDatabase.block.insertNewRecord(block)) 
     .future() 
    } 

    def insertTransaction(tx: Transaction) = { 
    Batch.logged 
     .add(ChainDatabase.tx.insertNewTransaction(tx)) 
     .future() 
    } 

    def insertBlockTransaction(bt: BlockTransaction) = { 
    Batch.logged 
     .add(ChainDatabase.btx.insertNewBlockTransaction(bt)) 
     .future() 
    } 

    object block extends ConcreteBlocksModel with keyspace.Connector 

    object tx extends ConcreteTransactionsModel with keyspace.Connector 

    object btx extends ConcreteBlockTransactionsModel with keyspace.Connector 


} 

object ChainDatabase extends Database(Config.keySpaceDefinition) 

Antwort

2

Der Fehler offensichtlich ist, dass Sie eine Future einen Batch hinzufügen möchten, wenn ein Batch benötigt eine Abfrage. Wenn Sie bereits eine Abfrage ausgelöst haben, ist es nicht mehr möglich, sie stapelweise zu verarbeiten. Sie müssen also einen Schritt weiter machen. Hier ist, wie:

Batch.logged.add(insertNewRecord(record1) 
.add(insertNewRecord(record2)) 
// etc 

Auf einer anderen Notiz ein batch in Cassandra verwendet wird, nicht parallel Einsätze zu tun, sondern es zu Garantie verwendet wird:

def insertNewRecord(
    bt: BlockTransaction 
): InsertQuery.Default[BlockTransactionModel, BlockTransaction] = { 
    insert 
    .value(_.hash, bt.hash) 
    .value(_.txid, bt.txid) 
} 

Jetzt können Sie mehrere Datensätze zu einer Charge mit hinzufügen Atomizität, die es im Allgemeinen mindestens 30% langsamer als eine normale parallele Insertion macht. Lesen Sie this für weitere Details.

Wenn Sie einfach mehr Dinge zur gleichen Zeit einfügen möchten, können Sie die Methode verwenden, die eine Zukunft wie folgt zurückgibt:

def insertMany(
    list: List[BlockTransaction] 
): Future[List[ResultSet]] = { 
    Future.sequence(list.map(insertNewRecord(_).future())) 
} 
+0

Batches langsam sind für Multi-Partitionsoperationen. Siehe auch https://inoio.de/blog/2016/01/13/cassandra-to-batch-or-not-to-batch/ – mmatloka