#corda
#corda
Вопрос:
Недавно я столкнулся с проблемой, когда кажется, что когда поток заканчивается на узле инициатора, и сразу после этого я запрашиваю состояние вывода транзакции в хранилищах всех узлов-участников транзакции, оказывается, что состояние присутствует только на узле инициатора, и только через некоторое время оно появляется в хранилищах других узлов-участников. Читая документацию здесь «Отправить транзакцию контрагенту для записи», и в ней не говорится, что она будет ждать, пока контрагент успешно не запишет транзакцию и ее состояния в свое хранилище, что подтверждает, что проблема, с которой я сталкиваюсь, на самом деле заключается в том, как реализована Corda, а не в ошибке или около того.
С другой стороны, кажется не совсем логичным завершать поток, не будучи уверенным, что на узле контрагента все было успешно завершено и все состояния записаны в их хранилища.
А также я просмотрел код и обратился к этому методу в ServiceHubInternal
, который, похоже, отвечает за запись состояний в хранилище.
fun recordTransactions(statesToRecord: StatesToRecord,
txs: Collection<SignedTransaction>,
validatedTransactions: WritableTransactionStorage,
stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage,
vaultService: VaultServiceInternal,
database: CordaPersistence) {
database.transaction {
require(txs.isNotEmpty()) { "No transactions passed in for recording" }
val orderedTxs = topologicalSort(txs)
val (recordedTransactions, previouslySeenTxs) = if (statesToRecord != StatesToRecord.ALL_VISIBLE) {
orderedTxs.filter(validatedTransactions::addTransaction) to emptyList()
} else {
orderedTxs.partition(validatedTransactions::addTransaction)
}
val stateMachineRunId = FlowStateMachineImpl.currentStateMachine()?.id
if (stateMachineRunId != null) {
recordedTransactions.forEach {
stateMachineRecordedTransactionMapping.addMapping(stateMachineRunId, it.id)
}
} else {
log.warn("Transactions recorded from outside of a state machine")
}
vaultService.notifyAll(statesToRecord, recordedTransactions.map { it.coreTransaction }, previouslySeenTxs.map { it.coreTransaction })
}
}
И мне не кажется, что этот метод делает что-то асинхронное, поэтому я действительно в замешательстве.
Итак, актуальный вопрос:
Действительно ли поток инициатора в Corda ожидает, пока все соответствующие состояния не будут записаны в хранилища всех узлов-участников, прежде чем он завершится, или он завершается сразу после отправки состояний узлам-участникам для записи, не дожидаясь подтверждения с их стороны, что состояния были записаны?
Отредактировано
Итак, в случае, если Corda по умолчанию не ожидает, пока потоки контрагентов сохранят состояния в своих хранилищах, но моя реализация в любом случае нуждается в таком поведении, было бы хорошим решением реализовать следующее:
В самом конце потока инициатора, перед возвратом из метода, вызывайте receiveAll для приостановки и ожидания, затем в самом конце потока получателя, перед возвратом из метода, выполняйте запрос хранилища с trackBy
, чтобы дождаться, пока в хранилище не будет записано состояние, представляющее интерес, и всякий раз, когда это происходит, вызывайте sendAll
, чтобы уведомить receiveAll
метод инициатора. И завершает поток инициатора только тогда, когда он получил подтверждение от всех получателей..
Будет ли это нормальным подходом к решению этой проблемы? могут ли у него быть какие-либо недостатки или побочные эффекты, о которых вы можете подумать?
Ответ №1:
Corda может обрабатывать ваш сценарий, на самом деле это объясняется здесь в Error handling behaviour
разделе; ниже приведен отрывок, но я рекомендую прочитать полный раздел:
Для восстановления из этого сценария обработчик завершения получателя будет автоматически отправлен в больницу потока, где он приостанавливается и повторяется с последней контрольной точки при перезапуске узла
Ответ №2:
Поток инициатора не отвечает за хранение состояний в хранилище ответчика. Итак, подтверждения хранилища от ответчика нет, поскольку он уже проверил транзакцию и предоставил подписи. Итак, с точки зрения инициатора, все хорошо, как только транзакция была нотариально заверена и сохранена на своей стороне, Ответчик должен управлять ошибками на этапе хранения, как упоминалось в предыдущем комментарии.
Комментарии:
1. Большое вам спасибо, Алессандро. Я отредактировал свой вопрос с решением моей проблемы, которое, как я думаю, может решить его для меня, можете ли вы взглянуть?